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> 20a94bb7a4SSanchayan Maity #include <asm/imx-common/iomux-v3.h> 21a94bb7a4SSanchayan Maity #include <asm/imx-common/regs-usbphy.h> 22e162c6b1SMateusz Kulikowski #include <usb/ehci-ci.h> 230885cdb9SSanchayan Maity #include <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 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 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 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 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 13008c11cb5SSanchayan Maity int __weak board_usb_phy_mode(int port) 13108c11cb5SSanchayan Maity { 13208c11cb5SSanchayan Maity return 0; 13308c11cb5SSanchayan Maity } 13408c11cb5SSanchayan Maity 13560ed2864SSanchayan Maity int __weak board_ehci_hcd_init(int port) 13660ed2864SSanchayan Maity { 13760ed2864SSanchayan Maity return 0; 13860ed2864SSanchayan Maity } 13960ed2864SSanchayan Maity 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 1570885cdb9SSanchayan Maity #ifndef CONFIG_DM_USB 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 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 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 226*a821c4afSSimon 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) { 2550885cdb9SSanchayan Maity gpio_request_by_name_nodev(dt_blob, node, "fsl,cdet-gpio", 0, 2560885cdb9SSanchayan Maity &priv->cdet_gpio, GPIOD_IS_IN); 2570885cdb9SSanchayan Maity if (dm_gpio_is_valid(&priv->cdet_gpio)) { 2580885cdb9SSanchayan Maity if (dm_gpio_get_value(&priv->cdet_gpio)) 2590885cdb9SSanchayan Maity priv->init_type = USB_INIT_DEVICE; 2600885cdb9SSanchayan Maity else 2610885cdb9SSanchayan Maity priv->init_type = USB_INIT_HOST; 2620885cdb9SSanchayan Maity } 2630885cdb9SSanchayan Maity } 2640885cdb9SSanchayan Maity 2650885cdb9SSanchayan Maity return 0; 2660885cdb9SSanchayan Maity } 2670885cdb9SSanchayan Maity 2680885cdb9SSanchayan Maity static int vf_init_after_reset(struct ehci_ctrl *dev) 2690885cdb9SSanchayan Maity { 2700885cdb9SSanchayan Maity struct ehci_vf_priv_data *priv = dev->priv; 2710885cdb9SSanchayan Maity enum usb_init_type type = priv->init_type; 2720885cdb9SSanchayan Maity struct usb_ehci *ehci = priv->ehci; 2730885cdb9SSanchayan Maity int ret; 2740885cdb9SSanchayan Maity 2750885cdb9SSanchayan Maity ret = ehci_vf_common_init(priv->ehci, priv->portnr); 2760885cdb9SSanchayan Maity if (ret) 2770885cdb9SSanchayan Maity return ret; 2780885cdb9SSanchayan Maity 2790885cdb9SSanchayan Maity if (type == USB_INIT_DEVICE) 2800885cdb9SSanchayan Maity return 0; 2810885cdb9SSanchayan Maity 2820885cdb9SSanchayan Maity setbits_le32(&ehci->usbmode, CM_HOST); 2830885cdb9SSanchayan Maity writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); 2840885cdb9SSanchayan Maity setbits_le32(&ehci->portsc, USB_EN); 2850885cdb9SSanchayan Maity 2860885cdb9SSanchayan Maity mdelay(10); 2870885cdb9SSanchayan Maity 2880885cdb9SSanchayan Maity return 0; 2890885cdb9SSanchayan Maity } 2900885cdb9SSanchayan Maity 2910885cdb9SSanchayan Maity static const struct ehci_ops vf_ehci_ops = { 2920885cdb9SSanchayan Maity .init_after_reset = vf_init_after_reset 2930885cdb9SSanchayan Maity }; 2940885cdb9SSanchayan Maity 2950885cdb9SSanchayan Maity static int vf_usb_bind(struct udevice *dev) 2960885cdb9SSanchayan Maity { 2970885cdb9SSanchayan Maity static int num_controllers; 2980885cdb9SSanchayan Maity 2990885cdb9SSanchayan Maity /* 3000885cdb9SSanchayan Maity * Without this hack, if we return ENODEV for USB Controller 0, on 3010885cdb9SSanchayan Maity * probe for the next controller, USB Controller 1 will be given a 3020885cdb9SSanchayan Maity * sequence number of 0. This conflicts with our requirement of 3030885cdb9SSanchayan Maity * sequence numbers while initialising the peripherals. 3040885cdb9SSanchayan Maity */ 3050885cdb9SSanchayan Maity dev->req_seq = num_controllers; 3060885cdb9SSanchayan Maity num_controllers++; 3070885cdb9SSanchayan Maity 3080885cdb9SSanchayan Maity return 0; 3090885cdb9SSanchayan Maity } 3100885cdb9SSanchayan Maity 3110885cdb9SSanchayan Maity static int ehci_usb_probe(struct udevice *dev) 3120885cdb9SSanchayan Maity { 3130885cdb9SSanchayan Maity struct usb_platdata *plat = dev_get_platdata(dev); 3140885cdb9SSanchayan Maity struct ehci_vf_priv_data *priv = dev_get_priv(dev); 3150885cdb9SSanchayan Maity struct usb_ehci *ehci = priv->ehci; 3160885cdb9SSanchayan Maity struct ehci_hccr *hccr; 3170885cdb9SSanchayan Maity struct ehci_hcor *hcor; 3180885cdb9SSanchayan Maity int ret; 3190885cdb9SSanchayan Maity 3200885cdb9SSanchayan Maity ret = ehci_vf_common_init(ehci, priv->portnr); 3210885cdb9SSanchayan Maity if (ret) 3220885cdb9SSanchayan Maity return ret; 3230885cdb9SSanchayan Maity 3240885cdb9SSanchayan Maity if (priv->init_type != plat->init_type) 3250885cdb9SSanchayan Maity return -ENODEV; 3260885cdb9SSanchayan Maity 3270885cdb9SSanchayan Maity if (priv->init_type == USB_INIT_HOST) { 3280885cdb9SSanchayan Maity setbits_le32(&ehci->usbmode, CM_HOST); 3290885cdb9SSanchayan Maity writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); 3300885cdb9SSanchayan Maity setbits_le32(&ehci->portsc, USB_EN); 3310885cdb9SSanchayan Maity } 3320885cdb9SSanchayan Maity 3330885cdb9SSanchayan Maity mdelay(10); 3340885cdb9SSanchayan Maity 3350885cdb9SSanchayan Maity hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); 3360885cdb9SSanchayan Maity hcor = (struct ehci_hcor *)((uint32_t)hccr + 3370885cdb9SSanchayan Maity HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 3380885cdb9SSanchayan Maity 3390885cdb9SSanchayan Maity return ehci_register(dev, hccr, hcor, &vf_ehci_ops, 0, priv->init_type); 3400885cdb9SSanchayan Maity } 3410885cdb9SSanchayan Maity 3420885cdb9SSanchayan Maity static const struct udevice_id vf_usb_ids[] = { 3430885cdb9SSanchayan Maity { .compatible = "fsl,vf610-usb" }, 3440885cdb9SSanchayan Maity { } 3450885cdb9SSanchayan Maity }; 3460885cdb9SSanchayan Maity 3470885cdb9SSanchayan Maity U_BOOT_DRIVER(usb_ehci) = { 3480885cdb9SSanchayan Maity .name = "ehci_vf", 3490885cdb9SSanchayan Maity .id = UCLASS_USB, 3500885cdb9SSanchayan Maity .of_match = vf_usb_ids, 3510885cdb9SSanchayan Maity .bind = vf_usb_bind, 3520885cdb9SSanchayan Maity .probe = ehci_usb_probe, 35399e2df47SMasahiro Yamada .remove = ehci_deregister, 3540885cdb9SSanchayan Maity .ops = &ehci_usb_ops, 3550885cdb9SSanchayan Maity .ofdata_to_platdata = vf_usb_ofdata_to_platdata, 3560885cdb9SSanchayan Maity .platdata_auto_alloc_size = sizeof(struct usb_platdata), 3570885cdb9SSanchayan Maity .priv_auto_alloc_size = sizeof(struct ehci_vf_priv_data), 3580885cdb9SSanchayan Maity .flags = DM_FLAG_ALLOC_PRIV_DMA, 3590885cdb9SSanchayan Maity }; 3600885cdb9SSanchayan Maity #endif 361