diff options
author | Lukasz Majewski <l.majewski@samsung.com> | 2012-05-12 19:28:28 -0400 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2012-05-16 09:31:44 -0400 |
commit | 8ea2d9e7de03d147d0bd0ac684fef00e469705e0 (patch) | |
tree | 441a36858c5baf836229b94970207506cd0c7de8 /arch/arm | |
parent | 36be50515fe2aef61533b516fa2576a2c7fe7664 (diff) |
ARM: EXYNOS: Add usb otg phy control for EXYNOS4210
This patch supports to control usb otg phy of EXYNOS4210.
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
[Rebased on the newest git/kgene/linux-samsung #for-next]
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
[kgene.kim@samsung.com: squashed 2 patches together]
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-exynos/include/mach/irqs.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-exynos/include/mach/map.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos/include/mach/regs-pmu.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-exynos/setup-usb-phy.c | 100 |
4 files changed, 80 insertions, 28 deletions
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index 591e78521a9f..c02dae7bf4a3 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h | |||
@@ -189,6 +189,7 @@ | |||
189 | #define IRQ_IIC7 EXYNOS4_IRQ_IIC7 | 189 | #define IRQ_IIC7 EXYNOS4_IRQ_IIC7 |
190 | 190 | ||
191 | #define IRQ_USB_HOST EXYNOS4_IRQ_USB_HOST | 191 | #define IRQ_USB_HOST EXYNOS4_IRQ_USB_HOST |
192 | #define IRQ_OTG EXYNOS4_IRQ_USB_HSOTG | ||
192 | 193 | ||
193 | #define IRQ_HSMMC0 EXYNOS4_IRQ_HSMMC0 | 194 | #define IRQ_HSMMC0 EXYNOS4_IRQ_HSMMC0 |
194 | #define IRQ_HSMMC1 EXYNOS4_IRQ_HSMMC1 | 195 | #define IRQ_HSMMC1 EXYNOS4_IRQ_HSMMC1 |
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 6e6d11ff352a..e009a66477f4 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h | |||
@@ -130,6 +130,9 @@ | |||
130 | #define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) | 130 | #define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) |
131 | #define EXYNOS4_PA_DWMCI 0x12550000 | 131 | #define EXYNOS4_PA_DWMCI 0x12550000 |
132 | 132 | ||
133 | #define EXYNOS4_PA_HSOTG 0x12480000 | ||
134 | #define EXYNOS4_PA_USB_HSPHY 0x125B0000 | ||
135 | |||
133 | #define EXYNOS4_PA_SATA 0x12560000 | 136 | #define EXYNOS4_PA_SATA 0x12560000 |
134 | #define EXYNOS4_PA_SATAPHY 0x125D0000 | 137 | #define EXYNOS4_PA_SATAPHY 0x125D0000 |
135 | #define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000 | 138 | #define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000 |
@@ -186,6 +189,7 @@ | |||
186 | #define S3C_PA_SPI0 EXYNOS4_PA_SPI0 | 189 | #define S3C_PA_SPI0 EXYNOS4_PA_SPI0 |
187 | #define S3C_PA_SPI1 EXYNOS4_PA_SPI1 | 190 | #define S3C_PA_SPI1 EXYNOS4_PA_SPI1 |
188 | #define S3C_PA_SPI2 EXYNOS4_PA_SPI2 | 191 | #define S3C_PA_SPI2 EXYNOS4_PA_SPI2 |
192 | #define S3C_PA_USB_HSOTG EXYNOS4_PA_HSOTG | ||
189 | 193 | ||
190 | #define S5P_PA_EHCI EXYNOS4_PA_EHCI | 194 | #define S5P_PA_EHCI EXYNOS4_PA_EHCI |
191 | #define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0 | 195 | #define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0 |
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 4c53f38b5a9e..d457d052a420 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h | |||
@@ -163,6 +163,9 @@ | |||
163 | #define S5P_CHECK_SLEEP 0x00000BAD | 163 | #define S5P_CHECK_SLEEP 0x00000BAD |
164 | 164 | ||
165 | /* Only for EXYNOS4210 */ | 165 | /* Only for EXYNOS4210 */ |
166 | #define S5P_USBDEVICE_PHY_CONTROL S5P_PMUREG(0x0704) | ||
167 | #define S5P_USBDEVICE_PHY_ENABLE (1 << 0) | ||
168 | |||
166 | #define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708) | 169 | #define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708) |
167 | #define S5P_USBHOST_PHY_ENABLE (1 << 0) | 170 | #define S5P_USBHOST_PHY_ENABLE (1 << 0) |
168 | 171 | ||
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c index 41743d21e8c6..1af0a7f44e00 100644 --- a/arch/arm/mach-exynos/setup-usb-phy.c +++ b/arch/arm/mach-exynos/setup-usb-phy.c | |||
@@ -26,11 +26,71 @@ static int exynos4_usb_host_phy_is_on(void) | |||
26 | return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1; | 26 | return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1; |
27 | } | 27 | } |
28 | 28 | ||
29 | static int exynos4_usb_phy1_init(struct platform_device *pdev) | 29 | static void exynos4210_usb_phy_clkset(struct platform_device *pdev) |
30 | { | 30 | { |
31 | struct clk *otg_clk; | ||
32 | struct clk *xusbxti_clk; | 31 | struct clk *xusbxti_clk; |
33 | u32 phyclk; | 32 | u32 phyclk; |
33 | |||
34 | /* set clock frequency for PLL */ | ||
35 | phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK; | ||
36 | |||
37 | xusbxti_clk = clk_get(&pdev->dev, "xusbxti"); | ||
38 | if (xusbxti_clk && !IS_ERR(xusbxti_clk)) { | ||
39 | switch (clk_get_rate(xusbxti_clk)) { | ||
40 | case 12 * MHZ: | ||
41 | phyclk |= CLKSEL_12M; | ||
42 | break; | ||
43 | case 24 * MHZ: | ||
44 | phyclk |= CLKSEL_24M; | ||
45 | break; | ||
46 | default: | ||
47 | case 48 * MHZ: | ||
48 | /* default reference clock */ | ||
49 | break; | ||
50 | } | ||
51 | clk_put(xusbxti_clk); | ||
52 | } | ||
53 | |||
54 | writel(phyclk, EXYNOS4_PHYCLK); | ||
55 | } | ||
56 | |||
57 | static int exynos4210_usb_phy0_init(struct platform_device *pdev) | ||
58 | { | ||
59 | u32 rstcon; | ||
60 | |||
61 | writel(readl(S5P_USBDEVICE_PHY_CONTROL) | S5P_USBDEVICE_PHY_ENABLE, | ||
62 | S5P_USBDEVICE_PHY_CONTROL); | ||
63 | |||
64 | exynos4210_usb_phy_clkset(pdev); | ||
65 | |||
66 | /* set to normal PHY0 */ | ||
67 | writel((readl(EXYNOS4_PHYPWR) & ~PHY0_NORMAL_MASK), EXYNOS4_PHYPWR); | ||
68 | |||
69 | /* reset PHY0 and Link */ | ||
70 | rstcon = readl(EXYNOS4_RSTCON) | PHY0_SWRST_MASK; | ||
71 | writel(rstcon, EXYNOS4_RSTCON); | ||
72 | udelay(10); | ||
73 | |||
74 | rstcon &= ~PHY0_SWRST_MASK; | ||
75 | writel(rstcon, EXYNOS4_RSTCON); | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int exynos4210_usb_phy0_exit(struct platform_device *pdev) | ||
81 | { | ||
82 | writel((readl(EXYNOS4_PHYPWR) | PHY0_ANALOG_POWERDOWN | | ||
83 | PHY0_OTG_DISABLE), EXYNOS4_PHYPWR); | ||
84 | |||
85 | writel(readl(S5P_USBDEVICE_PHY_CONTROL) & ~S5P_USBDEVICE_PHY_ENABLE, | ||
86 | S5P_USBDEVICE_PHY_CONTROL); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int exynos4210_usb_phy1_init(struct platform_device *pdev) | ||
92 | { | ||
93 | struct clk *otg_clk; | ||
34 | u32 rstcon; | 94 | u32 rstcon; |
35 | int err; | 95 | int err; |
36 | 96 | ||
@@ -54,27 +114,7 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev) | |||
54 | writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, | 114 | writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, |
55 | S5P_USBHOST_PHY_CONTROL); | 115 | S5P_USBHOST_PHY_CONTROL); |
56 | 116 | ||
57 | /* set clock frequency for PLL */ | 117 | exynos4210_usb_phy_clkset(pdev); |
58 | phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK; | ||
59 | |||
60 | xusbxti_clk = clk_get(&pdev->dev, "xusbxti"); | ||
61 | if (xusbxti_clk && !IS_ERR(xusbxti_clk)) { | ||
62 | switch (clk_get_rate(xusbxti_clk)) { | ||
63 | case 12 * MHZ: | ||
64 | phyclk |= CLKSEL_12M; | ||
65 | break; | ||
66 | case 24 * MHZ: | ||
67 | phyclk |= CLKSEL_24M; | ||
68 | break; | ||
69 | default: | ||
70 | case 48 * MHZ: | ||
71 | /* default reference clock */ | ||
72 | break; | ||
73 | } | ||
74 | clk_put(xusbxti_clk); | ||
75 | } | ||
76 | |||
77 | writel(phyclk, EXYNOS4_PHYCLK); | ||
78 | 118 | ||
79 | /* floating prevention logic: disable */ | 119 | /* floating prevention logic: disable */ |
80 | writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON); | 120 | writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON); |
@@ -102,7 +142,7 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev) | |||
102 | return 0; | 142 | return 0; |
103 | } | 143 | } |
104 | 144 | ||
105 | static int exynos4_usb_phy1_exit(struct platform_device *pdev) | 145 | static int exynos4210_usb_phy1_exit(struct platform_device *pdev) |
106 | { | 146 | { |
107 | struct clk *otg_clk; | 147 | struct clk *otg_clk; |
108 | int err; | 148 | int err; |
@@ -136,16 +176,20 @@ static int exynos4_usb_phy1_exit(struct platform_device *pdev) | |||
136 | 176 | ||
137 | int s5p_usb_phy_init(struct platform_device *pdev, int type) | 177 | int s5p_usb_phy_init(struct platform_device *pdev, int type) |
138 | { | 178 | { |
139 | if (type == S5P_USB_PHY_HOST) | 179 | if (type == S5P_USB_PHY_DEVICE) |
140 | return exynos4_usb_phy1_init(pdev); | 180 | return exynos4210_usb_phy0_init(pdev); |
181 | else if (type == S5P_USB_PHY_HOST) | ||
182 | return exynos4210_usb_phy1_init(pdev); | ||
141 | 183 | ||
142 | return -EINVAL; | 184 | return -EINVAL; |
143 | } | 185 | } |
144 | 186 | ||
145 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) | 187 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) |
146 | { | 188 | { |
147 | if (type == S5P_USB_PHY_HOST) | 189 | if (type == S5P_USB_PHY_DEVICE) |
148 | return exynos4_usb_phy1_exit(pdev); | 190 | return exynos4210_usb_phy0_exit(pdev); |
191 | else if (type == S5P_USB_PHY_HOST) | ||
192 | return exynos4210_usb_phy1_exit(pdev); | ||
149 | 193 | ||
150 | return -EINVAL; | 194 | return -EINVAL; |
151 | } | 195 | } |