aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-mxc/ehci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-mxc/ehci.c')
-rw-r--r--arch/arm/plat-mxc/ehci.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index 9915607683de..8772ce346a58 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -49,6 +49,7 @@
49 49
50#define MXC_OTG_OFFSET 0 50#define MXC_OTG_OFFSET 0
51#define MXC_H1_OFFSET 0x200 51#define MXC_H1_OFFSET 0x200
52#define MXC_H2_OFFSET 0x400
52 53
53/* USB_CTRL */ 54/* USB_CTRL */
54#define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */ 55#define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
@@ -61,6 +62,11 @@
61#define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */ 62#define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
62#define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */ 63#define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
63 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
64#define MXC_USBCMD_OFFSET 0x140 70#define MXC_USBCMD_OFFSET 0x140
65 71
66/* USBCMD */ 72/* USBCMD */
@@ -69,9 +75,9 @@
69int mxc_initialize_usb_hw(int port, unsigned int flags) 75int mxc_initialize_usb_hw(int port, unsigned int flags)
70{ 76{
71 unsigned int v; 77 unsigned int v;
72#if defined(CONFIG_ARCH_MX25) 78#if defined(CONFIG_SOC_IMX25)
73 if (cpu_is_mx25()) { 79 if (cpu_is_mx25()) {
74 v = readl(MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR + 80 v = readl(MX25_IO_ADDRESS(MX25_USB_BASE_ADDR +
75 USBCTRL_OTGBASE_OFFSET)); 81 USBCTRL_OTGBASE_OFFSET));
76 82
77 switch (port) { 83 switch (port) {
@@ -108,14 +114,14 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
108 return -EINVAL; 114 return -EINVAL;
109 } 115 }
110 116
111 writel(v, MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR + 117 writel(v, MX25_IO_ADDRESS(MX25_USB_BASE_ADDR +
112 USBCTRL_OTGBASE_OFFSET)); 118 USBCTRL_OTGBASE_OFFSET));
113 return 0; 119 return 0;
114 } 120 }
115#endif /* CONFIG_ARCH_MX25 */ 121#endif /* if defined(CONFIG_SOC_IMX25) */
116#if defined(CONFIG_ARCH_MX3) 122#if defined(CONFIG_ARCH_MX3)
117 if (cpu_is_mx31()) { 123 if (cpu_is_mx31()) {
118 v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + 124 v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR +
119 USBCTRL_OTGBASE_OFFSET)); 125 USBCTRL_OTGBASE_OFFSET));
120 126
121 switch (port) { 127 switch (port) {
@@ -153,13 +159,13 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
153 return -EINVAL; 159 return -EINVAL;
154 } 160 }
155 161
156 writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + 162 writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR +
157 USBCTRL_OTGBASE_OFFSET)); 163 USBCTRL_OTGBASE_OFFSET));
158 return 0; 164 return 0;
159 } 165 }
160 166
161 if (cpu_is_mx35()) { 167 if (cpu_is_mx35()) {
162 v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + 168 v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
163 USBCTRL_OTGBASE_OFFSET)); 169 USBCTRL_OTGBASE_OFFSET));
164 170
165 switch (port) { 171 switch (port) {
@@ -196,7 +202,7 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
196 return -EINVAL; 202 return -EINVAL;
197 } 203 }
198 204
199 writel(v, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + 205 writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
200 USBCTRL_OTGBASE_OFFSET)); 206 USBCTRL_OTGBASE_OFFSET));
201 return 0; 207 return 0;
202 } 208 }
@@ -206,7 +212,7 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
206 /* On i.MX27 we can use the i.MX31 USBCTRL bits, they 212 /* On i.MX27 we can use the i.MX31 USBCTRL bits, they
207 * are identical 213 * are identical
208 */ 214 */
209 v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR + 215 v = readl(MX27_IO_ADDRESS(MX27_USB_BASE_ADDR +
210 USBCTRL_OTGBASE_OFFSET)); 216 USBCTRL_OTGBASE_OFFSET));
211 switch (port) { 217 switch (port) {
212 case 0: /* OTG port */ 218 case 0: /* OTG port */
@@ -241,12 +247,12 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
241 default: 247 default:
242 return -EINVAL; 248 return -EINVAL;
243 } 249 }
244 writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR + 250 writel(v, MX27_IO_ADDRESS(MX27_USB_BASE_ADDR +
245 USBCTRL_OTGBASE_OFFSET)); 251 USBCTRL_OTGBASE_OFFSET));
246 return 0; 252 return 0;
247 } 253 }
248#endif /* CONFIG_MACH_MX27 */ 254#endif /* CONFIG_MACH_MX27 */
249#ifdef CONFIG_ARCH_MX51 255#ifdef CONFIG_SOC_IMX51
250 if (cpu_is_mx51()) { 256 if (cpu_is_mx51()) {
251 void __iomem *usb_base; 257 void __iomem *usb_base;
252 void __iomem *usbotg_base; 258 void __iomem *usbotg_base;
@@ -254,6 +260,10 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
254 int ret = 0; 260 int ret = 0;
255 261
256 usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); 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 }
257 267
258 switch (port) { 268 switch (port) {
259 case 0: /* OTG port */ 269 case 0: /* OTG port */
@@ -262,6 +272,9 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
262 case 1: /* Host 1 port */ 272 case 1: /* Host 1 port */
263 usbotg_base = usb_base + MXC_H1_OFFSET; 273 usbotg_base = usb_base + MXC_H1_OFFSET;
264 break; 274 break;
275 case 2: /* Host 2 port */
276 usbotg_base = usb_base + MXC_H2_OFFSET;
277 break;
265 default: 278 default:
266 printk(KERN_ERR"%s no such port %d\n", __func__, port); 279 printk(KERN_ERR"%s no such port %d\n", __func__, port);
267 ret = -ENOENT; 280 ret = -ENOENT;
@@ -274,10 +287,13 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
274 if (flags & MXC_EHCI_INTERNAL_PHY) { 287 if (flags & MXC_EHCI_INTERNAL_PHY) {
275 v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); 288 v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
276 289
277 if (flags & MXC_EHCI_POWER_PINS_ENABLED) 290 if (flags & MXC_EHCI_POWER_PINS_ENABLED) {
278 v |= (MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is not used */ 291 /* OC/USBPWR is not used */
279 else 292 v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
280 v &= ~(MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is used */ 293 } else {
294 /* OC/USBPWR is used */
295 v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
296 }
281 __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); 297 __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
282 298
283 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); 299 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
@@ -285,16 +301,23 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
285 v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */ 301 v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
286 else 302 else
287 v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */ 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;
288 __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); 308 __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
289 } 309 }
290 break; 310 break;
291 case 1: /* Host 1 */ 311 case 1: /* Host 1 */
292 /*Host ULPI */ 312 /*Host ULPI */
293 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); 313 v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
294 if (flags & MXC_EHCI_WAKEUP_ENABLED) 314 if (flags & MXC_EHCI_WAKEUP_ENABLED) {
295 v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ 315 /* HOST1 wakeup/ULPI intr enable */
296 else 316 v |= (MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
297 v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ 317 } else {
318 /* HOST1 wakeup/ULPI intr disable */
319 v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
320 }
298 321
299 if (flags & MXC_EHCI_POWER_PINS_ENABLED) 322 if (flags & MXC_EHCI_POWER_PINS_ENABLED)
300 v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ 323 v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
@@ -315,6 +338,22 @@ int mxc_initialize_usb_hw(int port, unsigned int flags)
315 v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK; 338 v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
316 __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET); 339 __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
317 break; 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;
318 } 357 }
319 358
320error: 359error: