X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fehci-mx5.c;h=c11279867c7ca0d2412d9cea5105763419729df3;hb=dd11fdc31fb82f63258c1970a6d8d22b8ffd3173;hp=dd11f535adc5937c3fdd6ea2da52cbf53dd24455;hpb=19d829fa60fc4e6df514a046142faaaf9fc8185d;p=platform%2Fkernel%2Fu-boot.git diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c index dd11f53..c112798 100644 --- a/drivers/usb/host/ehci-mx5.c +++ b/drivers/usb/host/ehci-mx5.c @@ -1,18 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2009 Daniel Mack * Copyright (C) 2010 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include #include -#include +#include +#include +#include #include #include #include +#include +#include #include "ehci.h" @@ -218,9 +222,51 @@ void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port) { } -int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) +__weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg, + uint32_t *reg) { + mdelay(50); +} + +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_of_to_plat(struct udevice *dev) +{ + struct usb_plat *plat = dev_get_plat(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_plat *plat = dev_get_plat(dev); + struct usb_ehci *ehci = dev_read_addr_ptr(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); @@ -229,29 +275,54 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) enable_usb_phy2_clk(true); mdelay(1); - /* Do board specific initialization */ - board_ehci_hcd_init(CONFIG_MXC_USB_PORT); + priv->ehci = ehci; + priv->portnr = dev_seq(dev); + 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; + } + } - ehci = (struct usb_ehci *)(OTG_BASE_ADDR + - (0x200 * CONFIG_MXC_USB_PORT)); - *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); - *hcor = (struct ehci_hcor *)((uint32_t)*hccr + - HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + 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); + __raw_writel(CFG_MXC_USB_PORTSC, &ehci->portsc); setbits_le32(&ehci->portsc, USB_EN); - mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS); + mxc_set_usbcontrol(priv->portnr, CFG_MXC_USB_FLAGS); mdelay(10); - /* Do board specific post-initialization */ - board_ehci_hcd_postinit(ehci, CONFIG_MXC_USB_PORT); - - return 0; + return ehci_register(dev, hccr, hcor, &mx5_ehci_ops, 0, + priv->init_type); } -int ehci_hcd_stop(int index) -{ - return 0; -} +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, + .of_to_plat = ehci_usb_of_to_plat, + .probe = ehci_usb_probe, + .remove = ehci_deregister, + .ops = &ehci_usb_ops, + .plat_auto = sizeof(struct usb_plat), + .priv_auto = sizeof(struct ehci_mx5_priv_data), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +};