diff options
author | Tom Rini <trini@konsulko.com> | 2015-12-06 21:52:40 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-12-06 21:52:40 -0500 |
commit | 2311335d4c5ad6496b3447746a88ecb371e4c71c (patch) | |
tree | a990344632d5abb4f184599bfff9f044fb49e5cc | |
parent | 540fcbca7e960b2855e7666fff8f11a7119341ee (diff) | |
parent | 6af4e2782d1300015ab1c3c28e9faa5c96d93f19 (diff) | |
download | u-boot-imx-2311335d4c5ad6496b3447746a88ecb371e4c71c.zip u-boot-imx-2311335d4c5ad6496b3447746a88ecb371e4c71c.tar.gz u-boot-imx-2311335d4c5ad6496b3447746a88ecb371e4c71c.tar.bz2 |
Merge git://git.denx.de/u-boot-usb
-rw-r--r-- | drivers/usb/dwc3/core.c | 2 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-omap.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 8 | ||||
-rw-r--r-- | drivers/usb/host/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-generic.c | 50 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sunxi.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-dwc3.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-fsl.c | 17 | ||||
-rw-r--r-- | drivers/usb/host/xhci-omap.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-zynqmp.c | 126 | ||||
-rw-r--r-- | include/configs/xilinx_zynqmp.h | 8 | ||||
-rw-r--r-- | include/configs/xilinx_zynqmp_ep.h | 2 | ||||
-rw-r--r-- | include/fsl_usb.h | 1 | ||||
-rw-r--r-- | include/linux/usb/dwc3.h | 1 |
14 files changed, 203 insertions, 22 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 0ae3de5..85cc96a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -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; diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index ac9a856..3dcc2f4 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -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); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2a2bffe..0096a2f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -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 diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index f70f38c..0b4b458 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -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 index 0000000..1292caa --- /dev/null +++ b/drivers/usb/host/ehci-generic.c @@ -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, +}; diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index 38d5f92..d494ca1 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -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, diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index c722c50..33961cd 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -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); } diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c index 6481e07..05f09d7 100644 --- a/drivers/usb/host/xhci-fsl.c +++ b/drivers/usb/host/xhci-fsl.c @@ -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; diff --git a/drivers/usb/host/xhci-omap.c b/drivers/usb/host/xhci-omap.c index 104e7a7..fd19f79 100644 --- a/drivers/usb/host/xhci-omap.c +++ b/drivers/usb/host/xhci-omap.c @@ -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 index 0000000..a735369 --- /dev/null +++ b/drivers/usb/host/xhci-zynqmp.c @@ -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; +} diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index 6b8b9f8..474bbaf 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -107,6 +107,14 @@ #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 diff --git a/include/configs/xilinx_zynqmp_ep.h b/include/configs/xilinx_zynqmp_ep.h index 8bdb5c9..b7d506e 100644 --- a/include/configs/xilinx_zynqmp_ep.h +++ b/include/configs/xilinx_zynqmp_ep.h @@ -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> diff --git a/include/fsl_usb.h b/include/fsl_usb.h index 8e3dded..187e384 100644 --- a/include/fsl_usb.h +++ b/include/fsl_usb.h @@ -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: diff --git a/include/linux/usb/dwc3.h b/include/linux/usb/dwc3.h index dd934a0..6d1e365 100644 --- a/include/linux/usb/dwc3.h +++ b/include/linux/usb/dwc3.h @@ -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_ */ |