From 22988766da6fe200b6947b8181ddbde663643248 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 4 Apr 2019 12:26:52 +0200 Subject: USB: DM: Convert i.MX5 ehci code to driver model This commit converts i.MX5's EHCI USB host driver to driver model (DM_USB). It is a straightforward conversion (to reuse as much code as possible), based on ehci-mx6.c code. Signed-off-by: Lukasz Majewski --- drivers/usb/host/ehci-mx5.c | 103 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c index 60f1470860..0b32728c57 100644 --- a/drivers/usb/host/ehci-mx5.c +++ b/drivers/usb/host/ehci-mx5.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "ehci.h" @@ -223,6 +225,7 @@ __weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg, mdelay(50); } +#if !CONFIG_IS_ENABLED(DM_USB) static const struct ehci_ops mx5_ehci_ops = { .powerup_fixup = mx5_ehci_powerup_fixup, }; @@ -267,3 +270,103 @@ int ehci_hcd_stop(int index) { return 0; } +#else /* CONFIG_IS_ENABLED(DM_USB) */ +struct ehci_mx5_priv_data { + struct ehci_ctrl ctrl; + struct usb_ehci *ehci; + struct udevice *vbus_supply; + enum usb_init_type init_type; + int portnr; +}; + +static const struct ehci_ops mx5_ehci_ops = { + .powerup_fixup = mx5_ehci_powerup_fixup, +}; + +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + const char *mode; + + mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "dr_mode", NULL); + if (mode) { + if (strcmp(mode, "peripheral") == 0) + plat->init_type = USB_INIT_DEVICE; + else if (strcmp(mode, "host") == 0) + plat->init_type = USB_INIT_HOST; + else + return -EINVAL; + } + + return 0; +} + +static int ehci_usb_probe(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + struct usb_ehci *ehci = (struct usb_ehci *)devfdt_get_addr(dev); + struct ehci_mx5_priv_data *priv = dev_get_priv(dev); + enum usb_init_type type = plat->init_type; + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; + int ret; + + set_usboh3_clk(); + enable_usboh3_clk(true); + set_usb_phy_clk(); + enable_usb_phy1_clk(true); + enable_usb_phy2_clk(true); + mdelay(1); + + priv->ehci = ehci; + priv->portnr = dev->seq; + priv->init_type = type; + + ret = device_get_supply_regulator(dev, "vbus-supply", + &priv->vbus_supply); + if (ret) + debug("%s: No vbus supply\n", dev->name); + + if (!ret && priv->vbus_supply) { + ret = regulator_set_enable(priv->vbus_supply, + (type == USB_INIT_DEVICE) ? + false : true); + if (ret) { + puts("Error enabling VBUS supply\n"); + return ret; + } + } + + hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); + hcor = (struct ehci_hcor *)((uint32_t)hccr + + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase))); + setbits_le32(&ehci->usbmode, CM_HOST); + + __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc); + setbits_le32(&ehci->portsc, USB_EN); + + mxc_set_usbcontrol(priv->portnr, CONFIG_MXC_USB_FLAGS); + mdelay(10); + + return ehci_register(dev, hccr, hcor, &mx5_ehci_ops, 0, + priv->init_type); +} + +static const struct udevice_id mx5_usb_ids[] = { + { .compatible = "fsl,imx53-usb" }, + { } +}; + +U_BOOT_DRIVER(usb_mx5) = { + .name = "ehci_mx5", + .id = UCLASS_USB, + .of_match = mx5_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, + .probe = ehci_usb_probe, + .remove = ehci_deregister, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct ehci_mx5_priv_data), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif /* !CONFIG_IS_ENABLED(DM_USB) */ -- cgit v1.2.3