Add support for DWC3 XHCI controller driver

Signed-off-by: Ramneek Mehresh <ramneek.mehr...@freescale.com>
---
 drivers/usb/host/Makefile    |  1 +
 drivers/usb/host/xhci-dwc3.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb/dwc3.h     |  4 +++
 3 files changed, 80 insertions(+)
 create mode 100644 drivers/usb/host/xhci-dwc3.c

diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 7658f87..c0d95cf 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
 
 # xhci
 obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
+obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
 obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
new file mode 100644
index 0000000..c875851
--- /dev/null
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * DWC3 controller driver
+ *
+ * Author: Ramneek Mehresh<ramneek.mehr...@freescale.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/usb/dwc3.h>
+
+void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
+{
+       clrsetbits_le32(&dwc3_reg->g_ctl,
+                       DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
+                       DWC3_GCTL_PRTCAPDIR(mode));
+}
+
+void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
+{
+       /* Before Resetting PHY, put Core in Reset */
+       setbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
+
+       /* reset USB3 phy - if required */
+       usb_phy_reset(dwc3_reg);
+
+       /* After PHYs are stable we can take Core out of reset state */
+       clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
+}
+
+int dwc3_core_init(struct dwc3 *dwc3_reg)
+{
+       u32 reg;
+       u32 revision;
+       unsigned int dwc3_hwparams1;
+
+       revision = readl(&dwc3_reg->g_snpsid);
+       /* This should read as U3 followed by revision number */
+       if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
+               puts("this is not a DesignWare USB3 DRD Core\n");
+               return -1;
+       }
+
+       dwc3_core_soft_reset(dwc3_reg);
+
+       dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
+
+       reg = readl(&dwc3_reg->g_ctl);
+       reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
+       reg &= ~DWC3_GCTL_DISSCRAMBLE;
+       switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
+       case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
+               reg &= ~DWC3_GCTL_DSBLCLKGTNG;
+               break;
+       default:
+               debug("No power optimization available\n");
+       }
+
+       /*
+        * WORKAROUND: DWC3 revisions <1.90a have a bug
+        * where the device can fail to connect at SuperSpeed
+        * and falls back to high-speed mode which causes
+        * the device to enter a Connect/Disconnect loop
+        */
+       if ((revision & DWC3_REVISION_MASK) < 0x190a)
+               reg |= DWC3_GCTL_U2RSTECN;
+
+       writel(reg, &dwc3_reg->g_ctl);
+
+       return 0;
+}
+
diff --git a/include/linux/usb/dwc3.h b/include/linux/usb/dwc3.h
index 7edc760..c21878c 100644
--- a/include/linux/usb/dwc3.h
+++ b/include/linux/usb/dwc3.h
@@ -191,4 +191,8 @@ struct dwc3 {                                       /* 
offset: 0xC100 */
 #define DWC3_DCTL_CSFTRST                      (1 << 30)
 #define DWC3_DCTL_LSFTRST                      (1 << 29)
 
+void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode);
+void dwc3_core_soft_reset(struct dwc3 *dwc3_reg);
+int dwc3_core_init(struct dwc3 *dwc3_reg);
+void usb_phy_reset(struct dwc3 *dwc3_reg);
 #endif /* __DWC3_H_ */
-- 
1.8.3.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to