diff options
Diffstat (limited to 'drivers/usb/host/xhci-dwc3.c')
-rw-r--r-- | drivers/usb/host/xhci-dwc3.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 3e0ae80cec..bec0d98081 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -7,10 +7,12 @@ * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com> */ +#include <clk.h> #include <common.h> #include <dm.h> #include <generic-phy.h> #include <log.h> +#include <reset.h> #include <usb.h> #include <dwc3-uboot.h> #include <linux/delay.h> @@ -21,7 +23,9 @@ #include <linux/usb/otg.h> struct xhci_dwc3_plat { + struct clk_bulk clks; struct phy_bulk phys; + struct reset_ctl_bulk resets; }; void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode) @@ -70,7 +74,8 @@ int dwc3_core_init(struct dwc3 *dwc3_reg) revision = readl(&dwc3_reg->g_snpsid); /* This should read as U3 followed by revision number */ - if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) { + if ((revision & DWC3_GSNPSID_MASK) != 0x55330000 && + (revision & DWC3_GSNPSID_MASK) != 0x33310000) { puts("this is not a DesignWare USB3 DRD Core\n"); return -1; } @@ -111,6 +116,46 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) } #if CONFIG_IS_ENABLED(DM_USB) +static int xhci_dwc3_reset_init(struct udevice *dev, + struct xhci_dwc3_plat *plat) +{ + int ret; + + ret = reset_get_bulk(dev, &plat->resets); + if (ret == -ENOTSUPP || ret == -ENOENT) + return 0; + else if (ret) + return ret; + + ret = reset_deassert_bulk(&plat->resets); + if (ret) { + reset_release_bulk(&plat->resets); + return ret; + } + + return 0; +} + +static int xhci_dwc3_clk_init(struct udevice *dev, + struct xhci_dwc3_plat *plat) +{ + int ret; + + ret = clk_get_bulk(dev, &plat->clks); + if (ret == -ENOSYS || ret == -ENOENT) + return 0; + if (ret) + return ret; + + ret = clk_enable_bulk(&plat->clks); + if (ret) { + clk_release_bulk(&plat->clks); + return ret; + } + + return 0; +} + static int xhci_dwc3_probe(struct udevice *dev) { struct xhci_hcor *hcor; @@ -122,6 +167,14 @@ static int xhci_dwc3_probe(struct udevice *dev) u32 reg; int ret; + ret = xhci_dwc3_reset_init(dev, plat); + if (ret) + return ret; + + ret = xhci_dwc3_clk_init(dev, plat); + if (ret) + return ret; + hccr = (struct xhci_hccr *)((uintptr_t)dev_remap_addr(dev)); hcor = (struct xhci_hcor *)((uintptr_t)hccr + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); @@ -171,6 +224,10 @@ static int xhci_dwc3_remove(struct udevice *dev) dwc3_shutdown_phy(dev, &plat->phys); + clk_release_bulk(&plat->clks); + + reset_release_bulk(&plat->resets); + return xhci_deregister(dev); } |