diff options
author | Yuvaraj CD <yuvaraj.cd@gmail.com> | 2012-12-26 10:48:11 +0530 |
---|---|---|
committer | Tushar Behera <tushar.behera@linaro.org> | 2013-01-16 17:14:42 +0530 |
commit | 7f50398b5e344b5f4e9008ad1a1b12a371f404ea (patch) | |
tree | b5d86dfb9e4eb9fe9ae1400e04dd2b63b9de2399 /arch/arm | |
parent | 94d1464e1ec088683dcf734e18f3e2c4f0fa39a1 (diff) |
USB3.0: Migration of Samsung USBPHY changes
Signed-off-by: Yuvaraj CD <yuvaraj.cd@gmail.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/boot/dts/exynos5250.dtsi | 6 | ||||
-rw-r--r-- | arch/arm/mach-exynos/include/mach/map.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos/include/mach/regs-pmu.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mach-exynos5-dt.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-exynos/setup-usb-phy.c | 212 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/usb-phy.h | 8 |
6 files changed, 80 insertions, 165 deletions
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 686db17ae9b..4e1c5518757 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -81,6 +81,11 @@ interrupts = <0 96 0>; }; + usbphy { + compatible = "samsung,exynos5250-usbphy"; + reg = <0x12130000 0x100>, <0x12100000 0x100>; + }; + ohci { compatible = "samsung,exynos-ohci"; reg = <0x12120000 0x100>; @@ -288,6 +293,7 @@ #size-cells = <0>; }; + amba { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index c20cb439e12..cf9a24848b9 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -190,7 +190,7 @@ #define EXYNOS4_PA_HSOTG 0x12480000 #define EXYNOS4_PA_USB_HSPHY 0x125B0000 - +#define EXYNOS5_PA_HSPHY 0x12130000 #define EXYNOS4_PA_SATA 0x12560000 #define EXYNOS4_PA_SATAPHY 0x125D0000 #define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000 diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 3f30aa1ae35..dfc39f204d1 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -41,6 +41,10 @@ #define S5P_HDMI_PHY_CONTROL S5P_PMUREG(0x0700) #define S5P_HDMI_PHY_ENABLE (1 << 0) +/* only for EXYNOS5250*/ +#define S5P_USBDRD_PHY_CONTROL S5P_PMUREG(0x0704) +#define S5P_USBDRD_PHY_ENABLE (1 << 0) + #define S5P_DAC_PHY_CONTROL S5P_PMUREG(0x070C) #define S5P_DAC_PHY_ENABLE (1 << 0) diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 18a93c39c3a..74a94f15020 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -17,21 +17,28 @@ #include <asm/mach/arch.h> #include <asm/hardware/gic.h> + #include <mach/map.h> #include <mach/regs-pmu.h> #include <plat/cpu.h> #include <plat/regs-serial.h> #include <plat/mfc.h> -#include <linux/platform_data/usb-exynos.h> - #include <plat/regs-srom.h> #include <plat/devs.h> #include <plat/usb-phy.h> + +#include <linux/platform_data/usb-exynos.h> +#include <linux/platform_data/samsung-usbphy.h> #include <linux/platform_data/usb-ehci-s5p.h> #include "common.h" +static struct samsung_usbphy_data exynos5_usbphy_pdata = { + .pmu_isolation = s5p_usb_phy_pmu_isolation, + .phy_cfg_sel = s5p_usb_phy_cfg_sel, +}; + static struct exynos4_ohci_platdata smdk5250_ohci_pdata = { .phy_init = s5p_usb_phy_init, .phy_exit = s5p_usb_phy_exit, @@ -143,6 +150,8 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("samsung,mfc-v6", 0x11000000, "s5p-mfc-v6", NULL), OF_DEV_AUXDATA("samsung,exynos5250-tmu", 0x10060000, "exynos-tmu", NULL), + OF_DEV_AUXDATA("samsung,exynos5250-usbphy", EXYNOS5_PA_HSPHY, + "s3c-usbphy", &exynos5_usbphy_pdata), OF_DEV_AUXDATA("samsung,exynos-ohci", 0x12120000, "exynos-ohci", &smdk5250_ohci_pdata), OF_DEV_AUXDATA("samsung,exynos-ehci", 0x12110000, diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c index e6f2f841376..c9728613138 100644 --- a/arch/arm/mach-exynos/setup-usb-phy.c +++ b/arch/arm/mach-exynos/setup-usb-phy.c @@ -14,17 +14,18 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/platform_device.h> +#include <linux/usb/samsung_usb_phy.h> +#include <linux/platform_data/samsung-usbphy.h> #include <mach/regs-pmu.h> #include <mach/regs-usb-phy.h> #include <plat/cpu.h> +#include <plat/map-base.h> #include <plat/usb-phy.h> #define PHY_ENABLE 1 #define PHY_DISABLE 0 +#define EXYNOS5_USB_CFG (S3C_VA_SYS + 0x230) -enum usb_phy_type { - USB_PHY = (0x1 << 0), -}; static atomic_t host_usage; @@ -160,7 +161,7 @@ static int exynos4210_usb_phy_clkset(struct platform_device *pdev) } return phyclk; } - +#if 0 static void exynos_usb_phy_control(enum usb_phy_type phy_type , int on) { if (soc_is_exynos5250()) { @@ -168,7 +169,7 @@ static void exynos_usb_phy_control(enum usb_phy_type phy_type , int on) writel(on, S5P_USBHOST_PHY_CONTROL); } } - +#endif static int exynos4210_usb_phy0_init(struct platform_device *pdev) { u32 rstcon; @@ -271,156 +272,12 @@ static int exynos4210_usb_phy1_exit(struct platform_device *pdev) return 0; } -static int exynos5_usb_phy20_init(struct platform_device *pdev) -{ - struct clk *host_clk; - u32 refclk_freq; - u32 hostphy_ctrl0; - u32 otgphy_sys; - u32 hsic_ctrl; - u32 ehcictrl; - u32 ohcictrl; - - atomic_inc(&host_usage); - host_clk = exynos_usb_clock_enable(pdev); - if (host_clk == NULL) { - dev_err(&pdev->dev, "Failed to enable USB2.0 host clock\n"); - return -1; - } - - if (exynos4_usb_host_phy_is_on()) { - dev_err(&pdev->dev, "Already power on PHY\n"); - return 0; - } - - exynos_usb_mux_change(pdev, 1); - - exynos_usb_phy_control(USB_PHY, PHY_ENABLE); - - /* Host and Device should be set at the same time */ - hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0); - hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK); - otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS); - otgphy_sys &= ~(OTG_SYS_CTRL0_FSEL_MASK); - - /* 2.0 phy reference clock configuration */ - refclk_freq = exynos4210_usb_phy_clkset(pdev); - hostphy_ctrl0 |= (refclk_freq << HOST_CTRL0_CLKSEL_SHIFT); - otgphy_sys |= (refclk_freq << OTG_SYS_CLKSEL_SHIFT); - - /* COMMON Block configuration during suspend */ - hostphy_ctrl0 |= (HOST_CTRL0_COMMONON_N); - otgphy_sys &= ~(OTG_SYS_COMMON_ON); - - /* otg phy reset */ - otgphy_sys &= ~(OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG - | OTG_SYS_FORCE_SLEEP); - otgphy_sys &= ~(OTG_SYS_REF_CLK_SEL_MASK << OTG_SYS_REF_CLK_SEL_SHIFT); - otgphy_sys |= (((OTG_SYS_REF_CLK_SEL_CLKCORE & OTG_SYS_REF_CLK_SEL_MASK) - << OTG_SYS_REF_CLK_SEL_SHIFT) - | OTG_SYS_OTGDISABLE); - otgphy_sys |= (OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG - | OTG_SYS_PHYLINK_SW_RESET); - writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS); - udelay(10); - otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG - | OTG_SYS_PHYLINK_SW_RESET); - writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS); - - /* host phy reset */ - hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL - | HOST_CTRL0_SIDDQ); - hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP); - hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST); - writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0); - udelay(10); - hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST); - writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0); - - /* HSIC phy reset */ - hsic_ctrl = (((HSIC_CTRL_REFCLKDIV_12 & HSIC_CTRL_REFCLKDIV_MASK) - << HSIC_CTRL_REFCLKDIV_SHIFT) - | ((HSIC_CTRL_REFCLKSEL & HSIC_CTRL_REFCLKSEL_MASK) - << HSIC_CTRL_REFCLKSEL_SHIFT) - | HSIC_CTRL_PHYSWRST); - writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1); - writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2); - udelay(10); - hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST); - writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1); - writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2); - - udelay(80); - - /* enable EHCI DMA burst */ - ehcictrl = readl(EXYNOS5_PHY_HOST_EHCICTRL); - ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4 - | EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16); - writel(ehcictrl, EXYNOS5_PHY_HOST_EHCICTRL); - - /* set ohci_suspend_on_n */ - ohcictrl = readl(EXYNOS5_PHY_HOST_OHCICTRL); - ohcictrl |= OHCICTRL_SUSPLGCY; - writel(ohcictrl, EXYNOS5_PHY_HOST_OHCICTRL); - - clk_disable(host_clk); - clk_put(host_clk); - return 0; -} - -static int exynos5_usb_phy20_exit(struct platform_device *pdev) -{ - struct clk *host_clk; - u32 hostphy_ctrl0; - u32 otgphy_sys; - u32 hsic_ctrl; - - if (atomic_dec_return(&host_usage) > 0) { - dev_info(&pdev->dev, "still being used\n"); - return -EBUSY; - } - - host_clk = exynos_usb_clock_enable(pdev); - if (host_clk == NULL) { - dev_err(&pdev->dev, "Failed to enable otg clock this time\n"); - return -1; - } - - hsic_ctrl = (((HSIC_CTRL_REFCLKDIV_12 & HSIC_CTRL_REFCLKDIV_MASK) - << HSIC_CTRL_REFCLKDIV_SHIFT) - | ((HSIC_CTRL_REFCLKSEL & HSIC_CTRL_REFCLKSEL_MASK) - << HSIC_CTRL_REFCLKSEL_SHIFT) - | HSIC_CTRL_SIDDQ | HSIC_CTRL_FORCESLEEP - | HSIC_CTRL_FORCESUSPEND); - writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1); - writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2); - - hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0); - hostphy_ctrl0 |= (HOST_CTRL0_SIDDQ); - hostphy_ctrl0 |= (HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP); - hostphy_ctrl0 |= (HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL); - writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0); - - otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS); - otgphy_sys |= (OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG - | OTG_SYS_FORCE_SLEEP); - writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS); - - exynos_usb_phy_control(USB_PHY, PHY_DISABLE); - - clk_disable(host_clk); - clk_put(host_clk); - return 0; -} int s5p_usb_phy_init(struct platform_device *pdev, int type) { - if (type == S5P_USB_PHY_DEVICE) + if (type == USB_PHY_TYPE_DEVICE) return exynos4210_usb_phy0_init(pdev); - else if (type == S5P_USB_PHY_HOST) { - if (soc_is_exynos5250()) - return exynos5_usb_phy20_init(pdev); - else + else if (type == USB_PHY_TYPE_HOST) { return exynos4210_usb_phy1_init(pdev); } @@ -429,13 +286,56 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type) int s5p_usb_phy_exit(struct platform_device *pdev, int type) { - if (type == S5P_USB_PHY_DEVICE) + + if (type == USB_PHY_TYPE_DEVICE) return exynos4210_usb_phy0_exit(pdev); - else if (type == S5P_USB_PHY_HOST) { - if (soc_is_exynos5250()) - return exynos5_usb_phy20_exit(pdev); - else + else if (type == USB_PHY_TYPE_HOST) { return exynos4210_usb_phy1_exit(pdev); } return -EINVAL; } + + void s5p_usb_phy_pmu_isolation(int on, int type) + { + if (type == USB_PHY_TYPE_HOST) { + if (on) + writel(readl(S5P_USBHOST_PHY_CONTROL) + & ~S5P_USBHOST_PHY_ENABLE, + S5P_USBHOST_PHY_CONTROL); + else + writel(readl(S5P_USBHOST_PHY_CONTROL) + | S5P_USBHOST_PHY_ENABLE, + S5P_USBHOST_PHY_CONTROL); + }else if(type == USB_PHY_TYPE_DRD) { + if (on) + writel(readl(S5P_USBDRD_PHY_CONTROL) + & ~S5P_USBDRD_PHY_ENABLE, + S5P_USBDRD_PHY_CONTROL); + else + writel(readl(S5P_USBDRD_PHY_CONTROL) + | S5P_USBDRD_PHY_ENABLE, + S5P_USBDRD_PHY_CONTROL); + } else { + if (on) + writel(readl(S5P_USBDEVICE_PHY_CONTROL) + & ~S5P_USBDEVICE_PHY_ENABLE, + S5P_USBDEVICE_PHY_CONTROL); + else + writel(readl(S5P_USBDEVICE_PHY_CONTROL) + | S5P_USBDEVICE_PHY_ENABLE, + S5P_USBDEVICE_PHY_CONTROL); + } + } + +/* Switch between HOST and OTG link from PHY_CFG */ +void s5p_usb_phy_cfg_sel(struct device *dev, int type) +{ + u32 is_host; + + is_host = readl(EXYNOS5_USB_CFG); + writel(type, EXYNOS5_USB_CFG); + + if (is_host != type) + dev_dbg(dev, "Changed USB MUX from %s to %s", + is_host ? "Host" : "Device", type ? "Host" : "Device"); +} diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h index 959bcdb03a2..72fb3122912 100644 --- a/arch/arm/plat-samsung/include/plat/usb-phy.h +++ b/arch/arm/plat-samsung/include/plat/usb-phy.h @@ -11,12 +11,8 @@ #ifndef __PLAT_SAMSUNG_USB_PHY_H #define __PLAT_SAMSUNG_USB_PHY_H __FILE__ -enum s5p_usb_phy_type { - S5P_USB_PHY_DEVICE, - S5P_USB_PHY_HOST, -}; - extern int s5p_usb_phy_init(struct platform_device *pdev, int type); extern int s5p_usb_phy_exit(struct platform_device *pdev, int type); - +extern void s5p_usb_phy_pmu_isolation(int on, int type); +extern void s5p_usb_phy_cfg_sel(struct device *dev, int type); #endif /* __PLAT_SAMSUNG_USB_PHY_H */ |