1a94bb7a4SSanchayan Maity /*
2a94bb7a4SSanchayan Maity * Copyright (c) 2015 Sanchayan Maity <sanchayan.maity@toradex.com>
3a94bb7a4SSanchayan Maity * Copyright (C) 2015 Toradex AG
4a94bb7a4SSanchayan Maity *
5a94bb7a4SSanchayan Maity * Based on ehci-mx6 driver
6a94bb7a4SSanchayan Maity *
7a94bb7a4SSanchayan Maity * SPDX-License-Identifier: GPL-2.0+
8a94bb7a4SSanchayan Maity */
9a94bb7a4SSanchayan Maity
10a94bb7a4SSanchayan Maity #include <common.h>
110885cdb9SSanchayan Maity #include <dm.h>
12a94bb7a4SSanchayan Maity #include <usb.h>
13a94bb7a4SSanchayan Maity #include <errno.h>
14a94bb7a4SSanchayan Maity #include <linux/compiler.h>
15a94bb7a4SSanchayan Maity #include <asm/io.h>
160885cdb9SSanchayan Maity #include <asm-generic/gpio.h>
17a94bb7a4SSanchayan Maity #include <asm/arch/clock.h>
18a94bb7a4SSanchayan Maity #include <asm/arch/imx-regs.h>
19a94bb7a4SSanchayan Maity #include <asm/arch/crm_regs.h>
20552a848eSStefano Babic #include <asm/mach-imx/iomux-v3.h>
21552a848eSStefano Babic #include <asm/mach-imx/regs-usbphy.h>
22e162c6b1SMateusz Kulikowski #include <usb/ehci-ci.h>
230e00a84cSMasahiro Yamada #include <linux/libfdt.h>
240885cdb9SSanchayan Maity #include <fdtdec.h>
25a94bb7a4SSanchayan Maity
26a94bb7a4SSanchayan Maity #include "ehci.h"
27a94bb7a4SSanchayan Maity
28a94bb7a4SSanchayan Maity #define USB_NC_REG_OFFSET 0x00000800
29a94bb7a4SSanchayan Maity
30a94bb7a4SSanchayan Maity #define ANADIG_PLL_CTRL_EN_USB_CLKS (1 << 6)
31a94bb7a4SSanchayan Maity
32a94bb7a4SSanchayan Maity #define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */
33a94bb7a4SSanchayan Maity #define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */
34a94bb7a4SSanchayan Maity
35a94bb7a4SSanchayan Maity /* USBCMD */
36a94bb7a4SSanchayan Maity #define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
37a94bb7a4SSanchayan Maity #define UCMD_RESET (1 << 1) /* controller reset */
38a94bb7a4SSanchayan Maity
390885cdb9SSanchayan Maity DECLARE_GLOBAL_DATA_PTR;
400885cdb9SSanchayan Maity
41a94bb7a4SSanchayan Maity static const unsigned phy_bases[] = {
42a94bb7a4SSanchayan Maity USB_PHY0_BASE_ADDR,
43a94bb7a4SSanchayan Maity USB_PHY1_BASE_ADDR,
44a94bb7a4SSanchayan Maity };
45a94bb7a4SSanchayan Maity
46a94bb7a4SSanchayan Maity static const unsigned nc_reg_bases[] = {
47a94bb7a4SSanchayan Maity USBC0_BASE_ADDR,
48a94bb7a4SSanchayan Maity USBC1_BASE_ADDR,
49a94bb7a4SSanchayan Maity };
50a94bb7a4SSanchayan Maity
usb_internal_phy_clock_gate(int index)51a94bb7a4SSanchayan Maity static void usb_internal_phy_clock_gate(int index)
52a94bb7a4SSanchayan Maity {
53a94bb7a4SSanchayan Maity void __iomem *phy_reg;
54a94bb7a4SSanchayan Maity
55a94bb7a4SSanchayan Maity phy_reg = (void __iomem *)phy_bases[index];
56a94bb7a4SSanchayan Maity clrbits_le32(phy_reg + USBPHY_CTRL, USBPHY_CTRL_CLKGATE);
57a94bb7a4SSanchayan Maity }
58a94bb7a4SSanchayan Maity
usb_power_config(int index)59a94bb7a4SSanchayan Maity static void usb_power_config(int index)
60a94bb7a4SSanchayan Maity {
61a94bb7a4SSanchayan Maity struct anadig_reg __iomem *anadig =
62a94bb7a4SSanchayan Maity (struct anadig_reg __iomem *)ANADIG_BASE_ADDR;
63a94bb7a4SSanchayan Maity void __iomem *pll_ctrl;
64a94bb7a4SSanchayan Maity
65a94bb7a4SSanchayan Maity switch (index) {
66a94bb7a4SSanchayan Maity case 0:
67a94bb7a4SSanchayan Maity pll_ctrl = &anadig->pll3_ctrl;
68a94bb7a4SSanchayan Maity clrbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_BYPASS);
69a94bb7a4SSanchayan Maity setbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_ENABLE
70a94bb7a4SSanchayan Maity | ANADIG_PLL3_CTRL_POWERDOWN
71a94bb7a4SSanchayan Maity | ANADIG_PLL_CTRL_EN_USB_CLKS);
72a94bb7a4SSanchayan Maity break;
73a94bb7a4SSanchayan Maity case 1:
74a94bb7a4SSanchayan Maity pll_ctrl = &anadig->pll7_ctrl;
75a94bb7a4SSanchayan Maity clrbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_BYPASS);
76a94bb7a4SSanchayan Maity setbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_ENABLE
77a94bb7a4SSanchayan Maity | ANADIG_PLL7_CTRL_POWERDOWN
78a94bb7a4SSanchayan Maity | ANADIG_PLL_CTRL_EN_USB_CLKS);
79a94bb7a4SSanchayan Maity break;
80a94bb7a4SSanchayan Maity default:
81a94bb7a4SSanchayan Maity return;
82a94bb7a4SSanchayan Maity }
83a94bb7a4SSanchayan Maity }
84a94bb7a4SSanchayan Maity
usb_phy_enable(int index,struct usb_ehci * ehci)85a94bb7a4SSanchayan Maity static void usb_phy_enable(int index, struct usb_ehci *ehci)
86a94bb7a4SSanchayan Maity {
87a94bb7a4SSanchayan Maity void __iomem *phy_reg;
88a94bb7a4SSanchayan Maity void __iomem *phy_ctrl;
89a94bb7a4SSanchayan Maity void __iomem *usb_cmd;
90a94bb7a4SSanchayan Maity
91a94bb7a4SSanchayan Maity phy_reg = (void __iomem *)phy_bases[index];
92a94bb7a4SSanchayan Maity phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
93a94bb7a4SSanchayan Maity usb_cmd = (void __iomem *)&ehci->usbcmd;
94a94bb7a4SSanchayan Maity
95a94bb7a4SSanchayan Maity /* Stop then Reset */
96a94bb7a4SSanchayan Maity clrbits_le32(usb_cmd, UCMD_RUN_STOP);
97a94bb7a4SSanchayan Maity while (readl(usb_cmd) & UCMD_RUN_STOP)
98a94bb7a4SSanchayan Maity ;
99a94bb7a4SSanchayan Maity
100a94bb7a4SSanchayan Maity setbits_le32(usb_cmd, UCMD_RESET);
101a94bb7a4SSanchayan Maity while (readl(usb_cmd) & UCMD_RESET)
102a94bb7a4SSanchayan Maity ;
103a94bb7a4SSanchayan Maity
104a94bb7a4SSanchayan Maity /* Reset USBPHY module */
105a94bb7a4SSanchayan Maity setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST);
106a94bb7a4SSanchayan Maity udelay(10);
107a94bb7a4SSanchayan Maity
108a94bb7a4SSanchayan Maity /* Remove CLKGATE and SFTRST */
109a94bb7a4SSanchayan Maity clrbits_le32(phy_ctrl, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST);
110a94bb7a4SSanchayan Maity udelay(10);
111a94bb7a4SSanchayan Maity
112a94bb7a4SSanchayan Maity /* Power up the PHY */
113a94bb7a4SSanchayan Maity writel(0, phy_reg + USBPHY_PWD);
114a94bb7a4SSanchayan Maity
115a94bb7a4SSanchayan Maity /* Enable FS/LS device */
116a94bb7a4SSanchayan Maity setbits_le32(phy_ctrl, USBPHY_CTRL_ENUTMILEVEL2 |
117a94bb7a4SSanchayan Maity USBPHY_CTRL_ENUTMILEVEL3);
118a94bb7a4SSanchayan Maity }
119a94bb7a4SSanchayan Maity
usb_oc_config(int index)120a94bb7a4SSanchayan Maity static void usb_oc_config(int index)
121a94bb7a4SSanchayan Maity {
122a94bb7a4SSanchayan Maity void __iomem *ctrl;
123a94bb7a4SSanchayan Maity
124a94bb7a4SSanchayan Maity ctrl = (void __iomem *)(nc_reg_bases[index] + USB_NC_REG_OFFSET);
125a94bb7a4SSanchayan Maity
126a94bb7a4SSanchayan Maity setbits_le32(ctrl, UCTRL_OVER_CUR_POL);
127a94bb7a4SSanchayan Maity setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
128a94bb7a4SSanchayan Maity }
129a94bb7a4SSanchayan Maity
board_usb_phy_mode(int port)13008c11cb5SSanchayan Maity int __weak board_usb_phy_mode(int port)
13108c11cb5SSanchayan Maity {
13208c11cb5SSanchayan Maity return 0;
13308c11cb5SSanchayan Maity }
13408c11cb5SSanchayan Maity
board_ehci_hcd_init(int port)13560ed2864SSanchayan Maity int __weak board_ehci_hcd_init(int port)
13660ed2864SSanchayan Maity {
13760ed2864SSanchayan Maity return 0;
13860ed2864SSanchayan Maity }
13960ed2864SSanchayan Maity
ehci_vf_common_init(struct usb_ehci * ehci,int index)1400885cdb9SSanchayan Maity int ehci_vf_common_init(struct usb_ehci *ehci, int index)
1410885cdb9SSanchayan Maity {
1420885cdb9SSanchayan Maity int ret;
1430885cdb9SSanchayan Maity
1440885cdb9SSanchayan Maity /* Do board specific initialisation */
1450885cdb9SSanchayan Maity ret = board_ehci_hcd_init(index);
1460885cdb9SSanchayan Maity if (ret)
1470885cdb9SSanchayan Maity return ret;
1480885cdb9SSanchayan Maity
1490885cdb9SSanchayan Maity usb_power_config(index);
1500885cdb9SSanchayan Maity usb_oc_config(index);
1510885cdb9SSanchayan Maity usb_internal_phy_clock_gate(index);
1520885cdb9SSanchayan Maity usb_phy_enable(index, ehci);
1530885cdb9SSanchayan Maity
1540885cdb9SSanchayan Maity return 0;
1550885cdb9SSanchayan Maity }
1560885cdb9SSanchayan Maity
157*3739bf7eSSven Schwermer #if !CONFIG_IS_ENABLED(DM_USB)
ehci_hcd_init(int index,enum usb_init_type init,struct ehci_hccr ** hccr,struct ehci_hcor ** hcor)158a94bb7a4SSanchayan Maity int ehci_hcd_init(int index, enum usb_init_type init,
159a94bb7a4SSanchayan Maity struct ehci_hccr **hccr, struct ehci_hcor **hcor)
160a94bb7a4SSanchayan Maity {
161a94bb7a4SSanchayan Maity struct usb_ehci *ehci;
16208c11cb5SSanchayan Maity enum usb_init_type type;
1630885cdb9SSanchayan Maity int ret;
164a94bb7a4SSanchayan Maity
165a94bb7a4SSanchayan Maity if (index >= ARRAY_SIZE(nc_reg_bases))
166a94bb7a4SSanchayan Maity return -EINVAL;
167a94bb7a4SSanchayan Maity
168a94bb7a4SSanchayan Maity ehci = (struct usb_ehci *)nc_reg_bases[index];
169a94bb7a4SSanchayan Maity
1700885cdb9SSanchayan Maity ret = ehci_vf_common_init(index);
1710885cdb9SSanchayan Maity if (ret)
1720885cdb9SSanchayan Maity return ret;
173a94bb7a4SSanchayan Maity
174a94bb7a4SSanchayan Maity *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
175a94bb7a4SSanchayan Maity *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
176a94bb7a4SSanchayan Maity HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
177a94bb7a4SSanchayan Maity
17808c11cb5SSanchayan Maity type = board_usb_phy_mode(index);
17908c11cb5SSanchayan Maity if (type != init)
18008c11cb5SSanchayan Maity return -ENODEV;
18108c11cb5SSanchayan Maity
182a94bb7a4SSanchayan Maity if (init == USB_INIT_DEVICE) {
183a94bb7a4SSanchayan Maity setbits_le32(&ehci->usbmode, CM_DEVICE);
184a94bb7a4SSanchayan Maity writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
185a94bb7a4SSanchayan Maity setbits_le32(&ehci->portsc, USB_EN);
186a94bb7a4SSanchayan Maity } else if (init == USB_INIT_HOST) {
187a94bb7a4SSanchayan Maity setbits_le32(&ehci->usbmode, CM_HOST);
188a94bb7a4SSanchayan Maity writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
189a94bb7a4SSanchayan Maity setbits_le32(&ehci->portsc, USB_EN);
190a94bb7a4SSanchayan Maity }
191a94bb7a4SSanchayan Maity
192a94bb7a4SSanchayan Maity return 0;
193a94bb7a4SSanchayan Maity }
194a94bb7a4SSanchayan Maity
ehci_hcd_stop(int index)195a94bb7a4SSanchayan Maity int ehci_hcd_stop(int index)
196a94bb7a4SSanchayan Maity {
197a94bb7a4SSanchayan Maity return 0;
198a94bb7a4SSanchayan Maity }
1990885cdb9SSanchayan Maity #else
2000885cdb9SSanchayan Maity /* Possible port types (dual role mode) */
2010885cdb9SSanchayan Maity enum dr_mode {
2020885cdb9SSanchayan Maity DR_MODE_NONE = 0,
2030885cdb9SSanchayan Maity DR_MODE_HOST, /* supports host operation */
2040885cdb9SSanchayan Maity DR_MODE_DEVICE, /* supports device operation */
2050885cdb9SSanchayan Maity DR_MODE_OTG, /* supports both */
2060885cdb9SSanchayan Maity };
2070885cdb9SSanchayan Maity
2080885cdb9SSanchayan Maity struct ehci_vf_priv_data {
2090885cdb9SSanchayan Maity struct ehci_ctrl ctrl;
2100885cdb9SSanchayan Maity struct usb_ehci *ehci;
2110885cdb9SSanchayan Maity struct gpio_desc cdet_gpio;
2120885cdb9SSanchayan Maity enum usb_init_type init_type;
2130885cdb9SSanchayan Maity enum dr_mode dr_mode;
2140885cdb9SSanchayan Maity u32 portnr;
2150885cdb9SSanchayan Maity };
2160885cdb9SSanchayan Maity
vf_usb_ofdata_to_platdata(struct udevice * dev)2170885cdb9SSanchayan Maity static int vf_usb_ofdata_to_platdata(struct udevice *dev)
2180885cdb9SSanchayan Maity {
2190885cdb9SSanchayan Maity struct ehci_vf_priv_data *priv = dev_get_priv(dev);
2200885cdb9SSanchayan Maity const void *dt_blob = gd->fdt_blob;
221e160f7d4SSimon Glass int node = dev_of_offset(dev);
2220885cdb9SSanchayan Maity const char *mode;
2230885cdb9SSanchayan Maity
2240885cdb9SSanchayan Maity priv->portnr = dev->seq;
2250885cdb9SSanchayan Maity
226a821c4afSSimon Glass priv->ehci = (struct usb_ehci *)devfdt_get_addr(dev);
2270885cdb9SSanchayan Maity mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
2280885cdb9SSanchayan Maity if (mode) {
2290885cdb9SSanchayan Maity if (0 == strcmp(mode, "host")) {
2300885cdb9SSanchayan Maity priv->dr_mode = DR_MODE_HOST;
2310885cdb9SSanchayan Maity priv->init_type = USB_INIT_HOST;
2320885cdb9SSanchayan Maity } else if (0 == strcmp(mode, "peripheral")) {
2330885cdb9SSanchayan Maity priv->dr_mode = DR_MODE_DEVICE;
2340885cdb9SSanchayan Maity priv->init_type = USB_INIT_DEVICE;
2350885cdb9SSanchayan Maity } else if (0 == strcmp(mode, "otg")) {
2360885cdb9SSanchayan Maity priv->dr_mode = DR_MODE_OTG;
2370885cdb9SSanchayan Maity /*
2380885cdb9SSanchayan Maity * We set init_type to device by default when OTG
2390885cdb9SSanchayan Maity * mode is requested. If a valid gpio is provided
2400885cdb9SSanchayan Maity * we will switch the init_type based on the state
2410885cdb9SSanchayan Maity * of the gpio pin.
2420885cdb9SSanchayan Maity */
2430885cdb9SSanchayan Maity priv->init_type = USB_INIT_DEVICE;
2440885cdb9SSanchayan Maity } else {
2450885cdb9SSanchayan Maity debug("%s: Cannot decode dr_mode '%s'\n",
2460885cdb9SSanchayan Maity __func__, mode);
2470885cdb9SSanchayan Maity return -EINVAL;
2480885cdb9SSanchayan Maity }
2490885cdb9SSanchayan Maity } else {
2500885cdb9SSanchayan Maity priv->dr_mode = DR_MODE_HOST;
2510885cdb9SSanchayan Maity priv->init_type = USB_INIT_HOST;
2520885cdb9SSanchayan Maity }
2530885cdb9SSanchayan Maity
2540885cdb9SSanchayan Maity if (priv->dr_mode == DR_MODE_OTG) {
255150c5afeSSimon Glass gpio_request_by_name_nodev(offset_to_ofnode(node),
256150c5afeSSimon Glass "fsl,cdet-gpio", 0, &priv->cdet_gpio,
257150c5afeSSimon Glass GPIOD_IS_IN);
2580885cdb9SSanchayan Maity if (dm_gpio_is_valid(&priv->cdet_gpio)) {
2590885cdb9SSanchayan Maity if (dm_gpio_get_value(&priv->cdet_gpio))
2600885cdb9SSanchayan Maity priv->init_type = USB_INIT_DEVICE;
2610885cdb9SSanchayan Maity else
2620885cdb9SSanchayan Maity priv->init_type = USB_INIT_HOST;
2630885cdb9SSanchayan Maity }
2640885cdb9SSanchayan Maity }
2650885cdb9SSanchayan Maity
2660885cdb9SSanchayan Maity return 0;
2670885cdb9SSanchayan Maity }
2680885cdb9SSanchayan Maity
vf_init_after_reset(struct ehci_ctrl * dev)2690885cdb9SSanchayan Maity static int vf_init_after_reset(struct ehci_ctrl *dev)
2700885cdb9SSanchayan Maity {
2710885cdb9SSanchayan Maity struct ehci_vf_priv_data *priv = dev->priv;
2720885cdb9SSanchayan Maity enum usb_init_type type = priv->init_type;
2730885cdb9SSanchayan Maity struct usb_ehci *ehci = priv->ehci;
2740885cdb9SSanchayan Maity int ret;
2750885cdb9SSanchayan Maity
2760885cdb9SSanchayan Maity ret = ehci_vf_common_init(priv->ehci, priv->portnr);
2770885cdb9SSanchayan Maity if (ret)
2780885cdb9SSanchayan Maity return ret;
2790885cdb9SSanchayan Maity
2800885cdb9SSanchayan Maity if (type == USB_INIT_DEVICE)
2810885cdb9SSanchayan Maity return 0;
2820885cdb9SSanchayan Maity
2830885cdb9SSanchayan Maity setbits_le32(&ehci->usbmode, CM_HOST);
2840885cdb9SSanchayan Maity writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
2850885cdb9SSanchayan Maity setbits_le32(&ehci->portsc, USB_EN);
2860885cdb9SSanchayan Maity
2870885cdb9SSanchayan Maity mdelay(10);
2880885cdb9SSanchayan Maity
2890885cdb9SSanchayan Maity return 0;
2900885cdb9SSanchayan Maity }
2910885cdb9SSanchayan Maity
2920885cdb9SSanchayan Maity static const struct ehci_ops vf_ehci_ops = {
2930885cdb9SSanchayan Maity .init_after_reset = vf_init_after_reset
2940885cdb9SSanchayan Maity };
2950885cdb9SSanchayan Maity
vf_usb_bind(struct udevice * dev)2960885cdb9SSanchayan Maity static int vf_usb_bind(struct udevice *dev)
2970885cdb9SSanchayan Maity {
2980885cdb9SSanchayan Maity static int num_controllers;
2990885cdb9SSanchayan Maity
3000885cdb9SSanchayan Maity /*
3010885cdb9SSanchayan Maity * Without this hack, if we return ENODEV for USB Controller 0, on
3020885cdb9SSanchayan Maity * probe for the next controller, USB Controller 1 will be given a
3030885cdb9SSanchayan Maity * sequence number of 0. This conflicts with our requirement of
3040885cdb9SSanchayan Maity * sequence numbers while initialising the peripherals.
3050885cdb9SSanchayan Maity */
3060885cdb9SSanchayan Maity dev->req_seq = num_controllers;
3070885cdb9SSanchayan Maity num_controllers++;
3080885cdb9SSanchayan Maity
3090885cdb9SSanchayan Maity return 0;
3100885cdb9SSanchayan Maity }
3110885cdb9SSanchayan Maity
ehci_usb_probe(struct udevice * dev)3120885cdb9SSanchayan Maity static int ehci_usb_probe(struct udevice *dev)
3130885cdb9SSanchayan Maity {
3140885cdb9SSanchayan Maity struct usb_platdata *plat = dev_get_platdata(dev);
3150885cdb9SSanchayan Maity struct ehci_vf_priv_data *priv = dev_get_priv(dev);
3160885cdb9SSanchayan Maity struct usb_ehci *ehci = priv->ehci;
3170885cdb9SSanchayan Maity struct ehci_hccr *hccr;
3180885cdb9SSanchayan Maity struct ehci_hcor *hcor;
3190885cdb9SSanchayan Maity int ret;
3200885cdb9SSanchayan Maity
3210885cdb9SSanchayan Maity ret = ehci_vf_common_init(ehci, priv->portnr);
3220885cdb9SSanchayan Maity if (ret)
3230885cdb9SSanchayan Maity return ret;
3240885cdb9SSanchayan Maity
3250885cdb9SSanchayan Maity if (priv->init_type != plat->init_type)
3260885cdb9SSanchayan Maity return -ENODEV;
3270885cdb9SSanchayan Maity
3280885cdb9SSanchayan Maity if (priv->init_type == USB_INIT_HOST) {
3290885cdb9SSanchayan Maity setbits_le32(&ehci->usbmode, CM_HOST);
3300885cdb9SSanchayan Maity writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
3310885cdb9SSanchayan Maity setbits_le32(&ehci->portsc, USB_EN);
3320885cdb9SSanchayan Maity }
3330885cdb9SSanchayan Maity
3340885cdb9SSanchayan Maity mdelay(10);
3350885cdb9SSanchayan Maity
3360885cdb9SSanchayan Maity hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
3370885cdb9SSanchayan Maity hcor = (struct ehci_hcor *)((uint32_t)hccr +
3380885cdb9SSanchayan Maity HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
3390885cdb9SSanchayan Maity
3400885cdb9SSanchayan Maity return ehci_register(dev, hccr, hcor, &vf_ehci_ops, 0, priv->init_type);
3410885cdb9SSanchayan Maity }
3420885cdb9SSanchayan Maity
3430885cdb9SSanchayan Maity static const struct udevice_id vf_usb_ids[] = {
3440885cdb9SSanchayan Maity { .compatible = "fsl,vf610-usb" },
3450885cdb9SSanchayan Maity { }
3460885cdb9SSanchayan Maity };
3470885cdb9SSanchayan Maity
3480885cdb9SSanchayan Maity U_BOOT_DRIVER(usb_ehci) = {
3490885cdb9SSanchayan Maity .name = "ehci_vf",
3500885cdb9SSanchayan Maity .id = UCLASS_USB,
3510885cdb9SSanchayan Maity .of_match = vf_usb_ids,
3520885cdb9SSanchayan Maity .bind = vf_usb_bind,
3530885cdb9SSanchayan Maity .probe = ehci_usb_probe,
35499e2df47SMasahiro Yamada .remove = ehci_deregister,
3550885cdb9SSanchayan Maity .ops = &ehci_usb_ops,
3560885cdb9SSanchayan Maity .ofdata_to_platdata = vf_usb_ofdata_to_platdata,
3570885cdb9SSanchayan Maity .platdata_auto_alloc_size = sizeof(struct usb_platdata),
3580885cdb9SSanchayan Maity .priv_auto_alloc_size = sizeof(struct ehci_vf_priv_data),
3590885cdb9SSanchayan Maity .flags = DM_FLAG_ALLOC_PRIV_DMA,
3600885cdb9SSanchayan Maity };
3610885cdb9SSanchayan Maity #endif
362