1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
4 * Copyright (C) 2010 Freescale Semiconductor, Inc.
5 */
6
7 #include <common.h>
8 #include <log.h>
9 #include <usb.h>
10 #include <errno.h>
11 #include <wait_bit.h>
12 #include <asm/global_data.h>
13 #include <linux/compiler.h>
14 #include <linux/delay.h>
15 #include <usb/ehci-ci.h>
16 #include <asm/io.h>
17 #include <asm/arch/imx-regs.h>
18 #include <asm/arch/clock.h>
19 #include <asm/mach-imx/iomux-v3.h>
20 #include <asm/mach-imx/sys_proto.h>
21 #include <dm.h>
22 #include <asm/mach-types.h>
23 #include <power/regulator.h>
24 #include <linux/usb/otg.h>
25
26 #include "ehci.h"
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 #define USB_OTGREGS_OFFSET 0x000
31 #define USB_H1REGS_OFFSET 0x200
32 #define USB_H2REGS_OFFSET 0x400
33 #define USB_H3REGS_OFFSET 0x600
34 #define USB_OTHERREGS_OFFSET 0x800
35
36 #define USB_H1_CTRL_OFFSET 0x04
37
38 #define USBPHY_CTRL 0x00000030
39 #define USBPHY_CTRL_SET 0x00000034
40 #define USBPHY_CTRL_CLR 0x00000038
41 #define USBPHY_CTRL_TOG 0x0000003c
42
43 #define USBPHY_PWD 0x00000000
44 #define USBPHY_CTRL_SFTRST 0x80000000
45 #define USBPHY_CTRL_CLKGATE 0x40000000
46 #define USBPHY_CTRL_ENUTMILEVEL3 0x00008000
47 #define USBPHY_CTRL_ENUTMILEVEL2 0x00004000
48 #define USBPHY_CTRL_OTG_ID 0x08000000
49
50 #define ANADIG_USB2_CHRG_DETECT_EN_B 0x00100000
51 #define ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B 0x00080000
52
53 #define ANADIG_USB2_PLL_480_CTRL_BYPASS 0x00010000
54 #define ANADIG_USB2_PLL_480_CTRL_ENABLE 0x00002000
55 #define ANADIG_USB2_PLL_480_CTRL_POWER 0x00001000
56 #define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS 0x00000040
57
58 #define USBNC_OFFSET 0x200
59 #define USBNC_PHY_STATUS_OFFSET 0x23C
60 #define USBNC_PHYSTATUS_ID_DIG (1 << 4) /* otg_id status */
61 #define USBNC_PHYCFG2_ACAENB (1 << 4) /* otg_id detection enable */
62 #define UCTRL_PWR_POL (1 << 9) /* OTG Polarity of Power Pin */
63 #define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */
64 #define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */
65
66 /* USBCMD */
67 #define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
68 #define UCMD_RESET (1 << 1) /* controller reset */
69
70 #if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
71 static const unsigned phy_bases[] = {
72 USB_PHY0_BASE_ADDR,
73 #if defined(USB_PHY1_BASE_ADDR)
74 USB_PHY1_BASE_ADDR,
75 #endif
76 };
77
usb_internal_phy_clock_gate(int index,int on)78 static void usb_internal_phy_clock_gate(int index, int on)
79 {
80 void __iomem *phy_reg;
81
82 if (index >= ARRAY_SIZE(phy_bases))
83 return;
84
85 phy_reg = (void __iomem *)phy_bases[index];
86 phy_reg += on ? USBPHY_CTRL_CLR : USBPHY_CTRL_SET;
87 writel(USBPHY_CTRL_CLKGATE, phy_reg);
88 }
89
usb_power_config(int index)90 static void usb_power_config(int index)
91 {
92 #if defined(CONFIG_MX7ULP)
93 struct usbphy_regs __iomem *usbphy =
94 (struct usbphy_regs __iomem *)USB_PHY0_BASE_ADDR;
95
96 if (index > 0)
97 return;
98
99 writel(ANADIG_USB2_CHRG_DETECT_EN_B |
100 ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
101 &usbphy->usb1_chrg_detect);
102
103 scg_enable_usb_pll(true);
104
105 #else
106 struct anatop_regs __iomem *anatop =
107 (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
108 void __iomem *chrg_detect;
109 void __iomem *pll_480_ctrl_clr;
110 void __iomem *pll_480_ctrl_set;
111
112 switch (index) {
113 case 0:
114 chrg_detect = &anatop->usb1_chrg_detect;
115 pll_480_ctrl_clr = &anatop->usb1_pll_480_ctrl_clr;
116 pll_480_ctrl_set = &anatop->usb1_pll_480_ctrl_set;
117 break;
118 case 1:
119 chrg_detect = &anatop->usb2_chrg_detect;
120 pll_480_ctrl_clr = &anatop->usb2_pll_480_ctrl_clr;
121 pll_480_ctrl_set = &anatop->usb2_pll_480_ctrl_set;
122 break;
123 default:
124 return;
125 }
126 /*
127 * Some phy and power's special controls
128 * 1. The external charger detector needs to be disabled
129 * or the signal at DP will be poor
130 * 2. The PLL's power and output to usb
131 * is totally controlled by IC, so the Software only needs
132 * to enable them at initializtion.
133 */
134 writel(ANADIG_USB2_CHRG_DETECT_EN_B |
135 ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
136 chrg_detect);
137
138 writel(ANADIG_USB2_PLL_480_CTRL_BYPASS,
139 pll_480_ctrl_clr);
140
141 writel(ANADIG_USB2_PLL_480_CTRL_ENABLE |
142 ANADIG_USB2_PLL_480_CTRL_POWER |
143 ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
144 pll_480_ctrl_set);
145
146 #endif
147 }
148
149 /* Return 0 : host node, <>0 : device mode */
usb_phy_enable(int index,struct usb_ehci * ehci)150 static int usb_phy_enable(int index, struct usb_ehci *ehci)
151 {
152 void __iomem *phy_reg;
153 void __iomem *phy_ctrl;
154 void __iomem *usb_cmd;
155 int ret;
156
157 if (index >= ARRAY_SIZE(phy_bases))
158 return 0;
159
160 phy_reg = (void __iomem *)phy_bases[index];
161 phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
162 usb_cmd = (void __iomem *)&ehci->usbcmd;
163
164 /* Stop then Reset */
165 clrbits_le32(usb_cmd, UCMD_RUN_STOP);
166 ret = wait_for_bit_le32(usb_cmd, UCMD_RUN_STOP, false, 10000, false);
167 if (ret)
168 return ret;
169
170 setbits_le32(usb_cmd, UCMD_RESET);
171 ret = wait_for_bit_le32(usb_cmd, UCMD_RESET, false, 10000, false);
172 if (ret)
173 return ret;
174
175 /* Reset USBPHY module */
176 setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST);
177 udelay(10);
178
179 /* Remove CLKGATE and SFTRST */
180 clrbits_le32(phy_ctrl, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST);
181 udelay(10);
182
183 /* Power up the PHY */
184 writel(0, phy_reg + USBPHY_PWD);
185 /* enable FS/LS device */
186 setbits_le32(phy_ctrl, USBPHY_CTRL_ENUTMILEVEL2 |
187 USBPHY_CTRL_ENUTMILEVEL3);
188
189 return 0;
190 }
191
usb_phy_mode(int port)192 int usb_phy_mode(int port)
193 {
194 void __iomem *phy_reg;
195 void __iomem *phy_ctrl;
196 u32 val;
197
198 phy_reg = (void __iomem *)phy_bases[port];
199 phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
200
201 val = readl(phy_ctrl);
202
203 if (val & USBPHY_CTRL_OTG_ID)
204 return USB_INIT_DEVICE;
205 else
206 return USB_INIT_HOST;
207 }
208
209 #if defined(CONFIG_MX7ULP)
210 struct usbnc_regs {
211 u32 ctrl1;
212 u32 ctrl2;
213 u32 reserve0[2];
214 u32 hsic_ctrl;
215 };
216 #else
217 /* Base address for this IP block is 0x02184800 */
218 struct usbnc_regs {
219 u32 ctrl[4]; /* otg/host1-3 */
220 u32 uh2_hsic_ctrl;
221 u32 uh3_hsic_ctrl;
222 u32 otg_phy_ctrl_0;
223 u32 uh1_phy_ctrl_0;
224 };
225 #endif
226
227 #elif defined(CONFIG_MX7)
228 struct usbnc_regs {
229 u32 ctrl1;
230 u32 ctrl2;
231 u32 reserve1[10];
232 u32 phy_cfg1;
233 u32 phy_cfg2;
234 u32 reserve2;
235 u32 phy_status;
236 u32 reserve3[4];
237 u32 adp_cfg1;
238 u32 adp_cfg2;
239 u32 adp_status;
240 };
241
usb_power_config(int index)242 static void usb_power_config(int index)
243 {
244 struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
245 (0x10000 * index) + USBNC_OFFSET);
246 void __iomem *phy_cfg2 = (void __iomem *)(&usbnc->phy_cfg2);
247
248 /*
249 * Clear the ACAENB to enable usb_otg_id detection,
250 * otherwise it is the ACA detection enabled.
251 */
252 clrbits_le32(phy_cfg2, USBNC_PHYCFG2_ACAENB);
253 }
254
usb_phy_mode(int port)255 int usb_phy_mode(int port)
256 {
257 struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
258 (0x10000 * port) + USBNC_OFFSET);
259 void __iomem *status = (void __iomem *)(&usbnc->phy_status);
260 u32 val;
261
262 val = readl(status);
263
264 if (val & USBNC_PHYSTATUS_ID_DIG)
265 return USB_INIT_DEVICE;
266 else
267 return USB_INIT_HOST;
268 }
269 #endif
270
usb_oc_config(int index)271 static void usb_oc_config(int index)
272 {
273 #if defined(CONFIG_MX6)
274 struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
275 USB_OTHERREGS_OFFSET);
276 void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl[index]);
277 #elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
278 struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
279 (0x10000 * index) + USBNC_OFFSET);
280 void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl1);
281 #endif
282
283 #if CONFIG_MACH_TYPE == MACH_TYPE_MX6Q_ARM2
284 /* mx6qarm2 seems to required a different setting*/
285 clrbits_le32(ctrl, UCTRL_OVER_CUR_POL);
286 #else
287 setbits_le32(ctrl, UCTRL_OVER_CUR_POL);
288 #endif
289
290 setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
291
292 /* Set power polarity to high active */
293 #ifdef CONFIG_MXC_USB_OTG_HACTIVE
294 setbits_le32(ctrl, UCTRL_PWR_POL);
295 #else
296 clrbits_le32(ctrl, UCTRL_PWR_POL);
297 #endif
298 }
299
300 /**
301 * board_usb_phy_mode - override usb phy mode
302 * @port: usb host/otg port
303 *
304 * Target board specific, override usb_phy_mode.
305 * When usb-otg is used as usb host port, iomux pad usb_otg_id can be
306 * left disconnected in this case usb_phy_mode will not be able to identify
307 * the phy mode that usb port is used.
308 * Machine file overrides board_usb_phy_mode.
309 *
310 * Return: USB_INIT_DEVICE or USB_INIT_HOST
311 */
board_usb_phy_mode(int port)312 int __weak board_usb_phy_mode(int port)
313 {
314 return usb_phy_mode(port);
315 }
316
317 /**
318 * board_ehci_hcd_init - set usb vbus voltage
319 * @port: usb otg port
320 *
321 * Target board specific, setup iomux pad to setup supply vbus voltage
322 * for usb otg port. Machine board file overrides board_ehci_hcd_init
323 *
324 * Return: 0 Success
325 */
board_ehci_hcd_init(int port)326 int __weak board_ehci_hcd_init(int port)
327 {
328 return 0;
329 }
330
331 /**
332 * board_ehci_power - enables/disables usb vbus voltage
333 * @port: usb otg port
334 * @on: on/off vbus voltage
335 *
336 * Enables/disables supply vbus voltage for usb otg port.
337 * Machine board file overrides board_ehci_power
338 *
339 * Return: 0 Success
340 */
board_ehci_power(int port,int on)341 int __weak board_ehci_power(int port, int on)
342 {
343 return 0;
344 }
345
ehci_mx6_common_init(struct usb_ehci * ehci,int index)346 int ehci_mx6_common_init(struct usb_ehci *ehci, int index)
347 {
348 int ret;
349
350 enable_usboh3_clk(1);
351 mdelay(1);
352
353 /* Do board specific initialization */
354 ret = board_ehci_hcd_init(index);
355 if (ret)
356 return ret;
357
358 usb_power_config(index);
359 usb_oc_config(index);
360
361 #if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
362 usb_internal_phy_clock_gate(index, 1);
363 usb_phy_enable(index, ehci);
364 #endif
365
366 return 0;
367 }
368
369 #if !CONFIG_IS_ENABLED(DM_USB)
ehci_hcd_init(int index,enum usb_init_type init,struct ehci_hccr ** hccr,struct ehci_hcor ** hcor)370 int ehci_hcd_init(int index, enum usb_init_type init,
371 struct ehci_hccr **hccr, struct ehci_hcor **hcor)
372 {
373 enum usb_init_type type;
374 #if defined(CONFIG_MX6)
375 u32 controller_spacing = 0x200;
376 #elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
377 u32 controller_spacing = 0x10000;
378 #endif
379 struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR +
380 (controller_spacing * index));
381 int ret;
382
383 if (index > 3)
384 return -EINVAL;
385
386 if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
387 if (usb_fused((ulong)ehci)) {
388 printf("SoC fuse indicates USB@0x%lx is unavailable.\n",
389 (ulong)ehci);
390 return -ENODEV;
391 }
392 }
393
394 ret = ehci_mx6_common_init(ehci, index);
395 if (ret)
396 return ret;
397
398 type = board_usb_phy_mode(index);
399
400 if (hccr && hcor) {
401 *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
402 *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
403 HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
404 }
405
406 if ((type == init) || (type == USB_INIT_DEVICE))
407 board_ehci_power(index, (type == USB_INIT_DEVICE) ? 0 : 1);
408 if (type != init)
409 return -ENODEV;
410 if (type == USB_INIT_DEVICE)
411 return 0;
412
413 setbits_le32(&ehci->usbmode, CM_HOST);
414 writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
415 setbits_le32(&ehci->portsc, USB_EN);
416
417 mdelay(10);
418
419 return 0;
420 }
421
ehci_hcd_stop(int index)422 int ehci_hcd_stop(int index)
423 {
424 return 0;
425 }
426 #else
427 struct ehci_mx6_priv_data {
428 struct ehci_ctrl ctrl;
429 struct usb_ehci *ehci;
430 struct udevice *vbus_supply;
431 enum usb_init_type init_type;
432 int portnr;
433 };
434
mx6_init_after_reset(struct ehci_ctrl * dev)435 static int mx6_init_after_reset(struct ehci_ctrl *dev)
436 {
437 struct ehci_mx6_priv_data *priv = dev->priv;
438 enum usb_init_type type = priv->init_type;
439 struct usb_ehci *ehci = priv->ehci;
440 int ret;
441
442 ret = ehci_mx6_common_init(priv->ehci, priv->portnr);
443 if (ret)
444 return ret;
445
446 #if CONFIG_IS_ENABLED(DM_REGULATOR)
447 if (priv->vbus_supply) {
448 ret = regulator_set_enable(priv->vbus_supply,
449 (type == USB_INIT_DEVICE) ?
450 false : true);
451 if (ret && ret != -ENOSYS) {
452 printf("Error enabling VBUS supply (ret=%i)\n", ret);
453 return ret;
454 }
455 }
456 #endif
457
458 if (type == USB_INIT_DEVICE)
459 return 0;
460
461 setbits_le32(&ehci->usbmode, CM_HOST);
462 writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
463 setbits_le32(&ehci->portsc, USB_EN);
464
465 mdelay(10);
466
467 return 0;
468 }
469
470 static const struct ehci_ops mx6_ehci_ops = {
471 .init_after_reset = mx6_init_after_reset
472 };
473
ehci_usb_phy_mode(struct udevice * dev)474 static int ehci_usb_phy_mode(struct udevice *dev)
475 {
476 struct usb_plat *plat = dev_get_plat(dev);
477 void *__iomem addr = dev_read_addr_ptr(dev);
478 void *__iomem phy_ctrl, *__iomem phy_status;
479 const void *blob = gd->fdt_blob;
480 int offset = dev_of_offset(dev), phy_off;
481 u32 val;
482
483 /*
484 * About fsl,usbphy, Refer to
485 * Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt.
486 */
487 if (is_mx6() || is_mx7ulp()) {
488 phy_off = fdtdec_lookup_phandle(blob,
489 offset,
490 "fsl,usbphy");
491 if (phy_off < 0)
492 return -EINVAL;
493
494 addr = (void __iomem *)fdtdec_get_addr(blob, phy_off,
495 "reg");
496 if ((fdt_addr_t)addr == FDT_ADDR_T_NONE)
497 return -EINVAL;
498
499 phy_ctrl = (void __iomem *)(addr + USBPHY_CTRL);
500 val = readl(phy_ctrl);
501
502 if (val & USBPHY_CTRL_OTG_ID)
503 plat->init_type = USB_INIT_DEVICE;
504 else
505 plat->init_type = USB_INIT_HOST;
506 } else if (is_mx7()) {
507 phy_status = (void __iomem *)(addr +
508 USBNC_PHY_STATUS_OFFSET);
509 val = readl(phy_status);
510
511 if (val & USBNC_PHYSTATUS_ID_DIG)
512 plat->init_type = USB_INIT_DEVICE;
513 else
514 plat->init_type = USB_INIT_HOST;
515 } else {
516 return -EINVAL;
517 }
518
519 return 0;
520 }
521
ehci_usb_of_to_plat(struct udevice * dev)522 static int ehci_usb_of_to_plat(struct udevice *dev)
523 {
524 struct usb_plat *plat = dev_get_plat(dev);
525 enum usb_dr_mode dr_mode;
526
527 dr_mode = usb_get_dr_mode(dev_ofnode(dev));
528
529 switch (dr_mode) {
530 case USB_DR_MODE_HOST:
531 plat->init_type = USB_INIT_HOST;
532 break;
533 case USB_DR_MODE_PERIPHERAL:
534 plat->init_type = USB_INIT_DEVICE;
535 break;
536 case USB_DR_MODE_OTG:
537 case USB_DR_MODE_UNKNOWN:
538 return ehci_usb_phy_mode(dev);
539 };
540
541 return 0;
542 }
543
ehci_usb_bind(struct udevice * dev)544 static int ehci_usb_bind(struct udevice *dev)
545 {
546 /*
547 * TODO:
548 * This driver is only partly converted to DT probing and still uses
549 * a tremendous amount of hard-coded addresses. To make things worse,
550 * the driver depends on specific sequential indexing of controllers,
551 * from which it derives offsets in the PHY and ANATOP register sets.
552 *
553 * Here we attempt to calculate these indexes from DT information as
554 * well as we can. The USB controllers on all existing iMX6 SoCs
555 * are placed next to each other, at addresses incremented by 0x200,
556 * and iMX7 their addresses are shifted by 0x10000.
557 * Thus, the index is derived from the multiple of 0x200 (0x10000 for
558 * iMX7) offset from the first controller address.
559 *
560 * However, to complete conversion of this driver to DT probing, the
561 * following has to be done:
562 * - DM clock framework support for iMX must be implemented
563 * - usb_power_config() has to be converted to clock framework
564 * -> Thus, the ad-hoc "index" variable goes away.
565 * - USB PHY handling has to be factored out into separate driver
566 * -> Thus, the ad-hoc "index" variable goes away from the PHY
567 * code, the PHY driver must parse it's address from DT. This
568 * USB driver must find the PHY driver via DT phandle.
569 * -> usb_power_config() shall be moved to PHY driver
570 * With these changes in place, the ad-hoc indexing goes away and
571 * the driver is fully converted to DT probing.
572 */
573
574 /*
575 * FIXME: This cannot work with the new sequence numbers.
576 * Please complete the DM conversion.
577 *
578 * u32 controller_spacing = is_mx7() ? 0x10000 : 0x200;
579 * fdt_addr_t addr = devfdt_get_addr_index(dev, 0);
580 *
581 * dev->req_seq = (addr - USB_BASE_ADDR) / controller_spacing;
582 */
583
584 return 0;
585 }
586
ehci_usb_probe(struct udevice * dev)587 static int ehci_usb_probe(struct udevice *dev)
588 {
589 struct usb_plat *plat = dev_get_plat(dev);
590 struct usb_ehci *ehci = dev_read_addr_ptr(dev);
591 struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
592 enum usb_init_type type = plat->init_type;
593 struct ehci_hccr *hccr;
594 struct ehci_hcor *hcor;
595 int ret;
596
597 if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
598 if (usb_fused((ulong)ehci)) {
599 printf("SoC fuse indicates USB@0x%lx is unavailable.\n",
600 (ulong)ehci);
601 return -ENODEV;
602 }
603 }
604
605 priv->ehci = ehci;
606 priv->portnr = dev_seq(dev);
607 priv->init_type = type;
608
609 #if CONFIG_IS_ENABLED(DM_REGULATOR)
610 ret = device_get_supply_regulator(dev, "vbus-supply",
611 &priv->vbus_supply);
612 if (ret)
613 debug("%s: No vbus supply\n", dev->name);
614 #endif
615 ret = ehci_mx6_common_init(ehci, priv->portnr);
616 if (ret)
617 return ret;
618
619 #if CONFIG_IS_ENABLED(DM_REGULATOR)
620 if (priv->vbus_supply) {
621 ret = regulator_set_enable(priv->vbus_supply,
622 (type == USB_INIT_DEVICE) ?
623 false : true);
624 if (ret && ret != -ENOSYS) {
625 printf("Error enabling VBUS supply (ret=%i)\n", ret);
626 return ret;
627 }
628 }
629 #endif
630
631 if (priv->init_type == USB_INIT_HOST) {
632 setbits_le32(&ehci->usbmode, CM_HOST);
633 writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
634 setbits_le32(&ehci->portsc, USB_EN);
635 }
636
637 mdelay(10);
638
639 hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
640 hcor = (struct ehci_hcor *)((uint32_t)hccr +
641 HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
642
643 return ehci_register(dev, hccr, hcor, &mx6_ehci_ops, 0, priv->init_type);
644 }
645
646 static const struct udevice_id mx6_usb_ids[] = {
647 { .compatible = "fsl,imx27-usb" },
648 { }
649 };
650
651 U_BOOT_DRIVER(usb_mx6) = {
652 .name = "ehci_mx6",
653 .id = UCLASS_USB,
654 .of_match = mx6_usb_ids,
655 .of_to_plat = ehci_usb_of_to_plat,
656 .bind = ehci_usb_bind,
657 .probe = ehci_usb_probe,
658 .remove = ehci_deregister,
659 .ops = &ehci_usb_ops,
660 .plat_auto = sizeof(struct usb_plat),
661 .priv_auto = sizeof(struct ehci_mx6_priv_data),
662 .flags = DM_FLAG_ALLOC_PRIV_DMA,
663 };
664 #endif
665