[U-Boot] [PATCH v3 00/18] Fixes for the DWC3 USB generic driver

The original title was "Improvement for the DWC3 USB generic driver and fixes for the K2 platforms" but has been changed because using UCLASS_MISC actually breaks the driver
The K2 platforms have shown boot issues after switching to the DWC3 generic driver. Those are due to the fact that the USB domains are not turned off before booting linux and the phy were not properly initialized. Fixing it by improving the DWC3-generic driver and handling the USB power domain in the PHY driver. At the same time this series introduce a new uclass (UCLASS_NOP) to replace usage of UCLASS_MISC in the USB wrapper because the MISC class now automatically binds all the child devices and that breaks the DWC3-generic driver.
Improvements to the DWC3 generic driver are: - Fix it by switching to UCLASS_NOP - core: read quirks properties from DT and apply the fixes. - add a new host driver that uses the DWC3 core (more generic than xhci-dwc3). This should enable most platforms to drop their own version of the xhci-driver to use the generic one instead.
This series also removes the now unused xhci-zynqmp driver and tries to better manage the Kconfig options related to DWC3 gadget/host mode selection.
This has been tested with K2 and DRA7 platforms (host and device modes). Travis build: https://travis-ci.org/jjhiblot/u-boot/builds/515282720
v2 of this series has been tested by Siva Durga Prasad Paladugu sivadur@xilinx.com
Changes in v3: - updated log message when defaulting to super speed
Changes in v2: Add a test for the NOP uclass Update commit log Select USB_GADGET_DUALSPEED if USB_DWC3_GADGET is selected
Jean-Jacques Hiblot (18): usb: dwc3-generic: remove dm_scan_fdt_dev() from the remove() callback usb: host: remove the xhci-zynqmp driver dm: Add a No-op uclass usb: dwc3: Use UCLASS_NOP instead of UCLASS_MISC for the DWC3 generic glue usb: dwc3: switch to peripheral mode when exiting usb: xhci: move xhci.h to include usb usb: dwc3: always use the inlined version of dwc3_host_init/dwc3_host_exit usb: dwc3-generic: use platdata usb: dwc3-generic: factorize code usb: dwc3-generic: add a new host driver that uses the dwc3 core usb: dwc3-generic: if no max speed is specified in DT, assume super speed usb: dwc3: Add dwc3_of_parse() to get quirks information from DT usb: dwc3: Kconfig: get rid of obsolete mode selection ARM: keystone: increase PSC timeout ARM: keystone: Do not enable the USB power domains at the board level phy: keystone-usb: handle the transition of the USB power domain configs: k2g_evm_defconfig: disable XHCI_DWC3 and enable KEYSTONE_USB_PHY ARM: DTS: keystone: complete the description of the USB PHY devices
MAINTAINERS | 1 + arch/arm/dts/keystone-k2e-evm-u-boot.dtsi | 32 ++++ arch/arm/dts/keystone-k2g-evm-u-boot.dtsi | 28 ++++ arch/arm/dts/keystone-k2hk-evm-u-boot.dtsi | 14 ++ arch/arm/dts/keystone-k2l-evm-u-boot.dtsi | 18 +++ .../arm/mach-keystone/include/mach/psc_defs.h | 2 +- arch/sandbox/dts/test.dts | 12 ++ board/ti/ks2_evm/board.c | 13 -- configs/avnet_ultra96_rev1_defconfig | 1 - configs/evb-rk3328_defconfig | 1 + configs/k2g_evm_defconfig | 3 +- .../xilinx_zynqmp_zc1751_xm015_dc1_defconfig | 1 - .../xilinx_zynqmp_zc1751_xm016_dc2_defconfig | 1 - .../xilinx_zynqmp_zc1751_xm017_dc3_defconfig | 1 - configs/xilinx_zynqmp_zcu100_revC_defconfig | 1 - configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 1 - configs/xilinx_zynqmp_zcu102_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu102_revB_defconfig | 1 - configs/xilinx_zynqmp_zcu104_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu104_revC_defconfig | 1 - configs/xilinx_zynqmp_zcu106_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu111_revA_defconfig | 1 - drivers/core/uclass.c | 5 + drivers/phy/keystone-usb-phy.c | 22 +++ drivers/usb/dwc3/Kconfig | 18 +-- drivers/usb/dwc3/core.c | 84 +++++++++- drivers/usb/dwc3/core.h | 6 +- drivers/usb/dwc3/dwc3-generic.c | 150 ++++++++++++++---- drivers/usb/host/Kconfig | 7 - drivers/usb/host/Makefile | 1 - drivers/usb/host/xhci-dwc3.c | 2 +- drivers/usb/host/xhci-exynos5.c | 2 +- drivers/usb/host/xhci-fsl.c | 2 +- drivers/usb/host/xhci-mem.c | 2 +- drivers/usb/host/xhci-mvebu.c | 2 +- drivers/usb/host/xhci-omap.c | 2 +- drivers/usb/host/xhci-pci.c | 2 +- drivers/usb/host/xhci-rcar.c | 2 +- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci-rockchip.c | 2 +- drivers/usb/host/xhci-zynqmp.c | 146 ----------------- drivers/usb/host/xhci.c | 2 +- drivers/usb/phy/omap_usb_phy.c | 2 +- include/dm/uclass-id.h | 1 + {drivers/usb/host => include/usb}/xhci.h | 0 test/dm/Makefile | 1 + test/dm/nop.c | 73 +++++++++ 47 files changed, 421 insertions(+), 253 deletions(-) create mode 100644 arch/arm/dts/keystone-k2l-evm-u-boot.dtsi delete mode 100644 drivers/usb/host/xhci-zynqmp.c rename {drivers/usb/host => include/usb}/xhci.h (100%) create mode 100644 test/dm/nop.c

There is simply no reason to do that here.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 3e6c494dc6..70431facb3 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -337,7 +337,7 @@ static int dwc3_glue_remove(struct udevice *dev)
clk_release_bulk(&glue->clks);
- return dm_scan_fdt_dev(dev); + return 0; }
static const struct udevice_id dwc3_glue_ids[] = {

This driver is not used anymore.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
configs/avnet_ultra96_rev1_defconfig | 1 - .../xilinx_zynqmp_zc1751_xm015_dc1_defconfig | 1 - .../xilinx_zynqmp_zc1751_xm016_dc2_defconfig | 1 - .../xilinx_zynqmp_zc1751_xm017_dc3_defconfig | 1 - configs/xilinx_zynqmp_zcu100_revC_defconfig | 1 - configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 1 - configs/xilinx_zynqmp_zcu102_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu102_revB_defconfig | 1 - configs/xilinx_zynqmp_zcu104_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu104_revC_defconfig | 1 - configs/xilinx_zynqmp_zcu106_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu111_revA_defconfig | 1 - drivers/usb/host/Kconfig | 7 - drivers/usb/host/Makefile | 1 - drivers/usb/host/xhci-zynqmp.c | 146 ------------------ 15 files changed, 166 deletions(-) delete mode 100644 drivers/usb/host/xhci-zynqmp.c
diff --git a/configs/avnet_ultra96_rev1_defconfig b/configs/avnet_ultra96_rev1_defconfig index b504332ff0..fcfebe9c78 100644 --- a/configs/avnet_ultra96_rev1_defconfig +++ b/configs/avnet_ultra96_rev1_defconfig @@ -75,7 +75,6 @@ CONFIG_ZYNQ_SPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig index 7b1f5e9d0a..8d906fa364 100644 --- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig @@ -86,7 +86,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig index ae2554a8eb..198b92a18d 100644 --- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig @@ -77,7 +77,6 @@ CONFIG_SPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig b/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig index 559a61e8d0..0d93f3ceb1 100644 --- a/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig @@ -74,7 +74,6 @@ CONFIG_SPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu100_revC_defconfig b/configs/xilinx_zynqmp_zcu100_revC_defconfig index 4b3f72da74..3b0f81adf9 100644 --- a/configs/xilinx_zynqmp_zcu100_revC_defconfig +++ b/configs/xilinx_zynqmp_zcu100_revC_defconfig @@ -74,7 +74,6 @@ CONFIG_ZYNQ_SPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig index ef291a7d38..7f10554594 100644 --- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig +++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig @@ -101,7 +101,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig index 975e9f5eb1..49f46dca09 100644 --- a/configs/xilinx_zynqmp_zcu102_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig @@ -100,7 +100,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig index 34918aa171..46ac6a3add 100644 --- a/configs/xilinx_zynqmp_zcu102_revB_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig @@ -100,7 +100,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu104_revA_defconfig b/configs/xilinx_zynqmp_zcu104_revA_defconfig index e4090dc281..1672a684ac 100644 --- a/configs/xilinx_zynqmp_zcu104_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu104_revA_defconfig @@ -85,7 +85,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu104_revC_defconfig b/configs/xilinx_zynqmp_zcu104_revC_defconfig index 25a2515d15..ba887d60ba 100644 --- a/configs/xilinx_zynqmp_zcu104_revC_defconfig +++ b/configs/xilinx_zynqmp_zcu104_revC_defconfig @@ -86,7 +86,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu106_revA_defconfig b/configs/xilinx_zynqmp_zcu106_revA_defconfig index 212de924a6..f1aceb6608 100644 --- a/configs/xilinx_zynqmp_zcu106_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu106_revA_defconfig @@ -95,7 +95,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/configs/xilinx_zynqmp_zcu111_revA_defconfig b/configs/xilinx_zynqmp_zcu111_revA_defconfig index dec894787e..1eee43af25 100644 --- a/configs/xilinx_zynqmp_zcu111_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu111_revA_defconfig @@ -87,7 +87,6 @@ CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y -CONFIG_USB_XHCI_ZYNQMP=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index b1188bcbf5..8d96f8f8af 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -72,13 +72,6 @@ config USB_XHCI_STI STiH407 family SoCs. This is a driver for the dwc3 to provide the glue logic to configure the controller.
-config USB_XHCI_ZYNQMP - bool "Support for Xilinx ZynqMP on-chip xHCI USB controller" - depends on ARCH_ZYNQMP - depends on DM_USB - help - Enables support for the on-chip xHCI controller on Xilinx ZynqMP SoCs. - config USB_XHCI_DRA7XX_INDEX int "DRA7XX xHCI USB index" range 0 1 diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 6aa574f6f7..2b99a48c56 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o -obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o diff --git a/drivers/usb/host/xhci-zynqmp.c b/drivers/usb/host/xhci-zynqmp.c deleted file mode 100644 index e44e1ae1d9..0000000000 --- a/drivers/usb/host/xhci-zynqmp.c +++ /dev/null @@ -1,146 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2015 Xilinx, Inc. - * - * Zynq USB HOST xHCI Controller - * - * Author: Siva Durga Prasad Paladugusivadur@xilinx.com - * - * This file was reused from Freescale USB xHCI - */ - -#include <common.h> -#include <dm.h> -#include <usb.h> -#include <linux/errno.h> -#include <asm/arch/hardware.h> -#include <linux/compat.h> -#include <linux/usb/dwc3.h> -#include "xhci.h" - -/* Declare global data pointer */ -/* 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 usb_platdata usb_plat; - struct xhci_ctrl ctrl; - struct xhci_hccr *hcd; - struct dwc3 *dwc3_reg; -}; - -struct zynqmp_xhci_platdata { - fdt_addr_t hcd_base; -}; - -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; -} - -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; -} - -static int xhci_usb_probe(struct udevice *dev) -{ - struct zynqmp_xhci_platdata *plat = dev_get_platdata(dev); - struct zynqmp_xhci *ctx = dev_get_priv(dev); - struct xhci_hcor *hcor; - int ret; - - ctx->hcd = (struct xhci_hccr *)plat->hcd_base; - ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET); - - ret = zynqmp_xhci_core_init(ctx); - if (ret) { - puts("XHCI: failed to initialize controller\n"); - return -EINVAL; - } - - hcor = (struct xhci_hcor *)((ulong)ctx->hcd + - HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase))); - - return xhci_register(dev, ctx->hcd, hcor); -} - -static int xhci_usb_remove(struct udevice *dev) -{ - return xhci_deregister(dev); -} - -static int xhci_usb_ofdata_to_platdata(struct udevice *dev) -{ - struct zynqmp_xhci_platdata *plat = dev_get_platdata(dev); - const void *blob = gd->fdt_blob; - - /* Get the base address for XHCI controller from the device node */ - plat->hcd_base = fdtdec_get_addr(blob, dev_of_offset(dev), "reg"); - if (plat->hcd_base == FDT_ADDR_T_NONE) { - debug("Can't get the XHCI register base address\n"); - return -ENXIO; - } - - return 0; -} - -U_BOOT_DRIVER(dwc3_generic_host) = { - .name = "dwc3-generic-host", - .id = UCLASS_USB, - .ofdata_to_platdata = xhci_usb_ofdata_to_platdata, - .probe = xhci_usb_probe, - .remove = xhci_usb_remove, - .ops = &xhci_usb_ops, - .platdata_auto_alloc_size = sizeof(struct zynqmp_xhci_platdata), - .priv_auto_alloc_size = sizeof(struct zynqmp_xhci), - .flags = DM_FLAG_ALLOC_PRIV_DMA, -};

This uclass is intended for devices that do not need any features from the uclass, including binding children. This will typically be used by devices that are used to bind child devices but do not use dm_scan_fdt_dev() to do it. That is for example the case of several USB wrappers that have 2 child devices (1 for device and 1 for host) but bind only one at a any given time.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Simon Glass sjg@chromium.org
---
Changes in v3: None Changes in v2: Add a test for the NOP uclass
arch/sandbox/dts/test.dts | 12 +++++++ drivers/core/uclass.c | 5 +++ include/dm/uclass-id.h | 1 + test/dm/Makefile | 1 + test/dm/nop.c | 73 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 test/dm/nop.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 8b2d6451c6..c328258901 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -400,6 +400,18 @@ sandbox,silent; /* Don't emit sounds while testing */ };
+ nop-test_0 { + compatible = "sandbox,nop_sandbox1"; + nop-test_1 { + compatible = "sandbox,nop_sandbox2"; + bind = "True"; + }; + nop-test_2 { + compatible = "sandbox,nop_sandbox2"; + bind = "False"; + }; + }; + misc-test { compatible = "sandbox,misc_sandbox"; }; diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index fc3157de39..dc9eb62893 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -757,3 +757,8 @@ int uclass_pre_remove_device(struct udevice *dev) return 0; } #endif + +UCLASS_DRIVER(nop) = { + .id = UCLASS_NOP, + .name = "nop", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 09e0ad5391..418392875c 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -62,6 +62,7 @@ enum uclass_id { UCLASS_MMC, /* SD / MMC card or chip */ UCLASS_MOD_EXP, /* RSA Mod Exp device */ UCLASS_MTD, /* Memory Technology Device (MTD) device */ + UCLASS_NOP, /* No-op devices */ UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */ UCLASS_NVME, /* NVM Express device */ UCLASS_PANEL, /* Display panel, such as an LCD */ diff --git a/test/dm/Makefile b/test/dm/Makefile index 49857c5092..aeb3aa0ca7 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -3,6 +3,7 @@ # Copyright (c) 2013 Google, Inc
obj-$(CONFIG_UT_DM) += bus.o +obj-$(CONFIG_UT_DM) += nop.o obj-$(CONFIG_UT_DM) += test-driver.o obj-$(CONFIG_UT_DM) += test-fdt.o obj-$(CONFIG_UT_DM) += test-main.o diff --git a/test/dm/nop.c b/test/dm/nop.c new file mode 100644 index 0000000000..2df29f3d15 --- /dev/null +++ b/test/dm/nop.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for the NOP uclass + * + * (C) Copyright 2019 - Texas Instruments Incorporated - http://www.ti.com/ + * Jean-Jacques Hiblot jjhiblot@ti.com + */ + +#include <common.h> +#include <dm.h> +#include <dm/ofnode.h> +#include <dm/lists.h> +#include <dm/device.h> +#include <dm/test.h> +#include <misc.h> +#include <test/ut.h> + +static int noptest_bind(struct udevice *parent) +{ + ofnode ofnode = dev_read_first_subnode(parent); + + while (ofnode_valid(ofnode)) { + struct udevice *dev; + const char *bind_flag = ofnode_read_string(ofnode, "bind"); + + if (bind_flag && (strcmp(bind_flag, "True") == 0)) + lists_bind_fdt(parent, ofnode, &dev, false); + ofnode = dev_read_next_subnode(ofnode); + } + + return 0; +} + +static const struct udevice_id noptest1_ids[] = { + { + .compatible = "sandbox,nop_sandbox1", + }, + { } +}; + +U_BOOT_DRIVER(noptest_drv1) = { + .name = "noptest1_drv", + .of_match = noptest1_ids, + .id = UCLASS_NOP, + .bind = noptest_bind, +}; + +static const struct udevice_id noptest2_ids[] = { + { + .compatible = "sandbox,nop_sandbox2", + }, + { } +}; + +U_BOOT_DRIVER(noptest_drv2) = { + .name = "noptest2_drv", + .of_match = noptest2_ids, + .id = UCLASS_NOP, +}; + +static int dm_test_nop(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_get_device_by_name(UCLASS_NOP, "nop-test_0", &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_NOP, "nop-test_1", &dev)); + ut_asserteq(-ENODEV, + uclass_get_device_by_name(UCLASS_NOP, "nop-test_2", &dev)); + + return 0; +} + +DM_TEST(dm_test_nop, DM_TESTF_FLAT_TREE | DM_TESTF_SCAN_FDT);

dwc3-generic has been broken since MISC uclass has been modified to scan DT sub-nodes after bind. Fixing it by a using the no-op uclass.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 70431facb3..406bf0b362 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -350,7 +350,7 @@ static const struct udevice_id dwc3_glue_ids[] = {
U_BOOT_DRIVER(dwc3_generic_wrapper) = { .name = "dwc3-generic-wrapper", - .id = UCLASS_MISC, + .id = UCLASS_NOP, .of_match = dwc3_glue_ids, .bind = dwc3_glue_bind, .probe = dwc3_glue_probe,

This allow the phy to enter idle and then suspend. the K2 platforms require the PHY to be suspended before the USB domain clock can be turned off.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
drivers/usb/dwc3/core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 56e2a046bf..ae01490306 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -581,6 +581,12 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) return 0; }
+static void dwc3_gadget_run(struct dwc3 *dwc) +{ + dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_RUN_STOP); + mdelay(100); +} + static void dwc3_core_exit_mode(struct dwc3 *dwc) { switch (dwc->dr_mode) { @@ -598,6 +604,13 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) /* do nothing */ break; } + + /* + * switch back to peripheral mode + * This enables the phy to enter idle and then, if enabled, suspend. + */ + dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); + dwc3_gadget_run(dwc); }
#define DWC3_ALIGN_MASK (16 - 1)

The xhci.h header file is currently located under drivers/usb/xhci Move it to the include/usb folder to make it available to drivers that are not under drivers/usb/xhci
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
MAINTAINERS | 1 + drivers/usb/host/xhci-dwc3.c | 2 +- drivers/usb/host/xhci-exynos5.c | 2 +- drivers/usb/host/xhci-fsl.c | 2 +- drivers/usb/host/xhci-mem.c | 2 +- drivers/usb/host/xhci-mvebu.c | 2 +- drivers/usb/host/xhci-omap.c | 2 +- drivers/usb/host/xhci-pci.c | 2 +- drivers/usb/host/xhci-rcar.c | 2 +- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci-rockchip.c | 2 +- drivers/usb/host/xhci.c | 2 +- drivers/usb/phy/omap_usb_phy.c | 2 +- {drivers/usb/host => include/usb}/xhci.h | 0 14 files changed, 13 insertions(+), 12 deletions(-) rename {drivers/usb/host => include/usb}/xhci.h (100%)
diff --git a/MAINTAINERS b/MAINTAINERS index 8e26eda2c8..7e8a50bedb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -786,6 +786,7 @@ M: Bin Meng bmeng.cn@gmail.com S: Maintained T: git git://git.denx.de/u-boot-usb.git topic-xhci F: drivers/usb/host/xhci* +F: include/usb/xhci.h
VIDEO M: Anatolij Gustschin agust@denx.de diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 83b9f119e7..051c4c12e7 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -14,7 +14,7 @@ #include <usb.h> #include <dwc3-uboot.h>
-#include "xhci.h" +#include <usb/xhci.h> #include <asm/io.h> #include <linux/usb/dwc3.h> #include <linux/usb/otg.h> diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c index c150f520bd..25c30c24f0 100644 --- a/drivers/usb/host/xhci-exynos5.c +++ b/drivers/usb/host/xhci-exynos5.c @@ -27,7 +27,7 @@ #include <linux/compat.h> #include <linux/usb/dwc3.h>
-#include "xhci.h" +#include <usb/xhci.h>
/* Declare global data pointer */ DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c index c0b98a8ec7..9e0c1b76e4 100644 --- a/drivers/usb/host/xhci-fsl.c +++ b/drivers/usb/host/xhci-fsl.c @@ -13,7 +13,7 @@ #include <linux/compat.h> #include <linux/usb/xhci-fsl.h> #include <linux/usb/dwc3.h> -#include "xhci.h" +#include <usb/xhci.h> #include <fsl_errata.h> #include <fsl_usb.h> #include <dm.h> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 84c2c3344a..530e979bb7 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -21,7 +21,7 @@ #include <asm/cache.h> #include <linux/errno.h>
-#include "xhci.h" +#include <usb/xhci.h>
#define CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE /** diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index b6c6aaf78e..2b871046ae 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -12,7 +12,7 @@ #include <power/regulator.h> #include <asm/gpio.h>
-#include "xhci.h" +#include <usb/xhci.h>
struct mvebu_xhci_platdata { fdt_addr_t hcd_base; diff --git a/drivers/usb/host/xhci-omap.c b/drivers/usb/host/xhci-omap.c index db007af37f..25b195f7d1 100644 --- a/drivers/usb/host/xhci-omap.c +++ b/drivers/usb/host/xhci-omap.c @@ -19,7 +19,7 @@ #include <linux/usb/dwc3.h> #include <linux/usb/xhci-omap.h>
-#include "xhci.h" +#include <usb/xhci.h>
/* Declare global data pointer */ static struct omap_xhci omap; diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b995aef997..c1f60da541 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -9,7 +9,7 @@ #include <dm.h> #include <pci.h> #include <usb.h> -#include "xhci.h" +#include <usb/xhci.h>
static void xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr, struct xhci_hcor **ret_hcor) diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index f2e91ef0fe..c4d8811343 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -12,7 +12,7 @@ #include <usb.h> #include <wait_bit.h>
-#include "xhci.h" +#include <usb/xhci.h> #include "xhci-rcar-r8a779x_usb3_v3.h"
/* Register Offset */ diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b2cfd948f8..119b418487 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -19,7 +19,7 @@ #include <asm/unaligned.h> #include <linux/errno.h>
-#include "xhci.h" +#include <usb/xhci.h>
/** * Is this TRB a link TRB or was the last TRB the last TRB in this event ring diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c index f19bea3a91..4f221a60f2 100644 --- a/drivers/usb/host/xhci-rockchip.c +++ b/drivers/usb/host/xhci-rockchip.c @@ -13,7 +13,7 @@ #include <linux/usb/dwc3.h> #include <power/regulator.h>
-#include "xhci.h" +#include <usb/xhci.h>
struct rockchip_xhci_platdata { fdt_addr_t hcd_base; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 44c5f2d264..848721a49d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -28,7 +28,7 @@ #include <asm/cache.h> #include <asm/unaligned.h> #include <linux/errno.h> -#include "xhci.h" +#include <usb/xhci.h>
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 diff --git a/drivers/usb/phy/omap_usb_phy.c b/drivers/usb/phy/omap_usb_phy.c index 32e5bbb8d8..897e6f19f7 100644 --- a/drivers/usb/phy/omap_usb_phy.c +++ b/drivers/usb/phy/omap_usb_phy.c @@ -19,7 +19,7 @@ #include <linux/usb/dwc3.h> #include <linux/usb/xhci-omap.h>
-#include "../host/xhci.h" +#include <usb/xhci.h>
#ifdef CONFIG_OMAP_USB3PHY1_HOST struct usb3_dpll_params { diff --git a/drivers/usb/host/xhci.h b/include/usb/xhci.h similarity index 100% rename from drivers/usb/host/xhci.h rename to include/usb/xhci.h

On 6/27/19 1:02 PM, Jean-Jacques Hiblot wrote:
The xhci.h header file is currently located under drivers/usb/xhci Move it to the include/usb folder to make it available to drivers that are not under drivers/usb/xhci
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
This doesn't apply to u-boot/master (5eea874b5e989e62519824ad140aa086432d01ee)

On 27/06/2019 13:11, Marek Vasut wrote:
On 6/27/19 1:02 PM, Jean-Jacques Hiblot wrote:
The xhci.h header file is currently located under drivers/usb/xhci Move it to the include/usb folder to make it available to drivers that are not under drivers/usb/xhci
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
This doesn't apply to u-boot/master (5eea874b5e989e62519824ad140aa086432d01ee)
I'll send a rebased version ASAP.
Thanks

No one is actually implementing those functions. We could remove calls to these altogether, but it does not really hurt to keep the empty inlined version at the moment and it satisfies a symmetry with the gadget mode.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
drivers/usb/dwc3/core.h | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index cfe29884e7..4c89dfcad9 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -994,15 +994,10 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); int dwc3_init(struct dwc3 *dwc); void dwc3_remove(struct dwc3 *dwc);
-#ifdef CONFIG_USB_DWC3_HOST -int dwc3_host_init(struct dwc3 *dwc); -void dwc3_host_exit(struct dwc3 *dwc); -#else static inline int dwc3_host_init(struct dwc3 *dwc) { return 0; } static inline void dwc3_host_exit(struct dwc3 *dwc) { } -#endif
#ifdef CONFIG_USB_DWC3_GADGET int dwc3_gadget_init(struct dwc3 *dwc);

Separate platform data from the private data. This is one step toward adding host support.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 37 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 406bf0b362..f29b93d191 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -22,17 +22,22 @@ #include <reset.h> #include <clk.h>
+struct dwc3_generic_plat { + fdt_addr_t base; + u32 maximum_speed; + enum usb_dr_mode dr_mode; +}; + #if CONFIG_IS_ENABLED(DM_USB_GADGET) -struct dwc3_generic_peripheral { +struct dwc3_generic_priv { struct dwc3 dwc3; struct phy *phys; int num_phys; - fdt_addr_t base; };
int dm_usb_gadget_handle_interrupts(struct udevice *dev) { - struct dwc3_generic_peripheral *priv = dev_get_priv(dev); + struct dwc3_generic_priv *priv = dev_get_priv(dev); struct dwc3 *dwc3 = &priv->dwc3;
dwc3_gadget_uboot_handle_interrupt(dwc3); @@ -43,14 +48,18 @@ int dm_usb_gadget_handle_interrupts(struct udevice *dev) static int dwc3_generic_peripheral_probe(struct udevice *dev) { int rc; - struct dwc3_generic_peripheral *priv = dev_get_priv(dev); + struct dwc3_generic_priv *priv = dev_get_priv(dev); + struct dwc3_generic_plat *plat = dev_get_platdata(dev); struct dwc3 *dwc3 = &priv->dwc3;
+ dwc3->maximum_speed = plat->maximum_speed; + dwc3->dr_mode = plat->dr_mode; + rc = dwc3_setup_phy(dev, &priv->phys, &priv->num_phys); if (rc) return rc;
- dwc3->regs = map_physmem(priv->base, DWC3_OTG_REGS_END, MAP_NOCACHE); + dwc3->regs = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE); dwc3->regs += DWC3_GLOBALS_REGS_START; dwc3->dev = dev;
@@ -65,7 +74,7 @@ static int dwc3_generic_peripheral_probe(struct udevice *dev)
static int dwc3_generic_peripheral_remove(struct udevice *dev) { - struct dwc3_generic_peripheral *priv = dev_get_priv(dev); + struct dwc3_generic_priv *priv = dev_get_priv(dev); struct dwc3 *dwc3 = &priv->dwc3;
dwc3_remove(dwc3); @@ -77,20 +86,19 @@ static int dwc3_generic_peripheral_remove(struct udevice *dev)
static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev) { - struct dwc3_generic_peripheral *priv = dev_get_priv(dev); - struct dwc3 *dwc3 = &priv->dwc3; + struct dwc3_generic_plat *plat = dev_get_platdata(dev); int node = dev_of_offset(dev);
- priv->base = devfdt_get_addr(dev); + plat->base = devfdt_get_addr(dev);
- dwc3->maximum_speed = usb_get_maximum_speed(node); - if (dwc3->maximum_speed == USB_SPEED_UNKNOWN) { + plat->maximum_speed = usb_get_maximum_speed(node); + if (plat->maximum_speed == USB_SPEED_UNKNOWN) { pr_err("Invalid usb maximum speed\n"); return -ENODEV; }
- dwc3->dr_mode = usb_get_dr_mode(node); - if (dwc3->dr_mode == USB_DR_MODE_UNKNOWN) { + plat->dr_mode = usb_get_dr_mode(node); + if (plat->dr_mode == USB_DR_MODE_UNKNOWN) { pr_err("Invalid usb mode setup\n"); return -ENODEV; } @@ -104,7 +112,8 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = { .ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata, .probe = dwc3_generic_peripheral_probe, .remove = dwc3_generic_peripheral_remove, - .priv_auto_alloc_size = sizeof(struct dwc3_generic_peripheral), + .priv_auto_alloc_size = sizeof(struct dwc3_generic_priv), + .platdata_auto_alloc_size = sizeof(struct dwc3_generic_plat), }; #endif

Factor code for re-usability. This is another step toward adding host support.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 55 +++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 20 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index f29b93d191..d5c71d024f 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -28,27 +28,17 @@ struct dwc3_generic_plat { enum usb_dr_mode dr_mode; };
-#if CONFIG_IS_ENABLED(DM_USB_GADGET) struct dwc3_generic_priv { + void *base; struct dwc3 dwc3; struct phy *phys; int num_phys; };
-int dm_usb_gadget_handle_interrupts(struct udevice *dev) -{ - struct dwc3_generic_priv *priv = dev_get_priv(dev); - struct dwc3 *dwc3 = &priv->dwc3; - - dwc3_gadget_uboot_handle_interrupt(dwc3); - - return 0; -} - -static int dwc3_generic_peripheral_probe(struct udevice *dev) +static int dwc3_generic_probe(struct udevice *dev, + struct dwc3_generic_priv *priv) { int rc; - struct dwc3_generic_priv *priv = dev_get_priv(dev); struct dwc3_generic_plat *plat = dev_get_platdata(dev); struct dwc3 *dwc3 = &priv->dwc3;
@@ -59,22 +49,22 @@ static int dwc3_generic_peripheral_probe(struct udevice *dev) if (rc) return rc;
- dwc3->regs = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE); - dwc3->regs += DWC3_GLOBALS_REGS_START; + priv->base = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE); + dwc3->regs = priv->base + DWC3_GLOBALS_REGS_START; dwc3->dev = dev;
rc = dwc3_init(dwc3); if (rc) { - unmap_physmem(dwc3->regs, MAP_NOCACHE); + unmap_physmem(priv->base, MAP_NOCACHE); return rc; }
return 0; }
-static int dwc3_generic_peripheral_remove(struct udevice *dev) +static int dwc3_generic_remove(struct udevice *dev, + struct dwc3_generic_priv *priv) { - struct dwc3_generic_priv *priv = dev_get_priv(dev); struct dwc3 *dwc3 = &priv->dwc3;
dwc3_remove(dwc3); @@ -84,7 +74,7 @@ static int dwc3_generic_peripheral_remove(struct udevice *dev) return 0; }
-static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev) +static int dwc3_generic_ofdata_to_platdata(struct udevice *dev) { struct dwc3_generic_plat *plat = dev_get_platdata(dev); int node = dev_of_offset(dev); @@ -106,10 +96,35 @@ static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev) return 0; }
+#if CONFIG_IS_ENABLED(DM_USB_GADGET) +int dm_usb_gadget_handle_interrupts(struct udevice *dev) +{ + struct dwc3_generic_priv *priv = dev_get_priv(dev); + struct dwc3 *dwc3 = &priv->dwc3; + + dwc3_gadget_uboot_handle_interrupt(dwc3); + + return 0; +} + +static int dwc3_generic_peripheral_probe(struct udevice *dev) +{ + struct dwc3_generic_priv *priv = dev_get_priv(dev); + + return dwc3_generic_probe(dev, priv); +} + +static int dwc3_generic_peripheral_remove(struct udevice *dev) +{ + struct dwc3_generic_priv *priv = dev_get_priv(dev); + + return dwc3_generic_remove(dev, priv); +} + U_BOOT_DRIVER(dwc3_generic_peripheral) = { .name = "dwc3-generic-peripheral", .id = UCLASS_USB_GADGET_GENERIC, - .ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata, + .ofdata_to_platdata = dwc3_generic_ofdata_to_platdata, .probe = dwc3_generic_peripheral_probe, .remove = dwc3_generic_peripheral_remove, .priv_auto_alloc_size = sizeof(struct dwc3_generic_priv),

Currently the host driver used by dwc3-generic is "xhci-dwc3". This is a functional driver but it doesn't use the dwc3 core and, in particular, it lacks some bits that may be important. For example on the k2 platforms, it is important that the phy are properly suspended when the USB is not used anymore. The dwc3 core also has a partial support for quirks. The new driver can be used as a drop-in replacement for "xhci-dwc3".
In terms of implementation, it may seem strange that 2 private structures dwc3_generic_host_priv and dwc3_generic_priv) are used. The reason for this is simply that the xhci layer expects a struct xhci_ctrl at the beginning of the private data and it seemed wasteful to include it also for the peripheral case.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
drivers/usb/dwc3/core.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 54 ++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ae01490306..653c874fa6 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -887,7 +887,7 @@ int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys) } #endif
-#if CONFIG_IS_ENABLED(DM_USB_GADGET) +#if CONFIG_IS_ENABLED(DM_USB) int dwc3_init(struct dwc3 *dwc) { int ret; diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index d5c71d024f..4924d07553 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -21,6 +21,7 @@ #include "gadget.h" #include <reset.h> #include <clk.h> +#include <usb/xhci.h>
struct dwc3_generic_plat { fdt_addr_t base; @@ -35,6 +36,11 @@ struct dwc3_generic_priv { int num_phys; };
+struct dwc3_generic_host_priv { + struct xhci_ctrl xhci_ctrl; + struct dwc3_generic_priv gen_priv; +}; + static int dwc3_generic_probe(struct udevice *dev, struct dwc3_generic_priv *priv) { @@ -132,6 +138,50 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = { }; #endif
+#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD) +static int dwc3_generic_host_probe(struct udevice *dev) +{ + struct xhci_hcor *hcor; + struct xhci_hccr *hccr; + struct dwc3_generic_host_priv *priv = dev_get_priv(dev); + int rc; + + rc = dwc3_generic_probe(dev, &priv->gen_priv); + if (rc) + return rc; + + hccr = (struct xhci_hccr *)priv->gen_priv.base; + hcor = (struct xhci_hcor *)(priv->gen_priv.base + + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); + + return xhci_register(dev, hccr, hcor); +} + +static int dwc3_generic_host_remove(struct udevice *dev) +{ + struct dwc3_generic_host_priv *priv = dev_get_priv(dev); + int rc; + + rc = xhci_deregister(dev); + if (rc) + return rc; + + return dwc3_generic_remove(dev, &priv->gen_priv); +} + +U_BOOT_DRIVER(dwc3_generic_host) = { + .name = "dwc3-generic-host", + .id = UCLASS_USB, + .ofdata_to_platdata = dwc3_generic_ofdata_to_platdata, + .probe = dwc3_generic_host_probe, + .remove = dwc3_generic_host_remove, + .priv_auto_alloc_size = sizeof(struct dwc3_generic_host_priv), + .platdata_auto_alloc_size = sizeof(struct dwc3_generic_plat), + .ops = &xhci_usb_ops, + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif + struct dwc3_glue_data { struct clk_bulk clks; struct reset_ctl_bulk resets; @@ -252,10 +302,12 @@ static int dwc3_glue_bind(struct udevice *parent) driver = "dwc3-generic-peripheral"; #endif break; +#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD) case USB_DR_MODE_HOST: debug("%s: dr_mode: HOST\n", __func__); - driver = "xhci-dwc3"; + driver = "dwc3-generic-host"; break; +#endif default: debug("%s: unsupported dr_mode\n", __func__); return -ENODEV;

There is no need to fail if the maximum speed is not specified. If the speed is not specified, do the same as linux and assume super speed.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
---
Changes in v3: - updated log message when defaulting to super speed
Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 4924d07553..a3b65088f1 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -89,8 +89,8 @@ static int dwc3_generic_ofdata_to_platdata(struct udevice *dev)
plat->maximum_speed = usb_get_maximum_speed(node); if (plat->maximum_speed == USB_SPEED_UNKNOWN) { - pr_err("Invalid usb maximum speed\n"); - return -ENODEV; + pr_info("No USB maximum speed specified. Using super speed\n"); + plat->maximum_speed = USB_SPEED_SUPER; }
plat->dr_mode = usb_get_dr_mode(node);

Add a new function that read quirk and configuration information from the DT. The goal is to allow platforms using their own version of DWC3 driver to migrate to the generic DWC3 driver. The function is adapted from the function dwc3_get_properties() in the linux dwc3 driver introduced in commit c5ac6116db35d.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
---
Changes in v3: None Changes in v2: Update commit log
drivers/usb/dwc3/core.c | 65 +++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/dwc3-generic.c | 6 ++- 3 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 653c874fa6..1baad39796 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -888,6 +888,71 @@ int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys) #endif
#if CONFIG_IS_ENABLED(DM_USB) +void dwc3_of_parse(struct dwc3 *dwc) +{ + const u8 *tmp; + struct udevice *dev = dwc->dev; + u8 lpm_nyet_threshold; + u8 tx_de_emphasis; + u8 hird_threshold; + + /* default to highest possible threshold */ + lpm_nyet_threshold = 0xff; + + /* default to -3.5dB de-emphasis */ + tx_de_emphasis = 1; + + /* + * default to assert utmi_sleep_n and use maximum allowed HIRD + * threshold value of 0b1100 + */ + hird_threshold = 12; + + dwc->has_lpm_erratum = dev_read_bool(dev, + "snps,has-lpm-erratum"); + tmp = dev_read_u8_array_ptr(dev, "snps,lpm-nyet-threshold", 1); + if (tmp) + lpm_nyet_threshold = *tmp; + + dwc->is_utmi_l1_suspend = dev_read_bool(dev, + "snps,is-utmi-l1-suspend"); + tmp = dev_read_u8_array_ptr(dev, "snps,hird-threshold", 1); + if (tmp) + hird_threshold = *tmp; + + dwc->disable_scramble_quirk = dev_read_bool(dev, + "snps,disable_scramble_quirk"); + dwc->u2exit_lfps_quirk = dev_read_bool(dev, + "snps,u2exit_lfps_quirk"); + dwc->u2ss_inp3_quirk = dev_read_bool(dev, + "snps,u2ss_inp3_quirk"); + dwc->req_p1p2p3_quirk = dev_read_bool(dev, + "snps,req_p1p2p3_quirk"); + dwc->del_p1p2p3_quirk = dev_read_bool(dev, + "snps,del_p1p2p3_quirk"); + dwc->del_phy_power_chg_quirk = dev_read_bool(dev, + "snps,del_phy_power_chg_quirk"); + dwc->lfps_filter_quirk = dev_read_bool(dev, + "snps,lfps_filter_quirk"); + dwc->rx_detect_poll_quirk = dev_read_bool(dev, + "snps,rx_detect_poll_quirk"); + dwc->dis_u3_susphy_quirk = dev_read_bool(dev, + "snps,dis_u3_susphy_quirk"); + dwc->dis_u2_susphy_quirk = dev_read_bool(dev, + "snps,dis_u2_susphy_quirk"); + dwc->tx_de_emphasis_quirk = dev_read_bool(dev, + "snps,tx_de_emphasis_quirk"); + tmp = dev_read_u8_array_ptr(dev, "snps,tx_de_emphasis", 1); + if (tmp) + tx_de_emphasis = *tmp; + + dwc->lpm_nyet_threshold = lpm_nyet_threshold; + dwc->tx_de_emphasis = tx_de_emphasis; + + dwc->hird_threshold = hird_threshold + | (dwc->is_utmi_l1_suspend << 4); +} + int dwc3_init(struct dwc3 *dwc) { int ret; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 4c89dfcad9..be9672266a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -991,6 +991,7 @@ struct dwc3_gadget_ep_cmd_params {
/* prototypes */ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); +void dwc3_of_parse(struct dwc3 *dwc); int dwc3_init(struct dwc3 *dwc); void dwc3_remove(struct dwc3 *dwc);
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index a3b65088f1..023e95395b 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -48,8 +48,12 @@ static int dwc3_generic_probe(struct udevice *dev, struct dwc3_generic_plat *plat = dev_get_platdata(dev); struct dwc3 *dwc3 = &priv->dwc3;
+ dwc3->dev = dev; dwc3->maximum_speed = plat->maximum_speed; dwc3->dr_mode = plat->dr_mode; +#if CONFIG_IS_ENABLED(OF_CONTROL) + dwc3_of_parse(dwc3); +#endif
rc = dwc3_setup_phy(dev, &priv->phys, &priv->num_phys); if (rc) @@ -57,7 +61,7 @@ static int dwc3_generic_probe(struct udevice *dev,
priv->base = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE); dwc3->regs = priv->base + DWC3_GLOBALS_REGS_START; - dwc3->dev = dev; +
rc = dwc3_init(dwc3); if (rc) {

The mode selection for the DWC3 is kind of obsolete. The driver does not have to be host only or gadget only. This choice is confusing. All the remaining callers of dwc3_uboot_init() explicitly set dr_mode before calling the function, so none rely on a default behavior.
Remove the choice menu and keep only the USB_DWC3_GADGET option. Enable it by default if USB_GADGET and USB_DWC3 are enabled. It must be disabled for the evb-rk3328 as it uses DWC2 for the gadget and DWC3 for the host.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
---
Changes in v3: None Changes in v2: Select USB_GADGET_DUALSPEED if USB_DWC3_GADGET is selected
configs/evb-rk3328_defconfig | 1 + drivers/usb/dwc3/Kconfig | 18 ++---------------- drivers/usb/dwc3/core.c | 4 ++-- 3 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig index aff9c32362..98929f220a 100644 --- a/configs/evb-rk3328_defconfig +++ b/configs/evb-rk3328_defconfig @@ -58,6 +58,7 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_GENERIC=y CONFIG_USB_DWC2=y CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_GADGET is not set CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Rockchip" CONFIG_USB_GADGET_VENDOR_NUM=0x2207 diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 25e1a38aee..c302486291 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -7,25 +7,11 @@ config USB_DWC3
if USB_DWC3
-choice - bool "DWC3 Mode Selection" - -config USB_DWC3_HOST - bool "Host only mode" - depends on USB - help - Select this when you want to use DWC3 in host mode only, - thereby the gadget feature will be regressed. - config USB_DWC3_GADGET - bool "Gadget only mode" + bool "USB Gadget support for DWC3" + default y depends on USB_GADGET select USB_GADGET_DUALSPEED - help - Select this when you want to use DWC3 in gadget mode only, - thereby the host feature will be regressed. - -endchoice
comment "Platform Glue Driver Support"
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 1baad39796..9f7f053265 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -707,9 +707,9 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev) return -ENOMEM; }
- if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) + if (!IS_ENABLED(USB_DWC3_GADGET)) dwc->dr_mode = USB_DR_MODE_HOST; - else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) + else if (!IS_ENABLED(CONFIG_USB_HOST)) dwc->dr_mode = USB_DR_MODE_PERIPHERAL;
if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)

On 6/27/19 1:02 PM, Jean-Jacques Hiblot wrote:
The mode selection for the DWC3 is kind of obsolete. The driver does not have to be host only or gadget only. This choice is confusing. All the remaining callers of dwc3_uboot_init() explicitly set dr_mode before calling the function, so none rely on a default behavior.
Remove the choice menu and keep only the USB_DWC3_GADGET option. Enable it by default if USB_GADGET and USB_DWC3 are enabled. It must be disabled for the evb-rk3328 as it uses DWC2 for the gadget and DWC3 for the host.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
This patch breaks u-boot-usb/master and makes it not build e.g. on odroid-n2 , I am dropping it.

Hi Marek
On 07/08/2019 14:06, Marek Vasut wrote:
On 6/27/19 1:02 PM, Jean-Jacques Hiblot wrote:
The mode selection for the DWC3 is kind of obsolete. The driver does not have to be host only or gadget only. This choice is confusing. All the remaining callers of dwc3_uboot_init() explicitly set dr_mode before calling the function, so none rely on a default behavior.
Remove the choice menu and keep only the USB_DWC3_GADGET option. Enable it by default if USB_GADGET and USB_DWC3 are enabled. It must be disabled for the evb-rk3328 as it uses DWC2 for the gadget and DWC3 for the host.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
This patch breaks u-boot-usb/master and makes it not build e.g. on odroid-n2 , I am dropping it.
I've just send a fix for this that applies on top of u-boot-usb/master. Leaving this patch out, breaks the build of the k2g-evm platform.
The odroid-n2 is using DWC3 for host and DWC2 for the peripheral. This requires tweaking the defconfig to override the default behavior which is 'if gadget enabled and dwc3 present, then enable dwc3 gadget'
JJ

On 8/7/19 5:59 PM, Jean-Jacques Hiblot wrote:
Hi Marek
Hi,
On 07/08/2019 14:06, Marek Vasut wrote:
On 6/27/19 1:02 PM, Jean-Jacques Hiblot wrote:
The mode selection for the DWC3 is kind of obsolete. The driver does not have to be host only or gadget only. This choice is confusing. All the remaining callers of dwc3_uboot_init() explicitly set dr_mode before calling the function, so none rely on a default behavior.
Remove the choice menu and keep only the USB_DWC3_GADGET option. Enable it by default if USB_GADGET and USB_DWC3 are enabled. It must be disabled for the evb-rk3328 as it uses DWC2 for the gadget and DWC3 for the host.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
This patch breaks u-boot-usb/master and makes it not build e.g. on odroid-n2 , I am dropping it.
I've just send a fix for this that applies on top of u-boot-usb/master. Leaving this patch out, breaks the build of the k2g-evm platform.
The odroid-n2 is using DWC3 for host and DWC2 for the peripheral. This requires tweaking the defconfig to override the default behavior which is 'if gadget enabled and dwc3 present, then enable dwc3 gadget'
I don't want to block the other patches, so I dropped this whole patchset. Can you fix it up, CI it and resend it ? I'll pick it for the next USB PR.

Turning off the USB clocks may take longer than 100us. Increase the timeout to 100ms.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
arch/arm/mach-keystone/include/mach/psc_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-keystone/include/mach/psc_defs.h b/arch/arm/mach-keystone/include/mach/psc_defs.h index dfc22d5e90..f164f95bf2 100644 --- a/arch/arm/mach-keystone/include/mach/psc_defs.h +++ b/arch/arm/mach-keystone/include/mach/psc_defs.h @@ -94,7 +94,7 @@ static inline u32 boot_set_bitfield(u32 z, u32 f, u32 x, u32 y) * Timeout limit on checking PTSTAT. This is the number of times the * wait function will be called before giving up. */ -#define PSC_PTSTAT_TIMEOUT_LIMIT 100 +#define PSC_PTSTAT_TIMEOUT_LIMIT 100000
u32 psc_get_domain_num(u32 mod_num); int psc_enable_module(u32 mod_num);

This breaks linux boot sequence. Observed on k2e and k2l platforms.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
board/ti/ks2_evm/board.c | 13 ------------- 1 file changed, 13 deletions(-)
diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c index eed62e9cac..c1ebce42b6 100644 --- a/board/ti/ks2_evm/board.c +++ b/board/ti/ks2_evm/board.c @@ -66,20 +66,7 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
int board_init(void) { -#if CONFIG_IS_ENABLED(DM_USB) - int rc = psc_enable_module(KS2_LPSC_USB); - - if (rc) - puts("Cannot enable USB0 module"); -#ifdef KS2_LPSC_USB_1 - rc = psc_enable_module(KS2_LPSC_USB_1); - if (rc) - puts("Cannot enable USB1 module"); -#endif -#endif - gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; - return 0; }

There is no proper power domain support for the keystone platforms. However we need to turn off the USB domains before jumping to linux or it fail to boot (observed with k2e and k2l platforms). This can be done in the PHY driver as it is dedicated only to the keystone platforms and matches the required on/off sequence.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
drivers/phy/keystone-usb-phy.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/drivers/phy/keystone-usb-phy.c b/drivers/phy/keystone-usb-phy.c index e8146cabfa..14ac6bbbb2 100644 --- a/drivers/phy/keystone-usb-phy.c +++ b/drivers/phy/keystone-usb-phy.c @@ -9,6 +9,7 @@ #include <dm/device.h> #include <generic-phy.h> #include <asm/io.h> +#include <asm/arch/psc_defs.h>
/* USB PHY control register offsets */ #define USB_PHY_CTL_UTMI 0x0000 @@ -22,15 +23,25 @@ #define PHY_REF_SSP_EN BIT(29)
struct keystone_usb_phy { + u32 psc_domain; void __iomem *reg; };
static int keystone_usb_init(struct phy *phy) { u32 val; + int rc; struct udevice *dev = phy->dev; struct keystone_usb_phy *keystone = dev_get_priv(dev);
+ /* Release USB from reset */ + rc = psc_enable_module(keystone->psc_domain); + if (rc) { + debug("Cannot enable USB module"); + return -rc; + } + mdelay(10); + /* * VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't. * It should always be cleared because our USB PHY has an onchip VBUS @@ -72,13 +83,24 @@ static int keystone_usb_power_off(struct phy *phy)
static int keystone_usb_exit(struct phy *phy) { + struct udevice *dev = phy->dev; + struct keystone_usb_phy *keystone = dev_get_priv(dev); + + if (psc_disable_module(keystone->psc_domain)) + debug("failed to disable USB module!\n"); + return 0; }
static int keystone_usb_phy_probe(struct udevice *dev) { + int rc; struct keystone_usb_phy *keystone = dev_get_priv(dev);
+ rc = dev_read_u32(dev, "psc-domain", &keystone->psc_domain); + if (rc) + return rc; + keystone->reg = dev_remap_addr_index(dev, 0); if (!keystone->reg) { pr_err("unable to remap usb phy\n");

KEYSTONE_USB_PHY is now required for proper USB operations. XHCI_DWC3 can be disabled as the xhci-dwc3 is not used anymore USB_DWC3_GADGET can also be removed, it is now selected automatically.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v3: None Changes in v2: None
configs/k2g_evm_defconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig index 48d7fdc0af..1532844598 100644 --- a/configs/k2g_evm_defconfig +++ b/configs/k2g_evm_defconfig @@ -59,6 +59,7 @@ CONFIG_MII=y CONFIG_DRIVER_TI_KEYSTONE_NET=y CONFIG_PHY=y CONFIG_NOP_PHY=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_REMOTEPROC_TI_POWER=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y @@ -69,9 +70,7 @@ CONFIG_USB=y CONFIG_DM_USB=y CONFIG_DM_USB_GADGET=y CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_DWC3=y CONFIG_USB_DWC3=y -CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DOWNLOAD=y

As the PHY driver now handles the transitions of USB power domain, we must add this information in the node of each PHY. Also, the phy are expected in the "phys" property, not "usb-phys". Also add the aliases for the USB ports on boards with more than a single port.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
---
Changes in v3: None Changes in v2: None
arch/arm/dts/keystone-k2e-evm-u-boot.dtsi | 32 ++++++++++++++++++++++ arch/arm/dts/keystone-k2g-evm-u-boot.dtsi | 28 +++++++++++++++++++ arch/arm/dts/keystone-k2hk-evm-u-boot.dtsi | 14 ++++++++++ arch/arm/dts/keystone-k2l-evm-u-boot.dtsi | 18 ++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 arch/arm/dts/keystone-k2l-evm-u-boot.dtsi
diff --git a/arch/arm/dts/keystone-k2e-evm-u-boot.dtsi b/arch/arm/dts/keystone-k2e-evm-u-boot.dtsi index aecb4dde68..c94165ffe7 100644 --- a/arch/arm/dts/keystone-k2e-evm-u-boot.dtsi +++ b/arch/arm/dts/keystone-k2e-evm-u-boot.dtsi @@ -7,8 +7,40 @@ soc { u-boot,dm-pre-reloc; }; + aliases { + usb0 = &usb; + usb1 = &usb1; + }; };
&i2c1 { u-boot,dm-pre-reloc; }; + +&usb_phy { + #phy-cells = <0>; + psc-domain = <2>; +}; + +&usb { + dwc3@2690000 { + phys = <&usb_phy>; + dr_mode = "host"; + snps,u2ss_inp3_quirk; + status = "okay"; + }; +}; + +&usb1_phy { + #phy-cells = <0>; + psc-domain = <1>; +}; + +&usb1 { + dwc3@25010000 { + phys = <&usb1_phy>; + dr_mode = "peripheral"; + snps,u2ss_inp3_quirk; + status = "okay"; + }; +}; diff --git a/arch/arm/dts/keystone-k2g-evm-u-boot.dtsi b/arch/arm/dts/keystone-k2g-evm-u-boot.dtsi index 80f1f60045..e8e70096ea 100644 --- a/arch/arm/dts/keystone-k2g-evm-u-boot.dtsi +++ b/arch/arm/dts/keystone-k2g-evm-u-boot.dtsi @@ -7,6 +7,10 @@ soc { u-boot,dm-pre-reloc; }; + aliases { + usb0 = &usb0; + usb1 = &usb1; + }; };
&i2c0 { @@ -16,3 +20,27 @@ &i2c1 { u-boot,dm-pre-reloc; }; + +&usb0_phy { + compatible = "ti,keystone-usbphy"; + #phy-cells = <0>; + reg = <0x2620738 24>; + psc-domain = <25>; +}; + +&usb0 { + phys = <&usb0_phy>; + snps,u2ss_inp3_quirk; +}; + +&usb1_phy { + compatible = "ti,keystone-usbphy"; + #phy-cells = <0>; + reg = <0x2620750 24>; + psc-domain = <26>; +}; + +&usb1 { + phys = <&usb1_phy>; + snps,u2ss_inp3_quirk; +}; diff --git a/arch/arm/dts/keystone-k2hk-evm-u-boot.dtsi b/arch/arm/dts/keystone-k2hk-evm-u-boot.dtsi index aecb4dde68..1c2f349f5c 100644 --- a/arch/arm/dts/keystone-k2hk-evm-u-boot.dtsi +++ b/arch/arm/dts/keystone-k2hk-evm-u-boot.dtsi @@ -12,3 +12,17 @@ &i2c1 { u-boot,dm-pre-reloc; }; + +&usb_phy { + #phy-cells = <0>; + psc-domain = <2>; +}; + +&usb { + dwc3@2690000 { + phys = <&usb_phy>; + dr_mode = "host"; + snps,u2ss_inp3_quirk; + status = "okay"; + }; +}; diff --git a/arch/arm/dts/keystone-k2l-evm-u-boot.dtsi b/arch/arm/dts/keystone-k2l-evm-u-boot.dtsi new file mode 100644 index 0000000000..0a507d0210 --- /dev/null +++ b/arch/arm/dts/keystone-k2l-evm-u-boot.dtsi @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ + */ + +&usb_phy { + #phy-cells = <0>; + psc-domain = <2>; +}; + +&usb { + dwc3@2690000 { + phys = <&usb_phy>; + dr_mode = "host"; + snps,u2ss_inp3_quirk; + status = "okay"; + }; +};
participants (2)
-
Jean-Jacques Hiblot
-
Marek Vasut