Merge git://git.denx.de/u-boot-usb
authorTom Rini <trini@konsulko.com>
Mon, 7 Dec 2015 02:52:40 +0000 (21:52 -0500)
committerTom Rini <trini@konsulko.com>
Mon, 7 Dec 2015 02:52:40 +0000 (21:52 -0500)
14 files changed:
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-omap.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-generic.c [new file with mode: 0644]
drivers/usb/host/ehci-sunxi.c
drivers/usb/host/xhci-dwc3.c
drivers/usb/host/xhci-fsl.c
drivers/usb/host/xhci-omap.c
drivers/usb/host/xhci-zynqmp.c [new file with mode: 0644]
include/configs/xilinx_zynqmp.h
include/configs/xilinx_zynqmp_ep.h
include/fsl_usb.h
include/linux/usb/dwc3.h

index 0ae3de5..85cc96a 100644 (file)
@@ -613,7 +613,7 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
 int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
 {
        struct dwc3             *dwc;
-       struct device           *dev;
+       struct device           *dev = NULL;
        u8                      lpm_nyet_threshold;
        u8                      tx_de_emphasis;
        u8                      hird_threshold;
index ac9a856..3dcc2f4 100644 (file)
@@ -374,7 +374,7 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap, int utmi_mode)
 int dwc3_omap_uboot_init(struct dwc3_omap_device *omap_dev)
 {
        u32                     reg;
-       struct device           *dev;
+       struct device           *dev = NULL;
        struct dwc3_omap        *omap;
 
        omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
index 2a2bffe..0096a2f 100644 (file)
@@ -73,4 +73,12 @@ config USB_EHCI_UNIPHIER
        ---help---
          Enables support for the on-chip EHCI controller on UniPhier SoCs.
 
+config USB_EHCI_GENERIC
+       bool "Support for generic EHCI USB controller"
+       depends on OF_CONTROL
+       depends on DM_USB
+       default n
+       ---help---
+         Enables support for generic EHCI controller.
+
 endif
index f70f38c..0b4b458 100644 (file)
@@ -32,6 +32,7 @@ else
 obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
 obj-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
+obj-$(CONFIG_USB_EHCI_GENERIC) += ehci-generic.o
 obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 obj-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 obj-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
@@ -54,6 +55,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_ZYNQMP) += xhci-zynqmp.o
 obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
new file mode 100644 (file)
index 0000000..1292caa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include "ehci.h"
+
+/*
+ * Even though here we don't explicitly use "struct ehci_ctrl"
+ * ehci_register() expects it to be the first thing that resides in
+ * device's private data.
+ */
+struct generic_ehci {
+       struct ehci_ctrl ctrl;
+};
+
+static int ehci_usb_probe(struct udevice *dev)
+{
+       struct ehci_hccr *hccr = (struct ehci_hccr *)dev_get_addr(dev);
+       struct ehci_hcor *hcor;
+
+       hcor = (struct ehci_hcor *)((uintptr_t)hccr +
+                                   HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+       return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+
+static int ehci_usb_remove(struct udevice *dev)
+{
+       return ehci_deregister(dev);
+}
+
+static const struct udevice_id ehci_usb_ids[] = {
+       { .compatible = "generic-ehci" },
+       { }
+};
+
+U_BOOT_DRIVER(ehci_generic) = {
+       .name   = "ehci_generic",
+       .id     = UCLASS_USB,
+       .of_match = ehci_usb_ids,
+       .probe = ehci_usb_probe,
+       .remove = ehci_usb_remove,
+       .ops    = &ehci_usb_ops,
+       .priv_auto_alloc_size = sizeof(struct generic_ehci),
+       .flags  = DM_FLAG_ALLOC_PRIV_DMA,
+};
index 38d5f92..d494ca1 100644 (file)
@@ -87,7 +87,7 @@ static const struct udevice_id ehci_usb_ids[] = {
        { }
 };
 
-U_BOOT_DRIVER(usb_ehci) = {
+U_BOOT_DRIVER(ehci_sunxi) = {
        .name   = "ehci_sunxi",
        .id     = UCLASS_USB,
        .of_match = ehci_usb_ids,
index c722c50..33961cd 100644 (file)
@@ -44,6 +44,8 @@ void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
        /* reset USB3 phy - if required */
        dwc3_phy_reset(dwc3_reg);
 
+       mdelay(100);
+
        /* After PHYs are stable we can take Core out of reset state */
        clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
 }
index 6481e07..05f09d7 100644 (file)
@@ -27,23 +27,6 @@ __weak int __board_usb_init(int index, enum usb_init_type init)
        return 0;
 }
 
-void usb_phy_reset(struct dwc3 *dwc3_reg)
-{
-       /* Assert USB3 PHY reset */
-       setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
-       /* Assert USB2 PHY reset */
-       setbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
-
-       mdelay(200);
-
-       /* Clear USB3 PHY reset */
-       clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
-       /* Clear USB2 PHY reset */
-       clrbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
-}
-
 static int fsl_xhci_core_init(struct fsl_xhci *fsl_xhci)
 {
        int ret = 0;
index 104e7a7..fd19f79 100644 (file)
@@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static struct omap_xhci omap;
 
-inline int __board_usb_init(int index, enum usb_init_type init)
+__weak int __board_usb_init(int index, enum usb_init_type init)
 {
        return 0;
 }
diff --git a/drivers/usb/host/xhci-zynqmp.c b/drivers/usb/host/xhci-zynqmp.c
new file mode 100644 (file)
index 0000000..a735369
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 Xilinx, Inc.
+ *
+ * Zynq USB HOST xHCI Controller
+ *
+ * Author: Siva Durga Prasad Paladugu<sivadur@xilinx.com>
+ *
+ * This file was reused from Freescale USB xHCI
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <usb.h>
+#include <asm-generic/errno.h>
+#include <asm/arch-zynqmp/hardware.h>
+#include <linux/compat.h>
+#include <linux/usb/dwc3.h>
+#include "xhci.h"
+
+/* Declare global data pointer */
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Default to the ZYNQMP XHCI defines */
+#define USB3_PWRCTL_CLK_CMD_MASK       0x3FE000
+#define USB3_PWRCTL_CLK_FREQ_MASK      0xFFC
+#define USB3_PHY_PARTIAL_RX_POWERON     BIT(6)
+#define USB3_PHY_RX_POWERON            BIT(14)
+#define USB3_PHY_TX_POWERON            BIT(15)
+#define USB3_PHY_TX_RX_POWERON (USB3_PHY_RX_POWERON | USB3_PHY_TX_POWERON)
+#define USB3_PWRCTL_CLK_CMD_SHIFT   14
+#define USB3_PWRCTL_CLK_FREQ_SHIFT     22
+
+/* USBOTGSS_WRAPPER definitions */
+#define USBOTGSS_WRAPRESET     BIT(17)
+#define USBOTGSS_DMADISABLE BIT(16)
+#define USBOTGSS_STANDBYMODE_NO_STANDBY BIT(4)
+#define USBOTGSS_STANDBYMODE_SMRT              BIT(5)
+#define USBOTGSS_STANDBYMODE_SMRT_WKUP (0x3 << 4)
+#define USBOTGSS_IDLEMODE_NOIDLE BIT(2)
+#define USBOTGSS_IDLEMODE_SMRT BIT(3)
+#define USBOTGSS_IDLEMODE_SMRT_WKUP (0x3 << 2)
+
+/* USBOTGSS_IRQENABLE_SET_0 bit */
+#define USBOTGSS_COREIRQ_EN    BIT(1)
+
+/* USBOTGSS_IRQENABLE_SET_1 bits */
+#define USBOTGSS_IRQ_SET_1_IDPULLUP_FALL_EN    BIT(1)
+#define USBOTGSS_IRQ_SET_1_DISCHRGVBUS_FALL_EN BIT(3)
+#define USBOTGSS_IRQ_SET_1_CHRGVBUS_FALL_EN    BIT(4)
+#define USBOTGSS_IRQ_SET_1_DRVVBUS_FALL_EN     BIT(5)
+#define USBOTGSS_IRQ_SET_1_IDPULLUP_RISE_EN    BIT(8)
+#define USBOTGSS_IRQ_SET_1_DISCHRGVBUS_RISE_EN BIT(11)
+#define USBOTGSS_IRQ_SET_1_CHRGVBUS_RISE_EN    BIT(12)
+#define USBOTGSS_IRQ_SET_1_DRVVBUS_RISE_EN     BIT(13)
+#define USBOTGSS_IRQ_SET_1_OEVT_EN             BIT(16)
+#define USBOTGSS_IRQ_SET_1_DMADISABLECLR_EN    BIT(17)
+
+struct zynqmp_xhci {
+       struct xhci_hccr *hcd;
+       struct dwc3 *dwc3_reg;
+};
+
+static struct zynqmp_xhci zynqmp_xhci;
+
+unsigned long ctr_addr[] = CONFIG_ZYNQMP_XHCI_LIST;
+
+static int zynqmp_xhci_core_init(struct zynqmp_xhci *zynqmp_xhci)
+{
+       int ret = 0;
+
+       ret = dwc3_core_init(zynqmp_xhci->dwc3_reg);
+       if (ret) {
+               debug("%s:failed to initialize core\n", __func__);
+               return ret;
+       }
+
+       /* We are hard-coding DWC3 core to Host Mode */
+       dwc3_set_mode(zynqmp_xhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
+
+       return ret;
+}
+
+int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
+{
+       struct zynqmp_xhci *ctx = &zynqmp_xhci;
+       int ret = 0;
+       uint32_t hclen;
+
+       if (index < 0 || index >= ARRAY_SIZE(ctr_addr))
+               return -EINVAL;
+
+       ctx->hcd = (struct xhci_hccr *)ctr_addr[index];
+       ctx->dwc3_reg = (struct dwc3 *)((void *)ctx->hcd + DWC3_REG_OFFSET);
+
+       ret = board_usb_init(index, USB_INIT_HOST);
+       if (ret != 0) {
+               puts("Failed to initialize board for USB\n");
+               return ret;
+       }
+
+       ret = zynqmp_xhci_core_init(ctx);
+       if (ret < 0) {
+               puts("Failed to initialize xhci\n");
+               return ret;
+       }
+
+       *hccr = (struct xhci_hccr *)ctx->hcd;
+       hclen = HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase));
+       *hcor = (struct xhci_hcor *)((uintptr_t) *hccr + hclen);
+
+       debug("zynqmp-xhci: init hccr %p and hcor %p hc_length %d\n",
+             *hccr, *hcor, hclen);
+
+       return ret;
+}
+
+void xhci_hcd_stop(int index)
+{
+       /*
+        * Currently zynqmp socs do not support PHY shutdown from
+        * sw. But this support may be added in future socs.
+        */
+
+       return;
+}
index 6b8b9f8..474bbaf 100644 (file)
 #define CONFIG_SYS_LOAD_ADDR           0x8000000
 
 #if defined(CONFIG_ZYNQMP_USB)
+#define CONFIG_USB_XHCI_DWC3
+#define CONFIG_USB_XHCI
+#define CONFIG_USB_MAX_CONTROLLER_COUNT         1
+#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
+#define CONFIG_CMD_USB
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_XHCI_ZYNQMP
+
 #define CONFIG_USB_DWC3
 #define CONFIG_USB_DWC3_GADGET
 
index 8bdb5c9..b7d506e 100644 (file)
@@ -24,6 +24,8 @@
 #define CONFIG_SYS_I2C_ZYNQ
 #define CONFIG_ZYNQ_EEPROM
 #define CONFIG_AHCI
+#define CONFIG_ZYNQMP_XHCI_LIST {ZYNQMP_USB0_XHCI_BASEADDR, \
+                                ZYNQMP_USB1_XHCI_BASEADDR}
 
 #include <configs/xilinx_zynqmp.h>
 
index 8e3dded..187e384 100644 (file)
@@ -181,6 +181,7 @@ static inline bool has_erratum_a007792(void)
        switch (soc) {
        case SVR_T4240:
        case SVR_T4160:
+       case SVR_T4080:
                return IS_SVR_REV(svr, 2, 0);
        case SVR_T1024:
        case SVR_T1023:
index dd934a0..6d1e365 100644 (file)
@@ -204,7 +204,6 @@ struct dwc3 {                                       /* offset: 0xC100 */
 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);
 void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val);
 #endif
 #endif /* __DWC3_H_ */