diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2011-01-03 04:33:01 -0500 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2011-02-11 02:34:17 -0500 |
commit | cb07625d1f84fb48e6849cb530762ffcc6f8e458 (patch) | |
tree | e3eecfdc41e5ee5236c339303d8705938a490fae /arch/arm/plat-mxc/ehci.c | |
parent | f19693a17c6705e197eb24d4618060eaac1b535c (diff) |
ARM i.MX ehci: factor out soc specific functions
Currently we have a mxc_initialize_usb_hw which is called on every
i.MX SoC. This function dispatches the different SoC types, which
is quite ugly. This patch moves the SoC specific USB initialization
to their correspondive mach directories.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/plat-mxc/ehci.c')
-rw-r--r-- | arch/arm/plat-mxc/ehci.c | 343 |
1 files changed, 10 insertions, 333 deletions
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c index 8772ce346a58..06fb3a4d7c27 100644 --- a/arch/arm/plat-mxc/ehci.c +++ b/arch/arm/plat-mxc/ehci.c | |||
@@ -14,352 +14,29 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/io.h> | ||
18 | 17 | ||
19 | #include <mach/hardware.h> | 18 | #include <mach/hardware.h> |
20 | #include <mach/mxc_ehci.h> | 19 | #include <mach/mxc_ehci.h> |
21 | 20 | ||
22 | #define USBCTRL_OTGBASE_OFFSET 0x600 | ||
23 | |||
24 | #define MX31_OTG_SIC_SHIFT 29 | ||
25 | #define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT) | ||
26 | #define MX31_OTG_PM_BIT (1 << 24) | ||
27 | |||
28 | #define MX31_H2_SIC_SHIFT 21 | ||
29 | #define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT) | ||
30 | #define MX31_H2_PM_BIT (1 << 16) | ||
31 | #define MX31_H2_DT_BIT (1 << 5) | ||
32 | |||
33 | #define MX31_H1_SIC_SHIFT 13 | ||
34 | #define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT) | ||
35 | #define MX31_H1_PM_BIT (1 << 8) | ||
36 | #define MX31_H1_DT_BIT (1 << 4) | ||
37 | |||
38 | #define MX35_OTG_SIC_SHIFT 29 | ||
39 | #define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT) | ||
40 | #define MX35_OTG_PM_BIT (1 << 24) | ||
41 | |||
42 | #define MX35_H1_SIC_SHIFT 21 | ||
43 | #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) | ||
44 | #define MX35_H1_PM_BIT (1 << 8) | ||
45 | #define MX35_H1_IPPUE_UP_BIT (1 << 7) | ||
46 | #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) | ||
47 | #define MX35_H1_TLL_BIT (1 << 5) | ||
48 | #define MX35_H1_USBTE_BIT (1 << 4) | ||
49 | |||
50 | #define MXC_OTG_OFFSET 0 | ||
51 | #define MXC_H1_OFFSET 0x200 | ||
52 | #define MXC_H2_OFFSET 0x400 | ||
53 | |||
54 | /* USB_CTRL */ | ||
55 | #define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */ | ||
56 | #define MXC_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */ | ||
57 | #define MXC_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */ | ||
58 | #define MXC_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */ | ||
59 | #define MXC_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */ | ||
60 | |||
61 | /* USB_PHY_CTRL_FUNC */ | ||
62 | #define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */ | ||
63 | #define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */ | ||
64 | |||
65 | /* USBH2CTRL */ | ||
66 | #define MXC_H2_UCTRL_H2UIE_BIT (1 << 8) | ||
67 | #define MXC_H2_UCTRL_H2WIE_BIT (1 << 7) | ||
68 | #define MXC_H2_UCTRL_H2PM_BIT (1 << 4) | ||
69 | |||
70 | #define MXC_USBCMD_OFFSET 0x140 | ||
71 | |||
72 | /* USBCMD */ | ||
73 | #define MXC_UCMD_ITC_NO_THRESHOLD_MASK (~(0xff << 16)) /* Interrupt Threshold Control */ | ||
74 | |||
75 | int mxc_initialize_usb_hw(int port, unsigned int flags) | 21 | int mxc_initialize_usb_hw(int port, unsigned int flags) |
76 | { | 22 | { |
77 | unsigned int v; | ||
78 | #if defined(CONFIG_SOC_IMX25) | 23 | #if defined(CONFIG_SOC_IMX25) |
79 | if (cpu_is_mx25()) { | 24 | if (cpu_is_mx25()) |
80 | v = readl(MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + | 25 | return mx25_initialize_usb_hw(port, flags); |
81 | USBCTRL_OTGBASE_OFFSET)); | ||
82 | |||
83 | switch (port) { | ||
84 | case 0: /* OTG port */ | ||
85 | v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT); | ||
86 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
87 | << MX35_OTG_SIC_SHIFT; | ||
88 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
89 | v |= MX35_OTG_PM_BIT; | ||
90 | |||
91 | break; | ||
92 | case 1: /* H1 port */ | ||
93 | v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT | | ||
94 | MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); | ||
95 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
96 | << MX35_H1_SIC_SHIFT; | ||
97 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
98 | v |= MX35_H1_PM_BIT; | ||
99 | |||
100 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
101 | v |= MX35_H1_TLL_BIT; | ||
102 | |||
103 | if (flags & MXC_EHCI_INTERNAL_PHY) | ||
104 | v |= MX35_H1_USBTE_BIT; | ||
105 | |||
106 | if (flags & MXC_EHCI_IPPUE_DOWN) | ||
107 | v |= MX35_H1_IPPUE_DOWN_BIT; | ||
108 | |||
109 | if (flags & MXC_EHCI_IPPUE_UP) | ||
110 | v |= MX35_H1_IPPUE_UP_BIT; | ||
111 | |||
112 | break; | ||
113 | default: | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | |||
117 | writel(v, MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + | ||
118 | USBCTRL_OTGBASE_OFFSET)); | ||
119 | return 0; | ||
120 | } | ||
121 | #endif /* if defined(CONFIG_SOC_IMX25) */ | 26 | #endif /* if defined(CONFIG_SOC_IMX25) */ |
122 | #if defined(CONFIG_ARCH_MX3) | 27 | #if defined(CONFIG_ARCH_MX3) |
123 | if (cpu_is_mx31()) { | 28 | if (cpu_is_mx31()) |
124 | v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + | 29 | return mx31_initialize_usb_hw(port, flags); |
125 | USBCTRL_OTGBASE_OFFSET)); | 30 | if (cpu_is_mx35()) |
126 | 31 | return mx35_initialize_usb_hw(port, flags); | |
127 | switch (port) { | ||
128 | case 0: /* OTG port */ | ||
129 | v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); | ||
130 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
131 | << MX31_OTG_SIC_SHIFT; | ||
132 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
133 | v |= MX31_OTG_PM_BIT; | ||
134 | |||
135 | break; | ||
136 | case 1: /* H1 port */ | ||
137 | v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); | ||
138 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
139 | << MX31_H1_SIC_SHIFT; | ||
140 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
141 | v |= MX31_H1_PM_BIT; | ||
142 | |||
143 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
144 | v |= MX31_H1_DT_BIT; | ||
145 | |||
146 | break; | ||
147 | case 2: /* H2 port */ | ||
148 | v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); | ||
149 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
150 | << MX31_H2_SIC_SHIFT; | ||
151 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
152 | v |= MX31_H2_PM_BIT; | ||
153 | |||
154 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
155 | v |= MX31_H2_DT_BIT; | ||
156 | |||
157 | break; | ||
158 | default: | ||
159 | return -EINVAL; | ||
160 | } | ||
161 | |||
162 | writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + | ||
163 | USBCTRL_OTGBASE_OFFSET)); | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | if (cpu_is_mx35()) { | ||
168 | v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + | ||
169 | USBCTRL_OTGBASE_OFFSET)); | ||
170 | |||
171 | switch (port) { | ||
172 | case 0: /* OTG port */ | ||
173 | v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT); | ||
174 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
175 | << MX35_OTG_SIC_SHIFT; | ||
176 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
177 | v |= MX35_OTG_PM_BIT; | ||
178 | |||
179 | break; | ||
180 | case 1: /* H1 port */ | ||
181 | v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT | | ||
182 | MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); | ||
183 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
184 | << MX35_H1_SIC_SHIFT; | ||
185 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
186 | v |= MX35_H1_PM_BIT; | ||
187 | |||
188 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
189 | v |= MX35_H1_TLL_BIT; | ||
190 | |||
191 | if (flags & MXC_EHCI_INTERNAL_PHY) | ||
192 | v |= MX35_H1_USBTE_BIT; | ||
193 | |||
194 | if (flags & MXC_EHCI_IPPUE_DOWN) | ||
195 | v |= MX35_H1_IPPUE_DOWN_BIT; | ||
196 | |||
197 | if (flags & MXC_EHCI_IPPUE_UP) | ||
198 | v |= MX35_H1_IPPUE_UP_BIT; | ||
199 | |||
200 | break; | ||
201 | default: | ||
202 | return -EINVAL; | ||
203 | } | ||
204 | |||
205 | writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + | ||
206 | USBCTRL_OTGBASE_OFFSET)); | ||
207 | return 0; | ||
208 | } | ||
209 | #endif /* CONFIG_ARCH_MX3 */ | 32 | #endif /* CONFIG_ARCH_MX3 */ |
210 | #ifdef CONFIG_MACH_MX27 | 33 | #ifdef CONFIG_MACH_MX27 |
211 | if (cpu_is_mx27()) { | 34 | if (cpu_is_mx27()) |
212 | /* On i.MX27 we can use the i.MX31 USBCTRL bits, they | 35 | return mx27_initialize_usb_hw(port, flags); |
213 | * are identical | ||
214 | */ | ||
215 | v = readl(MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + | ||
216 | USBCTRL_OTGBASE_OFFSET)); | ||
217 | switch (port) { | ||
218 | case 0: /* OTG port */ | ||
219 | v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); | ||
220 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
221 | << MX31_OTG_SIC_SHIFT; | ||
222 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
223 | v |= MX31_OTG_PM_BIT; | ||
224 | break; | ||
225 | case 1: /* H1 port */ | ||
226 | v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); | ||
227 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
228 | << MX31_H1_SIC_SHIFT; | ||
229 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
230 | v |= MX31_H1_PM_BIT; | ||
231 | |||
232 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
233 | v |= MX31_H1_DT_BIT; | ||
234 | |||
235 | break; | ||
236 | case 2: /* H2 port */ | ||
237 | v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); | ||
238 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
239 | << MX31_H2_SIC_SHIFT; | ||
240 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
241 | v |= MX31_H2_PM_BIT; | ||
242 | |||
243 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
244 | v |= MX31_H2_DT_BIT; | ||
245 | |||
246 | break; | ||
247 | default: | ||
248 | return -EINVAL; | ||
249 | } | ||
250 | writel(v, MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + | ||
251 | USBCTRL_OTGBASE_OFFSET)); | ||
252 | return 0; | ||
253 | } | ||
254 | #endif /* CONFIG_MACH_MX27 */ | 36 | #endif /* CONFIG_MACH_MX27 */ |
255 | #ifdef CONFIG_SOC_IMX51 | 37 | #ifdef CONFIG_SOC_IMX51 |
256 | if (cpu_is_mx51()) { | 38 | if (cpu_is_mx51()) |
257 | void __iomem *usb_base; | 39 | return mx51_initialize_usb_hw(port, flags); |
258 | void __iomem *usbotg_base; | ||
259 | void __iomem *usbother_base; | ||
260 | int ret = 0; | ||
261 | |||
262 | usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); | ||
263 | if (!usb_base) { | ||
264 | printk(KERN_ERR "%s(): ioremap failed\n", __func__); | ||
265 | return -ENOMEM; | ||
266 | } | ||
267 | |||
268 | switch (port) { | ||
269 | case 0: /* OTG port */ | ||
270 | usbotg_base = usb_base + MXC_OTG_OFFSET; | ||
271 | break; | ||
272 | case 1: /* Host 1 port */ | ||
273 | usbotg_base = usb_base + MXC_H1_OFFSET; | ||
274 | break; | ||
275 | case 2: /* Host 2 port */ | ||
276 | usbotg_base = usb_base + MXC_H2_OFFSET; | ||
277 | break; | ||
278 | default: | ||
279 | printk(KERN_ERR"%s no such port %d\n", __func__, port); | ||
280 | ret = -ENOENT; | ||
281 | goto error; | ||
282 | } | ||
283 | usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; | ||
284 | |||
285 | switch (port) { | ||
286 | case 0: /*OTG port */ | ||
287 | if (flags & MXC_EHCI_INTERNAL_PHY) { | ||
288 | v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); | ||
289 | |||
290 | if (flags & MXC_EHCI_POWER_PINS_ENABLED) { | ||
291 | /* OC/USBPWR is not used */ | ||
292 | v |= MXC_OTG_PHYCTRL_OC_DIS_BIT; | ||
293 | } else { | ||
294 | /* OC/USBPWR is used */ | ||
295 | v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT; | ||
296 | } | ||
297 | __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); | ||
298 | |||
299 | v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); | ||
300 | if (flags & MXC_EHCI_WAKEUP_ENABLED) | ||
301 | v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */ | ||
302 | else | ||
303 | v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */ | ||
304 | if (flags & MXC_EHCI_POWER_PINS_ENABLED) | ||
305 | v |= MXC_OTG_UCTRL_OPM_BIT; | ||
306 | else | ||
307 | v &= ~MXC_OTG_UCTRL_OPM_BIT; | ||
308 | __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); | ||
309 | } | ||
310 | break; | ||
311 | case 1: /* Host 1 */ | ||
312 | /*Host ULPI */ | ||
313 | v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); | ||
314 | if (flags & MXC_EHCI_WAKEUP_ENABLED) { | ||
315 | /* HOST1 wakeup/ULPI intr enable */ | ||
316 | v |= (MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT); | ||
317 | } else { | ||
318 | /* HOST1 wakeup/ULPI intr disable */ | ||
319 | v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT); | ||
320 | } | ||
321 | |||
322 | if (flags & MXC_EHCI_POWER_PINS_ENABLED) | ||
323 | v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ | ||
324 | else | ||
325 | v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ | ||
326 | __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); | ||
327 | |||
328 | v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); | ||
329 | if (flags & MXC_EHCI_POWER_PINS_ENABLED) | ||
330 | v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */ | ||
331 | else | ||
332 | v |= MXC_H1_OC_DIS_BIT; /* OC is not used */ | ||
333 | __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); | ||
334 | |||
335 | v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET); | ||
336 | if (flags & MXC_EHCI_ITC_NO_THRESHOLD) | ||
337 | /* Interrupt Threshold Control:Immediate (no threshold) */ | ||
338 | v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK; | ||
339 | __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET); | ||
340 | break; | ||
341 | case 2: /* Host 2 ULPI */ | ||
342 | v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET); | ||
343 | if (flags & MXC_EHCI_WAKEUP_ENABLED) { | ||
344 | /* HOST1 wakeup/ULPI intr enable */ | ||
345 | v |= (MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT); | ||
346 | } else { | ||
347 | /* HOST1 wakeup/ULPI intr disable */ | ||
348 | v &= ~(MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT); | ||
349 | } | ||
350 | |||
351 | if (flags & MXC_EHCI_POWER_PINS_ENABLED) | ||
352 | v &= ~MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/ | ||
353 | else | ||
354 | v |= MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/ | ||
355 | __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET); | ||
356 | break; | ||
357 | } | ||
358 | |||
359 | error: | ||
360 | iounmap(usb_base); | ||
361 | return ret; | ||
362 | } | ||
363 | #endif | 40 | #endif |
364 | printk(KERN_WARNING | 41 | printk(KERN_WARNING |
365 | "%s() unable to setup USBCONTROL for this CPU\n", __func__); | 42 | "%s() unable to setup USBCONTROL for this CPU\n", __func__); |