diff options
author | Greg Kroah-Hartman <greg@kroah.com> | 2013-06-12 14:44:13 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <greg@kroah.com> | 2013-06-12 14:44:13 -0700 |
commit | 976f8bef9cfb5246bc0e8dc781562daa79cb7aaf (patch) | |
tree | d995465d23f10080c3df6f5ca0c4375d59138b39 /drivers/usb/phy/phy-samsung-usb.c | |
parent | 1143832eca8f1d64da7d85642c956ae9d25c69e1 (diff) | |
parent | b1fd6cb5ee2f97a553d1c4b8a88914bd970daf37 (diff) |
Merge tag 'usb-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes:
usb: patches for v3.11 merge window
All function drivers are now converted to our new configfs-based
binding. Eventually this will help us getting rid of in-kernel
gadget drivers and only keep function drivers in the kernel.
MUSB was taught that it needs to be built for host-only and
device-only modes too. We had this support long ago but it
involved a ridiculous amount of ifdefs. Now we have a much
cleaner approach.
Samsung Exynos4 platform now implements HSIC support.
We're introducing support for AB8540 and AB9540 PHYs.
MUSB module reinsertion now works as expected, before we were
getting -EBUSY being returned by the resource checks done on
driver core.
DWC3 now has minimum support for TI's AM437x series of SoCs.
OMAP5 USB3 PHY learned one extra DPLL configuration values because
that PHY is reused in TI's DRA7xx devices.
We're introducing support for Faraday fotg210 UDCs.
Last, but not least, the usual set of non-critical fixes and cleanups
ranging from usage of platform_{get,set}_drvdata to lock improvements.
Signed-of-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy/phy-samsung-usb.c')
-rw-r--r-- | drivers/usb/phy/phy-samsung-usb.c | 159 |
1 files changed, 82 insertions, 77 deletions
diff --git a/drivers/usb/phy/phy-samsung-usb.c b/drivers/usb/phy/phy-samsung-usb.c index 7b118ee5f5e..ac025ca0842 100644 --- a/drivers/usb/phy/phy-samsung-usb.c +++ b/drivers/usb/phy/phy-samsung-usb.c @@ -73,7 +73,7 @@ EXPORT_SYMBOL_GPL(samsung_usbphy_parse_dt); * Here 'on = true' would mean USB PHY block is isolated, hence * de-activated and vice-versa. */ -void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) +void samsung_usbphy_set_isolation_4210(struct samsung_usbphy *sphy, bool on) { void __iomem *reg = NULL; u32 reg_val; @@ -84,32 +84,12 @@ void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) return; } - switch (sphy->drv_data->cpu_type) { - case TYPE_S3C64XX: - /* - * Do nothing: We will add here once S3C64xx goes for DT support - */ - break; - case TYPE_EXYNOS4210: - /* - * Fall through since exynos4210 and exynos5250 have similar - * register architecture: two separate registers for host and - * device phy control with enable bit at position 0. - */ - case TYPE_EXYNOS5250: - if (sphy->phy_type == USB_PHY_TYPE_DEVICE) { - reg = sphy->pmuregs + - sphy->drv_data->devphy_reg_offset; - en_mask = sphy->drv_data->devphy_en_mask; - } else if (sphy->phy_type == USB_PHY_TYPE_HOST) { - reg = sphy->pmuregs + - sphy->drv_data->hostphy_reg_offset; - en_mask = sphy->drv_data->hostphy_en_mask; - } - break; - default: - dev_err(sphy->dev, "Invalid SoC type\n"); - return; + if (sphy->phy_type == USB_PHY_TYPE_DEVICE) { + reg = sphy->pmuregs + sphy->drv_data->devphy_reg_offset; + en_mask = sphy->drv_data->devphy_en_mask; + } else if (sphy->phy_type == USB_PHY_TYPE_HOST) { + reg = sphy->pmuregs + sphy->drv_data->hostphy_reg_offset; + en_mask = sphy->drv_data->hostphy_en_mask; } reg_val = readl(reg); @@ -120,8 +100,13 @@ void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on) reg_val |= en_mask; writel(reg_val, reg); + + if (sphy->drv_data->cpu_type == TYPE_EXYNOS4X12) { + writel(reg_val, sphy->pmuregs + EXYNOS4X12_PHY_HSIC_CTRL0); + writel(reg_val, sphy->pmuregs + EXYNOS4X12_PHY_HSIC_CTRL1); + } } -EXPORT_SYMBOL_GPL(samsung_usbphy_set_isolation); +EXPORT_SYMBOL_GPL(samsung_usbphy_set_isolation_4210); /* * Configure the mode of working of usb-phy here: HOST/DEVICE. @@ -162,73 +147,93 @@ int samsung_usbphy_set_type(struct usb_phy *phy, } EXPORT_SYMBOL_GPL(samsung_usbphy_set_type); +int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy, + unsigned long rate) +{ + unsigned int clksel; + + switch (rate) { + case 12 * MHZ: + clksel = PHYCLK_CLKSEL_12M; + break; + case 24 * MHZ: + clksel = PHYCLK_CLKSEL_24M; + break; + case 48 * MHZ: + clksel = PHYCLK_CLKSEL_48M; + break; + default: + dev_err(sphy->dev, + "Invalid reference clock frequency: %lu\n", rate); + return -EINVAL; + } + + return clksel; +} +EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_64xx); + +int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy, + unsigned long rate) +{ + unsigned int clksel; + + switch (rate) { + case 9600 * KHZ: + clksel = FSEL_CLKSEL_9600K; + break; + case 10 * MHZ: + clksel = FSEL_CLKSEL_10M; + break; + case 12 * MHZ: + clksel = FSEL_CLKSEL_12M; + break; + case 19200 * KHZ: + clksel = FSEL_CLKSEL_19200K; + break; + case 20 * MHZ: + clksel = FSEL_CLKSEL_20M; + break; + case 24 * MHZ: + clksel = FSEL_CLKSEL_24M; + break; + case 50 * MHZ: + clksel = FSEL_CLKSEL_50M; + break; + default: + dev_err(sphy->dev, + "Invalid reference clock frequency: %lu\n", rate); + return -EINVAL; + } + + return clksel; +} +EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_4x12); + /* * Returns reference clock frequency selection value */ int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) { struct clk *ref_clk; - int refclk_freq = 0; + unsigned long rate; + int refclk_freq; /* * In exynos5250 USB host and device PHY use * external crystal clock XXTI */ if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) - ref_clk = devm_clk_get(sphy->dev, "ext_xtal"); + ref_clk = clk_get(sphy->dev, "ext_xtal"); else - ref_clk = devm_clk_get(sphy->dev, "xusbxti"); + ref_clk = clk_get(sphy->dev, "xusbxti"); if (IS_ERR(ref_clk)) { dev_err(sphy->dev, "Failed to get reference clock\n"); return PTR_ERR(ref_clk); } - if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) { - /* set clock frequency for PLL */ - switch (clk_get_rate(ref_clk)) { - case 9600 * KHZ: - refclk_freq = FSEL_CLKSEL_9600K; - break; - case 10 * MHZ: - refclk_freq = FSEL_CLKSEL_10M; - break; - case 12 * MHZ: - refclk_freq = FSEL_CLKSEL_12M; - break; - case 19200 * KHZ: - refclk_freq = FSEL_CLKSEL_19200K; - break; - case 20 * MHZ: - refclk_freq = FSEL_CLKSEL_20M; - break; - case 50 * MHZ: - refclk_freq = FSEL_CLKSEL_50M; - break; - case 24 * MHZ: - default: - /* default reference clock */ - refclk_freq = FSEL_CLKSEL_24M; - break; - } - } else { - switch (clk_get_rate(ref_clk)) { - case 12 * MHZ: - refclk_freq = PHYCLK_CLKSEL_12M; - break; - case 24 * MHZ: - refclk_freq = PHYCLK_CLKSEL_24M; - break; - case 48 * MHZ: - refclk_freq = PHYCLK_CLKSEL_48M; - break; - default: - if (sphy->drv_data->cpu_type == TYPE_S3C64XX) - refclk_freq = PHYCLK_CLKSEL_48M; - else - refclk_freq = PHYCLK_CLKSEL_24M; - break; - } - } + rate = clk_get_rate(ref_clk); + refclk_freq = sphy->drv_data->rate_to_clksel(sphy, rate); + clk_put(ref_clk); return refclk_freq; |