[U-Boot] [PATCH v4 00/10] Improvements for the dwc3_generic driver

This series aims at bringing improvements to the dwc3_generic driver so that it can be used by most of the platforms using the dwc3 controller.
I tested this on with DRA7 and AM57x platforms for both Peripheral and Host operations. The code to enable DM USB host & dev support for those platforms will be submitted in a separate series.
Michal Simek has tested this series: " I have tested it on zcu100 with usb stick, usb to ethernet converter and also dfu. Tested-by: Michal Simek michal.simek@xilinx.com"
Enhancements: - use separate Kconfig option for DM USB Periphal and DM USB Host. This allow platforms to keep their non-DM USB peripheral code and use the DM USB host. - fixes the bind/probe confusion in dwc3_generic. The probe is done when the USB device is first needed. - handles PHYs when in the peripheral mode. The code to handle the PHYs is shared with the host side - handles clock and reset - bind host controller to the more generic driver 'xhci-dwc3'
Changes in v4: - rebased on latest U-Boot - renamed DM_USB_DEV as DM_USB_GADGET - Add a new commit to create a new UCLASS for USB gadget drivers
Changes in v3: - fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. This was visible only when the device is removed. - Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is false. This fixes all build issues but one (evb-rk3328). - Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2: - Updated commit log - Fixed typo in thordown.c - select DM_USB_DEV by default for zynqmp platforms
Jean-Jacques Hiblot (10): usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers usb: introduce a separate config option for DM USB device usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() dwc3_generic: do not probe the USB device driver when it's bound dwc3: move phy operation to core.c dm: usb: create a new UCLASS ID for USB gadget devices configs: evb-rk3328: Enable CONFIG_USB_DWC3 dwc3-generic: Handle the PHYs, the clocks and the reset lines dwc3-generic: Add select_dr_mode operation usb: dwc3: Fix a compilation error with the edison defconfig
arch/arm/Kconfig | 2 + board/sunxi/board.c | 2 +- cmd/fastboot.c | 4 +- cmd/rockusb.c | 4 +- cmd/thordown.c | 4 +- cmd/usb_gadget_sdp.c | 4 +- cmd/usb_mass_storage.c | 4 +- common/dfu.c | 6 +- configs/evb-rk3328_defconfig | 1 + drivers/usb/Kconfig | 14 +++ drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 89 ++++++++++++++- drivers/usb/dwc3/dwc3-generic.c | 208 ++++++++++++++++++++++++++++-------- drivers/usb/dwc3/ep0.c | 2 +- drivers/usb/gadget/ether.c | 40 ++----- drivers/usb/gadget/udc/Makefile | 4 + drivers/usb/gadget/udc/udc-core.c | 3 +- drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ drivers/usb/host/xhci-dwc3.c | 95 ++-------------- drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + include/dwc3-uboot.h | 19 ++++ include/linux/usb/gadget.h | 18 ++++ 24 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c

Add 2 functions to wrap the calls to board_usb_init() and board_usb_cleanup(). This is a preparatory work for DM support for UDC drivers (DM_USB_GADGET).
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Lukasz Majewski lukma@denx.de
---
Changes in v4: None Changes in v3: None Changes in v2: - Updated commit log - Fixed typo in thordown.c
cmd/fastboot.c | 4 ++-- cmd/rockusb.c | 4 ++-- cmd/thordown.c | 4 ++-- cmd/usb_gadget_sdp.c | 4 ++-- cmd/usb_mass_storage.c | 4 ++-- common/dfu.c | 6 +++--- drivers/usb/gadget/ether.c | 38 +++++--------------------------------- include/linux/usb/gadget.h | 10 ++++++++++ 8 files changed, 28 insertions(+), 46 deletions(-)
diff --git a/cmd/fastboot.c b/cmd/fastboot.c index ae3a5f6..0be83b7 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -51,7 +51,7 @@ static int do_fastboot_usb(int argc, char *const argv[], return CMD_RET_FAILURE; }
- ret = board_usb_init(controller_index, USB_INIT_DEVICE); + ret = usb_gadget_initialize(controller_index); if (ret) { pr_err("USB init failed: %d\n", ret); return CMD_RET_FAILURE; @@ -82,7 +82,7 @@ static int do_fastboot_usb(int argc, char *const argv[], exit: g_dnl_unregister(); g_dnl_clear_detach(); - board_usb_cleanup(controller_index, USB_INIT_DEVICE); + usb_gadget_release(controller_index);
return ret; #else diff --git a/cmd/rockusb.c b/cmd/rockusb.c index 8206643..e0c1480 100644 --- a/cmd/rockusb.c +++ b/cmd/rockusb.c @@ -33,7 +33,7 @@ static int do_rockusb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) dev_index = simple_strtoul(devnum, NULL, 0); rockusb_dev_init(devtype, dev_index);
- ret = board_usb_init(controller_index, USB_INIT_DEVICE); + ret = usb_gadget_initialize(controller_index); if (ret) { printf("USB init failed: %d\n", ret); return CMD_RET_FAILURE; @@ -62,7 +62,7 @@ static int do_rockusb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) exit: g_dnl_unregister(); g_dnl_clear_detach(); - board_usb_cleanup(controller_index, USB_INIT_DEVICE); + usb_gadget_release(controller_index);
return ret; } diff --git a/cmd/thordown.c b/cmd/thordown.c index 2615ada..ce3660d 100644 --- a/cmd/thordown.c +++ b/cmd/thordown.c @@ -30,7 +30,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) goto done;
int controller_index = simple_strtoul(usb_controller, NULL, 0); - ret = board_usb_init(controller_index, USB_INIT_DEVICE); + ret = usb_gadget_initialize(controller_index); if (ret) { pr_err("USB init failed: %d\n", ret); ret = CMD_RET_FAILURE; @@ -55,7 +55,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
exit: g_dnl_unregister(); - board_usb_cleanup(controller_index, USB_INIT_DEVICE); + usb_gadget_release(controller_index); done: dfu_free_entities();
diff --git a/cmd/usb_gadget_sdp.c b/cmd/usb_gadget_sdp.c index ba1f66a..808ed97 100644 --- a/cmd/usb_gadget_sdp.c +++ b/cmd/usb_gadget_sdp.c @@ -20,7 +20,7 @@ static int do_sdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char *usb_controller = argv[1]; int controller_index = simple_strtoul(usb_controller, NULL, 0); - board_usb_init(controller_index, USB_INIT_DEVICE); + usb_gadget_initialize(controller_index);
g_dnl_clear_detach(); g_dnl_register("usb_dnl_sdp"); @@ -37,7 +37,7 @@ static int do_sdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
exit: g_dnl_unregister(); - board_usb_cleanup(controller_index, USB_INIT_DEVICE); + usb_gadget_release(controller_index);
return ret; } diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index 0d55114..753ae4f 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -160,7 +160,7 @@ static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
controller_index = (unsigned int)(simple_strtoul( usb_controller, NULL, 0)); - if (board_usb_init(controller_index, USB_INIT_DEVICE)) { + if (usb_gadget_initialize(controller_index)) { pr_err("Couldn't init USB controller.\n"); rc = CMD_RET_FAILURE; goto cleanup_ums_init; @@ -231,7 +231,7 @@ static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, cleanup_register: g_dnl_unregister(); cleanup_board: - board_usb_cleanup(controller_index, USB_INIT_DEVICE); + usb_gadget_release(controller_index); cleanup_ums_init: ums_fini();
diff --git a/common/dfu.c b/common/dfu.c index 2620d32..44d1484 100644 --- a/common/dfu.c +++ b/common/dfu.c @@ -23,9 +23,9 @@ int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget) bool dfu_reset = false; int ret, i = 0;
- ret = board_usb_init(usbctrl_index, USB_INIT_DEVICE); + ret = usb_gadget_initialize(usbctrl_index); if (ret) { - pr_err("board usb init failed\n"); + pr_err("usb_gadget_initialize failed\n"); return CMD_RET_FAILURE; } g_dnl_clear_detach(); @@ -84,7 +84,7 @@ int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget) } exit: g_dnl_unregister(); - board_usb_cleanup(usbctrl_index, USB_INIT_DEVICE); + usb_gadget_release(usbctrl_index);
if (dfu_reset) do_reset(NULL, 0, 0, NULL); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 193583b..5a9ffd7 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -100,9 +100,6 @@ struct eth_dev { struct usb_gadget *gadget; struct usb_request *req; /* for control responses */ struct usb_request *stat_req; /* for cdc & rndis status */ -#if CONFIG_IS_ENABLED(DM_USB) - struct udevice *usb_udev; -#endif
u8 config; struct usb_ep *in_ep, *out_ep, *status_ep; @@ -2336,40 +2333,17 @@ fail: }
/*-------------------------------------------------------------------------*/ - -#if CONFIG_IS_ENABLED(DM_USB) -int dm_usb_init(struct eth_dev *e_dev) -{ - struct udevice *dev = NULL; - int ret; - - ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev); - if (!dev || ret) { - pr_err("No USB device found\n"); - return -ENODEV; - } - - e_dev->usb_udev = dev; - - return ret; -} -#endif - static int _usb_eth_init(struct ether_priv *priv) { struct eth_dev *dev = &priv->ethdev; struct usb_gadget *gadget; unsigned long ts; + int ret; unsigned long timeout = USB_CONNECT_TIMEOUT;
-#if CONFIG_IS_ENABLED(DM_USB) - if (dm_usb_init(dev)) { - pr_err("USB ether not found\n"); - return -ENODEV; - } -#else - board_usb_init(0, USB_INIT_DEVICE); -#endif + ret = usb_gadget_initialize(0); + if (ret) + return ret;
/* Configure default mac-addresses for the USB ethernet device */ #ifdef CONFIG_USBNET_DEV_ADDR @@ -2541,9 +2515,7 @@ void _usb_eth_halt(struct ether_priv *priv) }
usb_gadget_unregister_driver(&priv->eth_driver); -#if !CONFIG_IS_ENABLED(DM_USB) - board_usb_cleanup(0, USB_INIT_DEVICE); -#endif + usb_gadget_release(0); }
#ifndef CONFIG_DM_ETH diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index b824f13..40ca2d3 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -19,6 +19,7 @@ #define __LINUX_USB_GADGET_H
#include <errno.h> +#include <usb.h> #include <linux/compat.h> #include <linux/list.h>
@@ -926,4 +927,13 @@ extern void usb_ep_autoconfig_reset(struct usb_gadget *);
extern int usb_gadget_handle_interrupts(int index);
+static inline int usb_gadget_initialize(int index) +{ + return board_usb_init(index, USB_INIT_DEVICE); +} + +static inline int usb_gadget_release(int index) +{ + return board_usb_cleanup(index, USB_INIT_DEVICE); +} #endif /* __LINUX_USB_GADGET_H */

Using CONFIG_DM_USB for this purpose prevents using DM_USB for host and not for device.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Lukasz Majewski lukma@denx.de
---
Changes in v4: - renamed DM_USB_DEV as DM_USB_GADGET
Changes in v3: None Changes in v2: - select DM_USB_DEV by default for zynqmp platforms
arch/arm/Kconfig | 2 ++ drivers/usb/Kconfig | 14 ++++++++++++++ drivers/usb/dwc3/core.c | 3 +-- drivers/usb/dwc3/dwc3-generic.c | 4 ++-- 4 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f5d4d39..05b6ebf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -917,6 +917,7 @@ config ARCH_ZYNQMP_R5 select DM_SERIAL select OF_CONTROL imply CMD_DM + imply DM_USB_GADGET
config ARCH_ZYNQMP bool "Xilinx ZynqMP based platform" @@ -933,6 +934,7 @@ config ARCH_ZYNQMP imply CMD_DM imply FAT_WRITE imply MP + imply DM_USB_GADGET
config TEGRA bool "NVIDIA Tegra" diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 03746dd..631fcce 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -52,6 +52,20 @@ config SPL_DM_USB depends on DM_USB default y
+config DM_USB_GADGET + bool "Enable driver model for USB Gadget" + depends on DM_USB + help + Enable driver model for USB Gadget (Peripheral + mode) + +config SPL_DM_USB_GADGET + bool "Enable driver model for USB Gadget in sPL" + depends on SPL_DM_USB + help + Enable driver model for USB Gadget in SPL + (Peripheral mode) + source "drivers/usb/host/Kconfig"
source "drivers/usb/dwc3/Kconfig" diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index f1ca619..f9d8465 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -789,8 +789,7 @@ MODULE_AUTHOR("Felipe Balbi balbi@ti.com"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
-#if CONFIG_IS_ENABLED(DM_USB) - +#if CONFIG_IS_ENABLED(DM_USB_GADGET) 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 56c9fd6..ad3a116 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -21,8 +21,7 @@ #include "gadget.h" #include "linux-compat.h"
-DECLARE_GLOBAL_DATA_PTR; - +#if CONFIG_IS_ENABLED(DM_USB_GADGET) int usb_gadget_handle_interrupts(int index) { struct dwc3 *priv; @@ -97,6 +96,7 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = { .priv_auto_alloc_size = sizeof(struct dwc3), .flags = DM_FLAG_ALLOC_PRIV_DMA, }; +#endif
static int dwc3_generic_bind(struct udevice *parent) {

When DM_USB_GADGET the platform code for the USB device must be replaced by calls to a USB device driver.
usb_gadget_initialize() probes the USB device driver. usb_gadget_release() removes the USB device driver.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com Reviewed-by: Lukasz Majewski lukma@denx.de ---
Changes in v4: None Changes in v3: None Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 14 ++----------- drivers/usb/gadget/udc/udc-core.c | 44 ++++++++++++++++++++++++++++++++++++++- include/linux/usb/gadget.h | 8 +++++++ 3 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index ad3a116..47cc140 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -22,19 +22,9 @@ #include "linux-compat.h"
#if CONFIG_IS_ENABLED(DM_USB_GADGET) -int usb_gadget_handle_interrupts(int index) +int dm_usb_gadget_handle_interrupts(struct udevice *dev) { - struct dwc3 *priv; - struct udevice *dev; - int ret; - - ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev); - if (!dev || ret) { - pr_err("No USB device found\n"); - return -ENODEV; - } - - priv = dev_get_priv(dev); + struct dwc3 *priv = dev_get_priv(dev);
dwc3_gadget_uboot_handle_interrupt(priv);
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index f5c30dd..34bea27 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -18,7 +18,8 @@ #include <asm/cache.h> #include <asm/dma-mapping.h> #include <common.h> - +#include <dm.h> +#include <dm/device-internal.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h>
@@ -351,3 +352,44 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver); MODULE_DESCRIPTION("UDC Framework"); MODULE_AUTHOR("Felipe Balbi balbi@ti.com"); MODULE_LICENSE("GPL v2"); + +#if CONFIG_IS_ENABLED(DM_USB_GADGET) +#define MAX_UDC_DEVICES 4 +static struct udevice *dev_array[MAX_UDC_DEVICES]; +int usb_gadget_initialize(int index) +{ + int ret; + struct udevice *dev = NULL; + + if (index < 0 || index >= ARRAY_SIZE(dev_array)) + return -EINVAL; + if (dev_array[index]) + return 0; + ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, index, &dev); + if (!dev || ret) { + pr_err("No USB device found\n"); + return -ENODEV; + } + dev_array[index] = dev; + return 0; +} + +int usb_gadget_release(int index) +{ + int ret; + + if (index < 0 || index >= ARRAY_SIZE(dev_array)) + return -EINVAL; + ret = device_remove(dev_array[index], DM_REMOVE_NORMAL); + if (!ret) + dev_array[index] = NULL; + return ret; +} + +int usb_gadget_handle_interrupts(int index) +{ + if (index < 0 || index >= ARRAY_SIZE(dev_array)) + return -EINVAL; + return dm_usb_gadget_handle_interrupts(dev_array[index]); +} +#endif diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 40ca2d3..497798a 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -927,6 +927,12 @@ extern void usb_ep_autoconfig_reset(struct usb_gadget *);
extern int usb_gadget_handle_interrupts(int index);
+#if CONFIG_IS_ENABLED(DM_USB_GADGET) +int usb_gadget_initialize(int index); +int usb_gadget_release(int index); +int dm_usb_gadget_handle_interrupts(struct udevice *dev); +#else +#include <usb.h> static inline int usb_gadget_initialize(int index) { return board_usb_init(index, USB_INIT_DEVICE); @@ -936,4 +942,6 @@ static inline int usb_gadget_release(int index) { return board_usb_cleanup(index, USB_INIT_DEVICE); } +#endif + #endif /* __LINUX_USB_GADGET_H */

The driver will be probed when usb_gadget_initialize() is called.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 47cc140..681b5c7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -70,21 +70,14 @@ static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev) return 0; }
-static int dwc3_generic_peripheral_bind(struct udevice *dev) -{ - return device_probe(dev); -} - U_BOOT_DRIVER(dwc3_generic_peripheral) = { .name = "dwc3-generic-peripheral", .id = UCLASS_USB_DEV_GENERIC, .ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata, .probe = dwc3_generic_peripheral_probe, .remove = dwc3_generic_peripheral_remove, - .bind = dwc3_generic_peripheral_bind, .platdata_auto_alloc_size = sizeof(struct usb_platdata), .priv_auto_alloc_size = sizeof(struct dwc3), - .flags = DM_FLAG_ALLOC_PRIV_DMA, }; #endif

Those operations can be used for peripheral operation as well as host operation.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
# Conflicts: # drivers/usb/dwc3/core.c # drivers/usb/host/xhci-dwc3.c
---
Changes in v4: None Changes in v3: - fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. This was visible only when the device is removed. - Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is false. This fixes all build issues but one (evb-rk3328).
Changes in v2: None
drivers/usb/dwc3/core.c | 88 +++++++++++++++++++++++++++++++++++++++- drivers/usb/host/xhci-dwc3.c | 95 ++++---------------------------------------- include/dwc3-uboot.h | 19 +++++++++ 3 files changed, 112 insertions(+), 90 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index f9d8465..56e2a04 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -19,7 +19,7 @@ #include <asm/dma-mapping.h> #include <linux/ioport.h> #include <dm.h> - +#include <generic-phy.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h>
@@ -789,6 +789,91 @@ MODULE_AUTHOR("Felipe Balbi balbi@ti.com"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
+#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB) +int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys) +{ + int i, ret, count; + struct phy *usb_phys; + + /* Return if no phy declared */ + if (!dev_read_prop(dev, "phys", NULL)) + return 0; + count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); + if (count <= 0) + return count; + + usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), + GFP_KERNEL); + if (!usb_phys) + return -ENOMEM; + + for (i = 0; i < count; i++) { + ret = generic_phy_get_by_index(dev, i, &usb_phys[i]); + if (ret && ret != -ENOENT) { + pr_err("Failed to get USB PHY%d for %s\n", + i, dev->name); + return ret; + } + } + + for (i = 0; i < count; i++) { + ret = generic_phy_init(&usb_phys[i]); + if (ret) { + pr_err("Can't init USB PHY%d for %s\n", + i, dev->name); + goto phys_init_err; + } + } + + for (i = 0; i < count; i++) { + ret = generic_phy_power_on(&usb_phys[i]); + if (ret) { + pr_err("Can't power USB PHY%d for %s\n", + i, dev->name); + goto phys_poweron_err; + } + } + + *array = usb_phys; + *num_phys = count; + return 0; + +phys_poweron_err: + for (i = count - 1; i >= 0; i--) + generic_phy_power_off(&usb_phys[i]); + + for (i = 0; i < count; i++) + generic_phy_exit(&usb_phys[i]); + + return ret; + +phys_init_err: + for (; i >= 0; i--) + generic_phy_exit(&usb_phys[i]); + + return ret; +} + +int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys) +{ + int i, ret; + + for (i = 0; i < num_phys; i++) { + if (!generic_phy_valid(&usb_phys[i])) + continue; + + ret = generic_phy_power_off(&usb_phys[i]); + ret |= generic_phy_exit(&usb_phys[i]); + if (ret) { + pr_err("Can't shutdown USB PHY%d for %s\n", + i, dev->name); + } + } + + return 0; +} +#endif + #if CONFIG_IS_ENABLED(DM_USB_GADGET) int dwc3_init(struct dwc3 *dwc) { @@ -840,5 +925,4 @@ void dwc3_remove(struct dwc3 *dwc) dwc3_core_exit(dwc); kfree(dwc->mem); } - #endif diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index dd0d156..83b9f11 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -12,6 +12,7 @@ #include <fdtdec.h> #include <generic-phy.h> #include <usb.h> +#include <dwc3-uboot.h>
#include "xhci.h" #include <asm/io.h> @@ -110,105 +111,21 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) }
#if CONFIG_IS_ENABLED(DM_USB) -static int xhci_dwc3_setup_phy(struct udevice *dev) -{ - struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); - int i, ret, count; - - /* Return if no phy declared */ - if (!dev_read_prop(dev, "phys", NULL)) - return 0; - - count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); - if (count <= 0) - return count; - - plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), - GFP_KERNEL); - if (!plat->usb_phys) - return -ENOMEM; - - for (i = 0; i < count; i++) { - ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]); - if (ret && ret != -ENOENT) { - pr_err("Failed to get USB PHY%d for %s\n", - i, dev->name); - return ret; - } - - ++plat->num_phys; - } - - for (i = 0; i < plat->num_phys; i++) { - ret = generic_phy_init(&plat->usb_phys[i]); - if (ret) { - pr_err("Can't init USB PHY%d for %s\n", - i, dev->name); - goto phys_init_err; - } - } - - for (i = 0; i < plat->num_phys; i++) { - ret = generic_phy_power_on(&plat->usb_phys[i]); - if (ret) { - pr_err("Can't power USB PHY%d for %s\n", - i, dev->name); - goto phys_poweron_err; - } - } - - return 0; - -phys_poweron_err: - for (; i >= 0; i--) - generic_phy_power_off(&plat->usb_phys[i]); - - for (i = 0; i < plat->num_phys; i++) - generic_phy_exit(&plat->usb_phys[i]); - - return ret; - -phys_init_err: - for (; i >= 0; i--) - generic_phy_exit(&plat->usb_phys[i]); - - return ret; -} - -static int xhci_dwc3_shutdown_phy(struct udevice *dev) -{ - struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); - int i, ret; - - for (i = 0; i < plat->num_phys; i++) { - if (!generic_phy_valid(&plat->usb_phys[i])) - continue; - - ret = generic_phy_power_off(&plat->usb_phys[i]); - ret |= generic_phy_exit(&plat->usb_phys[i]); - if (ret) { - pr_err("Can't shutdown USB PHY%d for %s\n", - i, dev->name); - } - } - - return 0; -} - static int xhci_dwc3_probe(struct udevice *dev) { struct xhci_hcor *hcor; struct xhci_hccr *hccr; struct dwc3 *dwc3_reg; enum usb_dr_mode dr_mode; + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); int ret;
hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev)); hcor = (struct xhci_hcor *)((uintptr_t)hccr + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
- ret = xhci_dwc3_setup_phy(dev); - if (ret) + ret = dwc3_setup_phy(dev, &plat->usb_phys, &plat->num_phys); + if (ret && (ret != -ENOTSUPP)) return ret;
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); @@ -227,7 +144,9 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev) { - xhci_dwc3_shutdown_phy(dev); + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); + + dwc3_shutdown_phy(dev, plat->usb_phys, plat->num_phys);
return xhci_deregister(dev); } diff --git a/include/dwc3-uboot.h b/include/dwc3-uboot.h index 228ab3b..9941cc3 100644 --- a/include/dwc3-uboot.h +++ b/include/dwc3-uboot.h @@ -38,4 +38,23 @@ struct dwc3_device { int dwc3_uboot_init(struct dwc3_device *dev); void dwc3_uboot_exit(int index); void dwc3_uboot_handle_interrupt(int index); + +struct phy; +#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB) +int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys); +int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys); +#else +static inline int dwc3_setup_phy(struct udevice *dev, struct phy **array, + int *num_phys) +{ + return -ENOTSUPP; +} + +static inline int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, + int num_phys) +{ + return -ENOTSUPP; +} +#endif + #endif /* __DWC3_UBOOT_H_ */

UCLASS_USB_DEV_GENERIC was meant for USB devices connected to host controllers, not gadget devices. Adding a new UCLASS for gadget devices alone.
Also move the generic DM code for USB gadgets in a separate file for clarity.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
---
Changes in v4: None Changes in v3: None Changes in v2: None
board/sunxi/board.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/udc/Makefile | 4 +++ drivers/usb/gadget/udc/udc-core.c | 41 -------------------------- drivers/usb/gadget/udc/udc-uclass.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 64ccbc7..9b36cc7 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -663,7 +663,7 @@ int g_dnl_board_usb_cable_connected(void) struct phy phy; int ret;
- ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev); + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev); if (ret) { pr_err("%s: Cannot find USB device\n", __func__); return ret; diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 681b5c7..7375660 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -72,7 +72,7 @@ static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev)
U_BOOT_DRIVER(dwc3_generic_peripheral) = { .name = "dwc3-generic-peripheral", - .id = UCLASS_USB_DEV_GENERIC, + .id = UCLASS_USB_GADGET_GENERIC, .ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata, .probe = dwc3_generic_peripheral_probe, .remove = dwc3_generic_peripheral_remove, diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 5a9ffd7..3b3d9af 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2671,7 +2671,7 @@ int usb_ether_init(void) struct udevice *usb_dev; int ret;
- ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &usb_dev); + ret = uclass_first_device(UCLASS_USB_GADGET_GENERIC, &usb_dev); if (!usb_dev || ret) { pr_err("No USB device found\n"); return ret; diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index 449339f..38ac2dd 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile @@ -2,4 +2,8 @@ # # USB peripheral controller drivers
+ifndef CONFIG_$(SPL_)DM_USB_GADGET obj-$(CONFIG_USB_DWC3_GADGET) += udc-core.o +endif + +obj-$(CONFIG_$(SPL_)DM_USB_GADGET) += udc-uclass.o udc-core.o diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index 34bea27..62b4778 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -352,44 +352,3 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver); MODULE_DESCRIPTION("UDC Framework"); MODULE_AUTHOR("Felipe Balbi balbi@ti.com"); MODULE_LICENSE("GPL v2"); - -#if CONFIG_IS_ENABLED(DM_USB_GADGET) -#define MAX_UDC_DEVICES 4 -static struct udevice *dev_array[MAX_UDC_DEVICES]; -int usb_gadget_initialize(int index) -{ - int ret; - struct udevice *dev = NULL; - - if (index < 0 || index >= ARRAY_SIZE(dev_array)) - return -EINVAL; - if (dev_array[index]) - return 0; - ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, index, &dev); - if (!dev || ret) { - pr_err("No USB device found\n"); - return -ENODEV; - } - dev_array[index] = dev; - return 0; -} - -int usb_gadget_release(int index) -{ - int ret; - - if (index < 0 || index >= ARRAY_SIZE(dev_array)) - return -EINVAL; - ret = device_remove(dev_array[index], DM_REMOVE_NORMAL); - if (!ret) - dev_array[index] = NULL; - return ret; -} - -int usb_gadget_handle_interrupts(int index) -{ - if (index < 0 || index >= ARRAY_SIZE(dev_array)) - return -EINVAL; - return dm_usb_gadget_handle_interrupts(dev_array[index]); -} -#endif diff --git a/drivers/usb/gadget/udc/udc-uclass.c b/drivers/usb/gadget/udc/udc-uclass.c new file mode 100644 index 0000000..0620518 --- /dev/null +++ b/drivers/usb/gadget/udc/udc-uclass.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com + * Written by Jean-Jacques Hiblot jjhiblot@ti.com + */ + +#include <common.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <linux/usb/gadget.h> + +#define MAX_UDC_DEVICES 4 +static struct udevice *dev_array[MAX_UDC_DEVICES]; +int usb_gadget_initialize(int index) +{ + int ret; + struct udevice *dev = NULL; + + if (index < 0 || index >= ARRAY_SIZE(dev_array)) + return -EINVAL; + if (dev_array[index]) + return 0; + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, index, &dev); + if (!dev || ret) { + pr_err("No USB device found\n"); + return -ENODEV; + } + dev_array[index] = dev; + return 0; +} + +int usb_gadget_release(int index) +{ +#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) + int ret; + if (index < 0 || index >= ARRAY_SIZE(dev_array)) + return -EINVAL; + + ret = device_remove(dev_array[index], DM_REMOVE_NORMAL); + if (!ret) + dev_array[index] = NULL; + return ret; +#else + return -ENOTSUPP; +#endif +} + +int usb_gadget_handle_interrupts(int index) +{ + if (index < 0 || index >= ARRAY_SIZE(dev_array)) + return -EINVAL; + return dm_usb_gadget_handle_interrupts(dev_array[index]); +} + +UCLASS_DRIVER(usb_gadget_generic) = { + .id = UCLASS_USB_GADGET_GENERIC, + .name = "usb_gadget_generic", +}; diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c index 58aed72..32743aa 100644 --- a/drivers/usb/musb-new/omap2430.c +++ b/drivers/usb/musb-new/omap2430.c @@ -263,7 +263,7 @@ U_BOOT_DRIVER(omap2430_musb) = { #ifdef CONFIG_USB_MUSB_HOST .id = UCLASS_USB, #else - .id = UCLASS_USB_DEV_GENERIC, + .id = UCLASS_USB_GADGET_GENERIC, #endif .of_match = omap2430_musb_ids, .ofdata_to_platdata = omap2430_musb_ofdata_to_platdata, diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 6cf9826..d7170a3 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -535,7 +535,7 @@ U_BOOT_DRIVER(usb_musb) = { #ifdef CONFIG_USB_MUSB_HOST .id = UCLASS_USB, #else - .id = UCLASS_USB_DEV_GENERIC, + .id = UCLASS_USB_GADGET_GENERIC, #endif .of_match = sunxi_musb_ids, .probe = musb_usb_probe, diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index c91dca1..1601100 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -92,6 +92,7 @@ enum uclass_id { UCLASS_USB, /* USB bus */ UCLASS_USB_DEV_GENERIC, /* USB generic device */ UCLASS_USB_HUB, /* USB hub */ + UCLASS_USB_GADGET_GENERIC, /* USB generic device */ UCLASS_VIDEO, /* Video or LCD device */ UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */

Hi Jean-Jacques,
On Thu, 29 Nov 2018 at 02:54, Jean-Jacques Hiblot jjhiblot@ti.com wrote:
UCLASS_USB_DEV_GENERIC was meant for USB devices connected to host controllers, not gadget devices. Adding a new UCLASS for gadget devices alone.
Also move the generic DM code for USB gadgets in a separate file for clarity.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Changes in v4: None Changes in v3: None Changes in v2: None
board/sunxi/board.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/udc/Makefile | 4 +++ drivers/usb/gadget/udc/udc-core.c | 41 -------------------------- drivers/usb/gadget/udc/udc-uclass.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
We should have a test for this, with a sandbox driver for this uclass, as we have done for UCLASS_USB.
Regards, Simon

On Thu, Nov 29, 2018 at 3:30 PM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
UCLASS_USB_DEV_GENERIC was meant for USB devices connected to host controllers, not gadget devices. Adding a new UCLASS for gadget devices alone.
Also move the generic DM code for USB gadgets in a separate file for clarity.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Changes in v4: None Changes in v3: None Changes in v2: None
board/sunxi/board.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/udc/Makefile | 4 +++ drivers/usb/gadget/udc/udc-core.c | 41 -------------------------- drivers/usb/gadget/udc/udc-uclass.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 64ccbc7..9b36cc7 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -663,7 +663,7 @@ int g_dnl_board_usb_cable_connected(void) struct phy phy; int ret;
ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev);
ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
This is breaking sunxi boards which uses gadget mode.
U-Boot 2019.01-rc2 (Dec 18 2018 - 17:31:53 +0530) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680) Model: Banana Pi BPI-M2-Plus DRAM: 1 GiB Error binding driver 'sunxi-musb': -96 Some drivers failed to bind Error binding driver 'generic_simple_bus': -96 Some drivers failed to bind initcall sequence 7dfd127c failed at call 4a00c3a3 (err=-96) ### ERROR ### Please RESET the board ###

On Tue, Dec 18, 2018 at 6:08 AM Jagan Teki jagan@amarulasolutions.com wrote:
On Thu, Nov 29, 2018 at 3:30 PM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
UCLASS_USB_DEV_GENERIC was meant for USB devices connected to host controllers, not gadget devices. Adding a new UCLASS for gadget devices alone.
Also move the generic DM code for USB gadgets in a separate file for clarity.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Changes in v4: None Changes in v3: None Changes in v2: None
board/sunxi/board.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/udc/Makefile | 4 +++ drivers/usb/gadget/udc/udc-core.c | 41 -------------------------- drivers/usb/gadget/udc/udc-uclass.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 64ccbc7..9b36cc7 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -663,7 +663,7 @@ int g_dnl_board_usb_cable_connected(void) struct phy phy; int ret;
ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev);
ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
This is breaking sunxi boards which uses gadget mode.
U-Boot 2019.01-rc2 (Dec 18 2018 - 17:31:53 +0530) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680) Model: Banana Pi BPI-M2-Plus DRAM: 1 GiB Error binding driver 'sunxi-musb': -96 Some drivers failed to bind Error binding driver 'generic_simple_bus': -96 Some drivers failed to bind initcall sequence 7dfd127c failed at call 4a00c3a3 (err=-96) ### ERROR ### Please RESET the board ###
I got a similar error when I tried to port the work done for the gadget mode to the omap2420 glue. I don't know if they're related, but the messages are the same (-96). I ended up just ignoring the generic device all together and used the #ifdef to load either host or gadget in the patch I submitted for the omap2430 glue. If this gets resolved, I might re-evaluate how I did the patch.
adam
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

On 18/12/2018 13:08, Jagan Teki wrote:
On Thu, Nov 29, 2018 at 3:30 PM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
UCLASS_USB_DEV_GENERIC was meant for USB devices connected to host controllers, not gadget devices. Adding a new UCLASS for gadget devices alone.
Also move the generic DM code for USB gadgets in a separate file for clarity.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Changes in v4: None Changes in v3: None Changes in v2: None
board/sunxi/board.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/udc/Makefile | 4 +++ drivers/usb/gadget/udc/udc-core.c | 41 -------------------------- drivers/usb/gadget/udc/udc-uclass.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 64ccbc7..9b36cc7 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -663,7 +663,7 @@ int g_dnl_board_usb_cable_connected(void) struct phy phy; int ret;
ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev);
ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
This is breaking sunxi boards which uses gadget mode.
U-Boot 2019.01-rc2 (Dec 18 2018 - 17:31:53 +0530) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680) Model: Banana Pi BPI-M2-Plus DRAM: 1 GiB Error binding driver 'sunxi-musb': -96 Some drivers failed to bind
Can you try with DM_USB_GADGET enabled ?
JJ
Error binding driver 'generic_simple_bus': -96 Some drivers failed to bind initcall sequence 7dfd127c failed at call 4a00c3a3 (err=-96) ### ERROR ### Please RESET the board ###

On 19/12/2018 11:31, Jean-Jacques Hiblot wrote:
On 18/12/2018 13:08, Jagan Teki wrote:
On Thu, Nov 29, 2018 at 3:30 PM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
UCLASS_USB_DEV_GENERIC was meant for USB devices connected to host controllers, not gadget devices. Adding a new UCLASS for gadget devices alone.
Also move the generic DM code for USB gadgets in a separate file for clarity.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Changes in v4: None Changes in v3: None Changes in v2: None
board/sunxi/board.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/udc/Makefile | 4 +++ drivers/usb/gadget/udc/udc-core.c | 41 -------------------------- drivers/usb/gadget/udc/udc-uclass.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 64ccbc7..9b36cc7 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -663,7 +663,7 @@ int g_dnl_board_usb_cable_connected(void) struct phy phy; int ret;
- ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev); + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
This is breaking sunxi boards which uses gadget mode.
U-Boot 2019.01-rc2 (Dec 18 2018 - 17:31:53 +0530) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680) Model: Banana Pi BPI-M2-Plus DRAM: 1 GiB Error binding driver 'sunxi-musb': -96 Some drivers failed to bind
Can you try with DM_USB_GADGET enabled ?
The reasoning is that UCLASS_DRIVER(usb_gadget_generic) is defined if and only if DM_USB_GADGET is enabled.
JJ
Error binding driver 'generic_simple_bus': -96 Some drivers failed to bind initcall sequence 7dfd127c failed at call 4a00c3a3 (err=-96) ### ERROR ### Please RESET the board ###
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

On Wed, Dec 19, 2018 at 4:34 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 19/12/2018 11:31, Jean-Jacques Hiblot wrote:
On 18/12/2018 13:08, Jagan Teki wrote:
On Thu, Nov 29, 2018 at 3:30 PM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
UCLASS_USB_DEV_GENERIC was meant for USB devices connected to host controllers, not gadget devices. Adding a new UCLASS for gadget devices alone.
Also move the generic DM code for USB gadgets in a separate file for clarity.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
Changes in v4: None Changes in v3: None Changes in v2: None
board/sunxi/board.c | 2 +- drivers/usb/dwc3/dwc3-generic.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/udc/Makefile | 4 +++ drivers/usb/gadget/udc/udc-core.c | 41 -------------------------- drivers/usb/gadget/udc/udc-uclass.c | 58 +++++++++++++++++++++++++++++++++++++ drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + 9 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 64ccbc7..9b36cc7 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -663,7 +663,7 @@ int g_dnl_board_usb_cable_connected(void) struct phy phy; int ret;
ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev);
ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
This is breaking sunxi boards which uses gadget mode.
U-Boot 2019.01-rc2 (Dec 18 2018 - 17:31:53 +0530) Allwinner Technology
CPU: Allwinner H3 (SUN8I 1680) Model: Banana Pi BPI-M2-Plus DRAM: 1 GiB Error binding driver 'sunxi-musb': -96 Some drivers failed to bind
Can you try with DM_USB_GADGET enabled ?
The reasoning is that UCLASS_DRIVER(usb_gadget_generic) is defined if and only if DM_USB_GADGET is enabled.
I tried this when trying to port to the omap2430 glue, and got the same -96 error when using the MISC class driver and I enabled DM_USB_GADGET.
adam
JJ
Error binding driver 'generic_simple_bus': -96 Some drivers failed to bind initcall sequence 7dfd127c failed at call 4a00c3a3 (err=-96) ### ERROR ### Please RESET the board ###
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

This is now required because the PHY operations used by xhci-dwc3 are part of the dwc3 core.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com
---
Changes in v4: None Changes in v3: - Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2: None
configs/evb-rk3328_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig index 5b3bb8e..f022163 100644 --- a/configs/evb-rk3328_defconfig +++ b/configs/evb-rk3328_defconfig @@ -49,6 +49,7 @@ CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYSRESET=y CONFIG_USB=y +CONFIG_USB_DWC3=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y CONFIG_USB_EHCI_HCD=y

This make the driver more generic. At this point this driver can replace the dwc3-of-simple implementation. Make the description in the Kconfig more generic too.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/dwc3-generic.c | 159 +++++++++++++++++++++++++++++++++------- 2 files changed, 137 insertions(+), 29 deletions(-)
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 943b763..bbd8105 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -38,10 +38,11 @@ config USB_DWC3_OMAP Say 'Y' here if you have one such device
config USB_DWC3_GENERIC - bool "Xilinx ZynqMP and similar Platforms" - depends on DM_USB && USB_DWC3 + bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)" + depends on DM_USB && USB_DWC3 && MISC help - Some platforms can reuse this DWC3 generic implementation. + Select this for Xilinx ZynqMP and similar Platforms. + This wrapper supports Host and Peripheral operation modes.
config USB_DWC3_UNIPHIER bool "DesignWare USB3 Host Support on UniPhier Platforms" diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 7375660..7be0187 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -11,58 +11,85 @@ #include <dm.h> #include <dm/device-internal.h> #include <dm/lists.h> -#include <linux/usb/otg.h> -#include <linux/compat.h> +#include <dwc3-uboot.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <malloc.h> #include <usb.h> #include "core.h" #include "gadget.h" -#include "linux-compat.h" +#include <reset.h> +#include <clk.h>
#if CONFIG_IS_ENABLED(DM_USB_GADGET) +struct dwc3_generic_peripheral { + struct dwc3 dwc3; + struct phy *phys; + int num_phys; + fdt_addr_t base; +}; + int dm_usb_gadget_handle_interrupts(struct udevice *dev) { - struct dwc3 *priv = dev_get_priv(dev); + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); + struct dwc3 *dwc3 = &priv->dwc3;
- dwc3_gadget_uboot_handle_interrupt(priv); + dwc3_gadget_uboot_handle_interrupt(dwc3);
return 0; }
static int dwc3_generic_peripheral_probe(struct udevice *dev) { - struct dwc3 *priv = dev_get_priv(dev); + int rc; + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); + struct dwc3 *dwc3 = &priv->dwc3; + + 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 += DWC3_GLOBALS_REGS_START; + dwc3->dev = dev; + + rc = dwc3_init(dwc3); + if (rc) { + unmap_physmem(dwc3->regs, MAP_NOCACHE); + return rc; + }
- return dwc3_init(priv); + return 0; }
static int dwc3_generic_peripheral_remove(struct udevice *dev) { - struct dwc3 *priv = dev_get_priv(dev); + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); + struct dwc3 *dwc3 = &priv->dwc3;
- dwc3_remove(priv); + dwc3_remove(dwc3); + dwc3_shutdown_phy(dev, priv->phys, priv->num_phys); + unmap_physmem(dwc3->regs, MAP_NOCACHE);
return 0; }
static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev) { - struct dwc3 *priv = dev_get_priv(dev); + struct dwc3_generic_peripheral *priv = dev_get_priv(dev); + struct dwc3 *dwc3 = &priv->dwc3; int node = dev_of_offset(dev);
- priv->regs = (void *)devfdt_get_addr(dev); - priv->regs += DWC3_GLOBALS_REGS_START; + priv->base = devfdt_get_addr(dev);
- priv->maximum_speed = usb_get_maximum_speed(node); - if (priv->maximum_speed == USB_SPEED_UNKNOWN) { + dwc3->maximum_speed = usb_get_maximum_speed(node); + if (dwc3->maximum_speed == USB_SPEED_UNKNOWN) { pr_err("Invalid usb maximum speed\n"); return -ENODEV; }
- priv->dr_mode = usb_get_dr_mode(node); - if (priv->dr_mode == USB_DR_MODE_UNKNOWN) { + dwc3->dr_mode = usb_get_dr_mode(node); + if (dwc3->dr_mode == USB_DR_MODE_UNKNOWN) { pr_err("Invalid usb mode setup\n"); return -ENODEV; } @@ -76,12 +103,16 @@ 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, - .platdata_auto_alloc_size = sizeof(struct usb_platdata), - .priv_auto_alloc_size = sizeof(struct dwc3), + .priv_auto_alloc_size = sizeof(struct dwc3_generic_peripheral), }; #endif
-static int dwc3_generic_bind(struct udevice *parent) +struct dwc3_glue_data { + struct clk_bulk clks; + struct reset_ctl_bulk resets; +}; + +static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob; int node; @@ -92,29 +123,32 @@ static int dwc3_generic_bind(struct udevice *parent) const char *name = fdt_get_name(fdt, node, NULL); enum usb_dr_mode dr_mode; struct udevice *dev; - const char *driver; + const char *driver = NULL;
debug("%s: subnode name: %s\n", __func__, name); - if (strncmp(name, "dwc3@", 4)) - continue;
dr_mode = usb_get_dr_mode(node);
switch (dr_mode) { case USB_DR_MODE_PERIPHERAL: case USB_DR_MODE_OTG: +#if CONFIG_IS_ENABLED(DM_USB_GADGET) debug("%s: dr_mode: OTG or Peripheral\n", __func__); driver = "dwc3-generic-peripheral"; +#endif break; case USB_DR_MODE_HOST: debug("%s: dr_mode: HOST\n", __func__); - driver = "dwc3-generic-host"; + driver = "xhci-dwc3"; break; default: debug("%s: unsupported dr_mode\n", __func__); return -ENODEV; };
+ if (!driver) + continue; + ret = device_bind_driver_to_node(parent, driver, name, offset_to_ofnode(node), &dev); if (ret) { @@ -127,7 +161,76 @@ static int dwc3_generic_bind(struct udevice *parent) return 0; }
-static const struct udevice_id dwc3_generic_ids[] = { +static int dwc3_glue_reset_init(struct udevice *dev, + struct dwc3_glue_data *glue) +{ + int ret; + + ret = reset_get_bulk(dev, &glue->resets); + if (ret == -ENOTSUPP) + return 0; + else if (ret) + return ret; + + ret = reset_deassert_bulk(&glue->resets); + if (ret) { + reset_release_bulk(&glue->resets); + return ret; + } + + return 0; +} + +static int dwc3_glue_clk_init(struct udevice *dev, + struct dwc3_glue_data *glue) +{ + int ret; + + ret = clk_get_bulk(dev, &glue->clks); + if (ret == -ENOSYS) + return 0; + if (ret) + return ret; + +#if CONFIG_IS_ENABLED(CLK) + ret = clk_enable_bulk(&glue->clks); + if (ret) { + clk_release_bulk(&glue->clks); + return ret; + } +#endif + + return 0; +} + +static int dwc3_glue_probe(struct udevice *dev) +{ + struct dwc3_glue_data *glue = dev_get_platdata(dev); + int ret; + + ret = dwc3_glue_clk_init(dev, glue); + if (ret) + return ret; + + ret = dwc3_glue_reset_init(dev, glue); + if (ret) + return ret; + + return 0; +} + +static int dwc3_glue_remove(struct udevice *dev) +{ + struct dwc3_glue_data *glue = dev_get_platdata(dev); + + reset_release_bulk(&glue->resets); + + clk_release_bulk(&glue->clks); + + return dm_scan_fdt_dev(dev); +} + +static const struct udevice_id dwc3_glue_ids[] = { { .compatible = "xlnx,zynqmp-dwc3" }, { } }; @@ -135,6 +238,10 @@ static const struct udevice_id dwc3_generic_ids[] = { U_BOOT_DRIVER(dwc3_generic_wrapper) = { .name = "dwc3-generic-wrapper", .id = UCLASS_MISC, - .of_match = dwc3_generic_ids, - .bind = dwc3_generic_bind, + .of_match = dwc3_glue_ids, + .bind = dwc3_glue_bind, + .probe = dwc3_glue_probe, + .remove = dwc3_glue_remove, + .platdata_auto_alloc_size = sizeof(struct dwc3_glue_data), + };

The select_dr_mode operation is executed when the glue driver is probed. The role of this optional function is to configure the operating mode of the controller at the glue level.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
drivers/usb/dwc3/dwc3-generic.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 7be0187..6d9be9b 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -8,6 +8,7 @@ */
#include <common.h> +#include <asm-generic/io.h> #include <dm.h> #include <dm/device-internal.h> #include <dm/lists.h> @@ -110,6 +111,12 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = { struct dwc3_glue_data { struct clk_bulk clks; struct reset_ctl_bulk resets; + fdt_addr_t regs; +}; + +struct dwc3_glue_ops { + void (*select_dr_mode)(struct udevice *dev, int index, + enum usb_dr_mode mode); };
static int dwc3_glue_bind(struct udevice *parent) @@ -205,9 +212,14 @@ static int dwc3_glue_clk_init(struct udevice *dev,
static int dwc3_glue_probe(struct udevice *dev) { + struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(dev); struct dwc3_glue_data *glue = dev_get_platdata(dev); + struct udevice *child = NULL; + int index = 0; int ret;
+ glue->regs = dev_read_addr(dev); + ret = dwc3_glue_clk_init(dev, glue); if (ret) return ret; @@ -216,6 +228,20 @@ static int dwc3_glue_probe(struct udevice *dev) if (ret) return ret;
+ ret = device_find_first_child(dev, &child); + if (ret) + return ret; + + while (child) { + enum usb_dr_mode dr_mode; + + dr_mode = usb_get_dr_mode(dev_of_offset(child)); + device_find_next_child(&child); + if (ops && ops->select_dr_mode) + ops->select_dr_mode(dev, index, dr_mode); + index++; + } + return 0; }

The error is: In file included from include/part.h:10:0, from include/usb.h:18, from include/linux/usb/gadget.h:22, from drivers/usb/dwc3/ep0.c:20: include/ide.h:62:14: error: unknown type name ‘uchar’ void ide_led(uchar led, uchar status);
Fixing it by including common.h that defines the uchar type.
Signed-off-by: Jean-Jacques Hiblot jjhiblot@ti.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
drivers/usb/dwc3/ep0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 4f68887..818efb3 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -12,7 +12,7 @@ * * commit c00552ebaf : Merge 3.18-rc7 into usb-next */ - +#include <common.h> #include <linux/kernel.h> #include <linux/list.h>

Hi,
I re-tested this series on Khadas VIM1 and it still fix the USB issue I had with 'usb reset' (I already tested v2 patches).
I just have a message and I'm not sure that I had it last time: "Error disabling PHY supply Can't shutdown USB PHY1 for dwc3@c9000000"
But USB stack looks ok, I can plug/unplug USB key and do the reset, all works as expected.
Since my last test lot of changes has been done in Amlogic SoCs, maybe it's because of this?
So if you want you can add my tested-by flag. Tested-by: Loic Devulder ldevulder@suse.de
On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote:
This series aims at bringing improvements to the dwc3_generic driver so that it can be used by most of the platforms using the dwc3 controller.
I tested this on with DRA7 and AM57x platforms for both Peripheral and Host operations. The code to enable DM USB host & dev support for those platforms will be submitted in a separate series.
Michal Simek has tested this series: " I have tested it on zcu100 with usb stick, usb to ethernet converter and also dfu. Tested-by: Michal Simek michal.simek@xilinx.com"
Enhancements:
- use separate Kconfig option for DM USB Periphal and DM USB Host. This
allow platforms to keep their non-DM USB peripheral code and use the DM USB host.
- fixes the bind/probe confusion in dwc3_generic. The probe is done when
the USB device is first needed.
- handles PHYs when in the peripheral mode. The code to handle the PHYs is
shared with the host side
- handles clock and reset
- bind host controller to the more generic driver 'xhci-dwc3'
Changes in v4:
- rebased on latest U-Boot
- renamed DM_USB_DEV as DM_USB_GADGET
- Add a new commit to create a new UCLASS for USB gadget drivers
Changes in v3:
- fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. This was visible only when the device is removed.
- Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is false. This fixes all build issues but one (evb-rk3328).
- Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2:
- Updated commit log
- Fixed typo in thordown.c
- select DM_USB_DEV by default for zynqmp platforms
Jean-Jacques Hiblot (10): usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers usb: introduce a separate config option for DM USB device usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() dwc3_generic: do not probe the USB device driver when it's bound dwc3: move phy operation to core.c dm: usb: create a new UCLASS ID for USB gadget devices configs: evb-rk3328: Enable CONFIG_USB_DWC3 dwc3-generic: Handle the PHYs, the clocks and the reset lines dwc3-generic: Add select_dr_mode operation usb: dwc3: Fix a compilation error with the edison defconfig
arch/arm/Kconfig | 2 + board/sunxi/board.c | 2 +- cmd/fastboot.c | 4 +- cmd/rockusb.c | 4 +- cmd/thordown.c | 4 +- cmd/usb_gadget_sdp.c | 4 +- cmd/usb_mass_storage.c | 4 +- common/dfu.c | 6 +- configs/evb-rk3328_defconfig | 1 + drivers/usb/Kconfig | 14 +++ drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 89 ++++++++++++++- drivers/usb/dwc3/dwc3-generic.c | 208 ++++++++++++++++++++++++++++-------- drivers/usb/dwc3/ep0.c | 2 +- drivers/usb/gadget/ether.c | 40 ++----- drivers/usb/gadget/udc/Makefile | 4 + drivers/usb/gadget/udc/udc-core.c | 3 +- drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ drivers/usb/host/xhci-dwc3.c | 95 ++-------------- drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + include/dwc3-uboot.h | 19 ++++ include/linux/usb/gadget.h | 18 ++++ 24 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c

On 06/12/2018 21:56, Loic Devulder wrote:
Hi,
I re-tested this series on Khadas VIM1 and it still fix the USB issue I had with 'usb reset' (I already tested v2 patches).
I just have a message and I'm not sure that I had it last time: "Error disabling PHY supply Can't shutdown USB PHY1 for dwc3@c9000000"
But USB stack looks ok, I can plug/unplug USB key and do the reset, all works as expected.
Since my last test lot of changes has been done in Amlogic SoCs, maybe it's because of this?
So if you want you can add my tested-by flag. Tested-by: Loic Devulder ldevulder@suse.de
Thank you for testing
On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote:
This series aims at bringing improvements to the dwc3_generic driver so that it can be used by most of the platforms using the dwc3 controller.
I tested this on with DRA7 and AM57x platforms for both Peripheral and Host operations. The code to enable DM USB host & dev support for those platforms will be submitted in a separate series.
Michal Simek has tested this series: " I have tested it on zcu100 with usb stick, usb to ethernet converter and also dfu. Tested-by: Michal Simek michal.simek@xilinx.com"
Enhancements:
- use separate Kconfig option for DM USB Periphal and DM USB Host. This
allow platforms to keep their non-DM USB peripheral code and use the DM USB host.
- fixes the bind/probe confusion in dwc3_generic. The probe is done when
the USB device is first needed.
- handles PHYs when in the peripheral mode. The code to handle the PHYs is
shared with the host side
- handles clock and reset
- bind host controller to the more generic driver 'xhci-dwc3'
Changes in v4:
- rebased on latest U-Boot
- renamed DM_USB_DEV as DM_USB_GADGET
- Add a new commit to create a new UCLASS for USB gadget drivers
Changes in v3:
- fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. This was visible only when the device is removed.
- Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is false. This fixes all build issues but one (evb-rk3328).
- Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2:
- Updated commit log
- Fixed typo in thordown.c
- select DM_USB_DEV by default for zynqmp platforms
Jean-Jacques Hiblot (10): usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers usb: introduce a separate config option for DM USB device usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() dwc3_generic: do not probe the USB device driver when it's bound dwc3: move phy operation to core.c dm: usb: create a new UCLASS ID for USB gadget devices configs: evb-rk3328: Enable CONFIG_USB_DWC3 dwc3-generic: Handle the PHYs, the clocks and the reset lines dwc3-generic: Add select_dr_mode operation usb: dwc3: Fix a compilation error with the edison defconfig
arch/arm/Kconfig | 2 + board/sunxi/board.c | 2 +- cmd/fastboot.c | 4 +- cmd/rockusb.c | 4 +- cmd/thordown.c | 4 +- cmd/usb_gadget_sdp.c | 4 +- cmd/usb_mass_storage.c | 4 +- common/dfu.c | 6 +- configs/evb-rk3328_defconfig | 1 + drivers/usb/Kconfig | 14 +++ drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 89 ++++++++++++++- drivers/usb/dwc3/dwc3-generic.c | 208 ++++++++++++++++++++++++++++-------- drivers/usb/dwc3/ep0.c | 2 +- drivers/usb/gadget/ether.c | 40 ++----- drivers/usb/gadget/udc/Makefile | 4 + drivers/usb/gadget/udc/udc-core.c | 3 +- drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ drivers/usb/host/xhci-dwc3.c | 95 ++-------------- drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + include/dwc3-uboot.h | 19 ++++ include/linux/usb/gadget.h | 18 ++++ 24 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c

On Fri, Dec 7, 2018 at 8:46 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 06/12/2018 21:56, Loic Devulder wrote:
Hi,
I re-tested this series on Khadas VIM1 and it still fix the USB issue I had with 'usb reset' (I already tested v2 patches).
I just have a message and I'm not sure that I had it last time: "Error disabling PHY supply Can't shutdown USB PHY1 for dwc3@c9000000"
But USB stack looks ok, I can plug/unplug USB key and do the reset, all works as expected.
Since my last test lot of changes has been done in Amlogic SoCs, maybe it's because of this?
So if you want you can add my tested-by flag. Tested-by: Loic Devulder ldevulder@suse.de
Thank you for testing
On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote:
This series aims at bringing improvements to the dwc3_generic driver so that it can be used by most of the platforms using the dwc3 controller.
I tested this on with DRA7 and AM57x platforms for both Peripheral and Host operations. The code to enable DM USB host & dev support for those platforms will be submitted in a separate series.
Michal Simek has tested this series: " I have tested it on zcu100 with usb stick, usb to ethernet converter and also dfu. Tested-by: Michal Simek michal.simek@xilinx.com"
Enhancements:
- use separate Kconfig option for DM USB Periphal and DM USB Host. This
allow platforms to keep their non-DM USB peripheral code and use the DM USB host.
- fixes the bind/probe confusion in dwc3_generic. The probe is done when
the USB device is first needed.
- handles PHYs when in the peripheral mode. The code to handle the PHYs is
shared with the host side
- handles clock and reset
- bind host controller to the more generic driver 'xhci-dwc3'
Changes in v4:
- rebased on latest U-Boot
- renamed DM_USB_DEV as DM_USB_GADGET
- Add a new commit to create a new UCLASS for USB gadget drivers
Changes in v3:
- fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. This was visible only when the device is removed.
- Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is false. This fixes all build issues but one (evb-rk3328).
- Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2:
- Updated commit log
- Fixed typo in thordown.c
- select DM_USB_DEV by default for zynqmp platforms
Jean-Jacques Hiblot (10): usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers usb: introduce a separate config option for DM USB device usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() dwc3_generic: do not probe the USB device driver when it's bound dwc3: move phy operation to core.c dm: usb: create a new UCLASS ID for USB gadget devices configs: evb-rk3328: Enable CONFIG_USB_DWC3 dwc3-generic: Handle the PHYs, the clocks and the reset lines dwc3-generic: Add select_dr_mode operation usb: dwc3: Fix a compilation error with the edison defconfig
arch/arm/Kconfig | 2 + board/sunxi/board.c | 2 +- cmd/fastboot.c | 4 +- cmd/rockusb.c | 4 +- cmd/thordown.c | 4 +- cmd/usb_gadget_sdp.c | 4 +- cmd/usb_mass_storage.c | 4 +- common/dfu.c | 6 +- configs/evb-rk3328_defconfig | 1 + drivers/usb/Kconfig | 14 +++ drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 89 ++++++++++++++- drivers/usb/dwc3/dwc3-generic.c | 208 ++++++++++++++++++++++++++++-------- drivers/usb/dwc3/ep0.c | 2 +- drivers/usb/gadget/ether.c | 40 ++----- drivers/usb/gadget/udc/Makefile | 4 + drivers/usb/gadget/udc/udc-core.c | 3 +- drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ drivers/usb/host/xhci-dwc3.c | 95 ++-------------- drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + include/dwc3-uboot.h | 19 ++++ include/linux/usb/gadget.h | 18 ++++ 24 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
First off thanks for the work. I have imported it into my u-boot tree for the iMX8M and now have both usb host and gadget mode working simultaneously. There is one catch. Currently, the iMX8M codebase does not support clock and power device initialization from DM. I have patched the driver to punt back to the board to do these initializations in the following patch. Yes I know not ideal, but functional. I am wondering if we should support architecture specific implementation quirks for boards that don't fully support DM initialization yet. I am open to writing something more complete if we decide it is something worth pursuing, otherwise I will carry this patch in my tree for time being.
-Jon
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 6d9be9b245..90d4ff2ea7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -119,6 +119,15 @@ struct dwc3_glue_ops { enum usb_dr_mode mode); };
+__weak int board_usb_of_init(struct udevice *dev) +{ + return 0; +} + +__weak void board_usb_of_cleanup(struct udevice *dev) +{ +} + static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob; @@ -242,6 +251,8 @@ static int dwc3_glue_probe(struct udevice *dev) index++; }
+ ret = board_usb_of_init(dev); + return 0; }
@@ -249,6 +260,8 @@ static int dwc3_glue_remove(struct udevice *dev) { struct dwc3_glue_data *glue = dev_get_platdata(dev);
+ board_usb_of_cleanup(dev); + reset_release_bulk(&glue->resets);
clk_release_bulk(&glue->clks); @@ -257,6 +270,7 @@ static int dwc3_glue_remove(struct udevice *dev) }

On 04/01/2019 08:05, Jon Nettleton wrote:
On Fri, Dec 7, 2018 at 8:46 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 06/12/2018 21:56, Loic Devulder wrote:
Hi,
I re-tested this series on Khadas VIM1 and it still fix the USB issue I had with 'usb reset' (I already tested v2 patches).
I just have a message and I'm not sure that I had it last time: "Error disabling PHY supply Can't shutdown USB PHY1 for dwc3@c9000000"
But USB stack looks ok, I can plug/unplug USB key and do the reset, all works as expected.
Since my last test lot of changes has been done in Amlogic SoCs, maybe it's because of this?
So if you want you can add my tested-by flag. Tested-by: Loic Devulder ldevulder@suse.de
Thank you for testing
On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote:
This series aims at bringing improvements to the dwc3_generic driver so that it can be used by most of the platforms using the dwc3 controller.
I tested this on with DRA7 and AM57x platforms for both Peripheral and Host operations. The code to enable DM USB host & dev support for those platforms will be submitted in a separate series.
Michal Simek has tested this series: " I have tested it on zcu100 with usb stick, usb to ethernet converter and also dfu. Tested-by: Michal Simek michal.simek@xilinx.com"
Enhancements:
- use separate Kconfig option for DM USB Periphal and DM USB Host. This
allow platforms to keep their non-DM USB peripheral code and use the DM USB host.
- fixes the bind/probe confusion in dwc3_generic. The probe is done when
the USB device is first needed.
- handles PHYs when in the peripheral mode. The code to handle the PHYs is
shared with the host side
- handles clock and reset
- bind host controller to the more generic driver 'xhci-dwc3'
Changes in v4:
- rebased on latest U-Boot
- renamed DM_USB_DEV as DM_USB_GADGET
- Add a new commit to create a new UCLASS for USB gadget drivers
Changes in v3:
- fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. This was visible only when the device is removed.
- Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is false. This fixes all build issues but one (evb-rk3328).
- Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2:
- Updated commit log
- Fixed typo in thordown.c
- select DM_USB_DEV by default for zynqmp platforms
Jean-Jacques Hiblot (10): usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers usb: introduce a separate config option for DM USB device usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() dwc3_generic: do not probe the USB device driver when it's bound dwc3: move phy operation to core.c dm: usb: create a new UCLASS ID for USB gadget devices configs: evb-rk3328: Enable CONFIG_USB_DWC3 dwc3-generic: Handle the PHYs, the clocks and the reset lines dwc3-generic: Add select_dr_mode operation usb: dwc3: Fix a compilation error with the edison defconfig
arch/arm/Kconfig | 2 + board/sunxi/board.c | 2 +- cmd/fastboot.c | 4 +- cmd/rockusb.c | 4 +- cmd/thordown.c | 4 +- cmd/usb_gadget_sdp.c | 4 +- cmd/usb_mass_storage.c | 4 +- common/dfu.c | 6 +- configs/evb-rk3328_defconfig | 1 + drivers/usb/Kconfig | 14 +++ drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 89 ++++++++++++++- drivers/usb/dwc3/dwc3-generic.c | 208 ++++++++++++++++++++++++++++-------- drivers/usb/dwc3/ep0.c | 2 +- drivers/usb/gadget/ether.c | 40 ++----- drivers/usb/gadget/udc/Makefile | 4 + drivers/usb/gadget/udc/udc-core.c | 3 +- drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ drivers/usb/host/xhci-dwc3.c | 95 ++-------------- drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + include/dwc3-uboot.h | 19 ++++ include/linux/usb/gadget.h | 18 ++++ 24 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
First off thanks for the work. I have imported it into my u-boot tree for the iMX8M and now have both usb host and gadget mode working simultaneously. There is one catch. Currently, the iMX8M codebase does not support clock and power device initialization from DM. I have patched the driver to punt back to the board to do these initializations in the following patch. Yes I know not ideal, but functional. I am wondering if we should support architecture specific implementation quirks for boards that don't fully support DM initialization yet.
That is not fitting the DM model. I had the same issue and finally enabled the clocks in the board_late_init(): board/ti/dra7xx/evm.c:662:int board_late_init(void)
I am open to writing something more complete if we decide it is something worth pursuing, otherwise I will carry this patch in my tree for time being.
The true solution would be to implement the support for clk.
-Jon
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 6d9be9b245..90d4ff2ea7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -119,6 +119,15 @@ struct dwc3_glue_ops { enum usb_dr_mode mode); };
+__weak int board_usb_of_init(struct udevice *dev) +{
return 0;
+}
+__weak void board_usb_of_cleanup(struct udevice *dev) +{ +}
- static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob;
@@ -242,6 +251,8 @@ static int dwc3_glue_probe(struct udevice *dev) index++; }
ret = board_usb_of_init(dev);
}return 0;
@@ -249,6 +260,8 @@ static int dwc3_glue_remove(struct udevice *dev) { struct dwc3_glue_data *glue = dev_get_platdata(dev);
board_usb_of_cleanup(dev);
reset_release_bulk(&glue->resets); clk_release_bulk(&glue->clks);
@@ -257,6 +270,7 @@ static int dwc3_glue_remove(struct udevice *dev) }

Hi Jean-Jacques,
On 04/01/2019 08:05, Jon Nettleton wrote:
On Fri, Dec 7, 2018 at 8:46 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 06/12/2018 21:56, Loic Devulder wrote:
Hi,
I re-tested this series on Khadas VIM1 and it still fix the USB issue I had with 'usb reset' (I already tested v2 patches).
I just have a message and I'm not sure that I had it last time: "Error disabling PHY supply Can't shutdown USB PHY1 for dwc3@c9000000"
But USB stack looks ok, I can plug/unplug USB key and do the reset, all works as expected.
Since my last test lot of changes has been done in Amlogic SoCs, maybe it's because of this?
So if you want you can add my tested-by flag. Tested-by: Loic Devulder ldevulder@suse.de
Thank you for testing
On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote:
This series aims at bringing improvements to the dwc3_generic driver so that it can be used by most of the platforms using the dwc3 controller.
I tested this on with DRA7 and AM57x platforms for both Peripheral and Host operations. The code to enable DM USB host & dev support for those platforms will be submitted in a separate series.
Michal Simek has tested this series: " I have tested it on zcu100 with usb stick, usb to ethernet converter and also dfu. Tested-by: Michal Simek michal.simek@xilinx.com"
Enhancements:
- use separate Kconfig option for DM USB Periphal and DM USB
Host. This allow platforms to keep their non-DM USB peripheral code and use the DM USB host.
- fixes the bind/probe confusion in dwc3_generic. The probe is
done when the USB device is first needed.
- handles PHYs when in the peripheral mode. The code to handle
the PHYs is shared with the host side
- handles clock and reset
- bind host controller to the more generic driver 'xhci-dwc3'
Changes in v4:
- rebased on latest U-Boot
- renamed DM_USB_DEV as DM_USB_GADGET
- Add a new commit to create a new UCLASS for USB gadget drivers
Changes in v3:
- fixes bug dwc3_setup_phy(): the phy arrays wasn't returned.
This was visible only when the device is removed.
- Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is
false. This fixes all build issues but one (evb-rk3328).
- Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3.
This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2:
- Updated commit log
- Fixed typo in thordown.c
- select DM_USB_DEV by default for zynqmp platforms
Jean-Jacques Hiblot (10): usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers usb: introduce a separate config option for DM USB device usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() dwc3_generic: do not probe the USB device driver when it's bound dwc3: move phy operation to core.c dm: usb: create a new UCLASS ID for USB gadget devices configs: evb-rk3328: Enable CONFIG_USB_DWC3 dwc3-generic: Handle the PHYs, the clocks and the reset lines dwc3-generic: Add select_dr_mode operation usb: dwc3: Fix a compilation error with the edison defconfig
arch/arm/Kconfig | 2 + board/sunxi/board.c | 2 +- cmd/fastboot.c | 4 +- cmd/rockusb.c | 4 +- cmd/thordown.c | 4 +- cmd/usb_gadget_sdp.c | 4 +- cmd/usb_mass_storage.c | 4 +- common/dfu.c | 6 +- configs/evb-rk3328_defconfig | 1 + drivers/usb/Kconfig | 14 +++ drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 89 ++++++++++++++- drivers/usb/dwc3/dwc3-generic.c | 208 ++++++++++++++++++++++++++++-------- drivers/usb/dwc3/ep0.c | 2 +- drivers/usb/gadget/ether.c | 40 ++----- drivers/usb/gadget/udc/Makefile | 4 + drivers/usb/gadget/udc/udc-core.c | 3 +- drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ drivers/usb/host/xhci-dwc3.c | 95 ++-------------- drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + include/dwc3-uboot.h | 19 ++++ include/linux/usb/gadget.h | 18 ++++ 24 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
First off thanks for the work. I have imported it into my u-boot tree for the iMX8M and now have both usb host and gadget mode working simultaneously. There is one catch. Currently, the iMX8M codebase does not support clock and power device initialization from DM. I have patched the driver to punt back to the board to do these initializations in the following patch. Yes I know not ideal, but functional. I am wondering if we should support architecture specific implementation quirks for boards that don't fully support DM initialization yet.
That is not fitting the DM model. I had the same issue and finally enabled the clocks in the board_late_init(): board/ti/dra7xx/evm.c:662:int board_late_init(void)
I am open to writing something more complete if we decide it is something worth pursuing, otherwise I will carry this patch in my tree for time being.
The true solution would be to implement the support for clk.
Many other people on the ML (including me) see the urgent need to implement the DM_CLK for e.g. imx6/5/7/8, etc.
I think that it would be best to add it clock by clock. The stubs in board code/files is a dead end, IMHO.
-Jon
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 6d9be9b245..90d4ff2ea7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -119,6 +119,15 @@ struct dwc3_glue_ops { enum usb_dr_mode mode); };
+__weak int board_usb_of_init(struct udevice *dev) +{
return 0;
+}
+__weak void board_usb_of_cleanup(struct udevice *dev) +{ +}
- static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob;
@@ -242,6 +251,8 @@ static int dwc3_glue_probe(struct udevice *dev) index++; }
ret = board_usb_of_init(dev);
}return 0;
@@ -249,6 +260,8 @@ static int dwc3_glue_remove(struct udevice *dev) { struct dwc3_glue_data *glue = dev_get_platdata(dev);
board_usb_of_cleanup(dev);
reset_release_bulk(&glue->resets); clk_release_bulk(&glue->clks);
@@ -257,6 +270,7 @@ static int dwc3_glue_remove(struct udevice *dev) }
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

On 04/01/2019 11:19, Lukasz Majewski wrote:
Hi Jean-Jacques,
On 04/01/2019 08:05, Jon Nettleton wrote:
On Fri, Dec 7, 2018 at 8:46 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 06/12/2018 21:56, Loic Devulder wrote:
Hi,
I re-tested this series on Khadas VIM1 and it still fix the USB issue I had with 'usb reset' (I already tested v2 patches).
I just have a message and I'm not sure that I had it last time: "Error disabling PHY supply Can't shutdown USB PHY1 for dwc3@c9000000"
But USB stack looks ok, I can plug/unplug USB key and do the reset, all works as expected.
Since my last test lot of changes has been done in Amlogic SoCs, maybe it's because of this?
So if you want you can add my tested-by flag. Tested-by: Loic Devulder ldevulder@suse.de
Thank you for testing
On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote:
This series aims at bringing improvements to the dwc3_generic driver so that it can be used by most of the platforms using the dwc3 controller.
I tested this on with DRA7 and AM57x platforms for both Peripheral and Host operations. The code to enable DM USB host & dev support for those platforms will be submitted in a separate series.
Michal Simek has tested this series: " I have tested it on zcu100 with usb stick, usb to ethernet converter and also dfu. Tested-by: Michal Simek michal.simek@xilinx.com"
Enhancements:
- use separate Kconfig option for DM USB Periphal and DM USB
Host. This allow platforms to keep their non-DM USB peripheral code and use the DM USB host.
- fixes the bind/probe confusion in dwc3_generic. The probe is
done when the USB device is first needed.
- handles PHYs when in the peripheral mode. The code to handle
the PHYs is shared with the host side
- handles clock and reset
- bind host controller to the more generic driver 'xhci-dwc3'
Changes in v4:
- rebased on latest U-Boot
- renamed DM_USB_DEV as DM_USB_GADGET
- Add a new commit to create a new UCLASS for USB gadget drivers
Changes in v3:
- fixes bug dwc3_setup_phy(): the phy arrays wasn't returned.
This was visible only when the device is removed.
- Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is
false. This fixes all build issues but one (evb-rk3328).
- Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3.
This has little impact on the footprint and should not break the runtime as the xhci-rockchip driver has its own probe function. Nevertheless this was !!! NOT TESTED !!! by lack of hw
Changes in v2:
- Updated commit log
- Fixed typo in thordown.c
- select DM_USB_DEV by default for zynqmp platforms
Jean-Jacques Hiblot (10): usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers usb: introduce a separate config option for DM USB device usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() dwc3_generic: do not probe the USB device driver when it's bound dwc3: move phy operation to core.c dm: usb: create a new UCLASS ID for USB gadget devices configs: evb-rk3328: Enable CONFIG_USB_DWC3 dwc3-generic: Handle the PHYs, the clocks and the reset lines dwc3-generic: Add select_dr_mode operation usb: dwc3: Fix a compilation error with the edison defconfig
arch/arm/Kconfig | 2 + board/sunxi/board.c | 2 +- cmd/fastboot.c | 4 +- cmd/rockusb.c | 4 +- cmd/thordown.c | 4 +- cmd/usb_gadget_sdp.c | 4 +- cmd/usb_mass_storage.c | 4 +- common/dfu.c | 6 +- configs/evb-rk3328_defconfig | 1 + drivers/usb/Kconfig | 14 +++ drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 89 ++++++++++++++- drivers/usb/dwc3/dwc3-generic.c | 208
++++++++++++++++++++++++++++-------- drivers/usb/dwc3/ep0.c | 2 +- drivers/usb/gadget/ether.c | 40 ++----- drivers/usb/gadget/udc/Makefile | 4 + drivers/usb/gadget/udc/udc-core.c | 3 +- drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ drivers/usb/host/xhci-dwc3.c | 95 ++-------------- drivers/usb/musb-new/omap2430.c | 2 +- drivers/usb/musb-new/sunxi.c | 2 +- include/dm/uclass-id.h | 1 + include/dwc3-uboot.h | 19 ++++ include/linux/usb/gadget.h | 18 ++++ 24 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 drivers/usb/gadget/udc/udc-uclass.c
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
First off thanks for the work. I have imported it into my u-boot tree for the iMX8M and now have both usb host and gadget mode working simultaneously. There is one catch. Currently, the iMX8M codebase does not support clock and power device initialization from DM. I have patched the driver to punt back to the board to do these initializations in the following patch. Yes I know not ideal, but functional. I am wondering if we should support architecture specific implementation quirks for boards that don't fully support DM initialization yet.
That is not fitting the DM model. I had the same issue and finally enabled the clocks in the board_late_init(): board/ti/dra7xx/evm.c:662:int board_late_init(void)
I am open to writing something more complete if we decide it is something worth pursuing, otherwise I will carry this patch in my tree for time being.
The true solution would be to implement the support for clk.
Many other people on the ML (including me) see the urgent need to implement the DM_CLK for e.g. imx6/5/7/8, etc.
I think that it would be best to add it clock by clock. The stubs in board code/files is a dead end, IMHO.
I agree 100%.
We had a similar discussion for the TI platforms, but due to the specific design of the TI power/clk in Linux (hwmod), we chose to keep the clocks handling in the board file at the moment.
-Jon
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 6d9be9b245..90d4ff2ea7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -119,6 +119,15 @@ struct dwc3_glue_ops { enum usb_dr_mode mode); };
+__weak int board_usb_of_init(struct udevice *dev) +{
return 0;
+}
+__weak void board_usb_of_cleanup(struct udevice *dev) +{ +}
- static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob;
@@ -242,6 +251,8 @@ static int dwc3_glue_probe(struct udevice *dev) index++; }
ret = board_usb_of_init(dev);
}return 0;
@@ -249,6 +260,8 @@ static int dwc3_glue_remove(struct udevice *dev) { struct dwc3_glue_data *glue = dev_get_platdata(dev);
board_usb_of_cleanup(dev);
reset_release_bulk(&glue->resets); clk_release_bulk(&glue->clks);
@@ -257,6 +270,7 @@ static int dwc3_glue_remove(struct udevice *dev) }
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

On Fri, Jan 4, 2019 at 11:25 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 04/01/2019 11:19, Lukasz Majewski wrote:
Hi Jean-Jacques,
On 04/01/2019 08:05, Jon Nettleton wrote:
On Fri, Dec 7, 2018 at 8:46 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 06/12/2018 21:56, Loic Devulder wrote:
Hi,
I re-tested this series on Khadas VIM1 and it still fix the USB issue I had with 'usb reset' (I already tested v2 patches).
I just have a message and I'm not sure that I had it last time: "Error disabling PHY supply Can't shutdown USB PHY1 for dwc3@c9000000"
But USB stack looks ok, I can plug/unplug USB key and do the reset, all works as expected.
Since my last test lot of changes has been done in Amlogic SoCs, maybe it's because of this?
So if you want you can add my tested-by flag. Tested-by: Loic Devulder ldevulder@suse.de
Thank you for testing
On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote: > This series aims at bringing improvements to the dwc3_generic > driver so that it can be used by most of the platforms using the > dwc3 controller. > > I tested this on with DRA7 and AM57x platforms for both > Peripheral and Host operations. The code to enable DM USB host & > dev support for those platforms will be submitted in a separate > series. > > Michal Simek has tested this series: > " I have tested it on zcu100 with usb stick, usb to ethernet > converter and also dfu. > Tested-by: Michal Simek michal.simek@xilinx.com" > > Enhancements: > - use separate Kconfig option for DM USB Periphal and DM USB > Host. This allow platforms to keep their non-DM USB peripheral > code and use the DM USB host. > - fixes the bind/probe confusion in dwc3_generic. The probe is > done when the USB device is first needed. > - handles PHYs when in the peripheral mode. The code to handle > the PHYs is shared with the host side > - handles clock and reset > - bind host controller to the more generic driver 'xhci-dwc3' > > > Changes in v4: > - rebased on latest U-Boot > - renamed DM_USB_DEV as DM_USB_GADGET > - Add a new commit to create a new UCLASS for USB gadget drivers > > Changes in v3: > - fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. > This was visible only when the device is removed. > - Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is > false. This fixes all build issues but one (evb-rk3328). > - Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. > This has little impact on the footprint and should not break the > runtime as the xhci-rockchip driver has its own probe function. > Nevertheless this was !!! NOT TESTED !!! by lack of hw > > Changes in v2: > - Updated commit log > - Fixed typo in thordown.c > - select DM_USB_DEV by default for zynqmp platforms > > Jean-Jacques Hiblot (10): > usb: gadget: Do not call board_usb_xxx() directly in USB > gadget drivers > usb: introduce a separate config option for DM USB device > usb: udc: implement DM versions of > usb_gadget_initialize()/_release()/_handle_interrupt() > dwc3_generic: do not probe the USB device driver when it's > bound dwc3: move phy operation to core.c > dm: usb: create a new UCLASS ID for USB gadget devices > configs: evb-rk3328: Enable CONFIG_USB_DWC3 > dwc3-generic: Handle the PHYs, the clocks and the reset lines > dwc3-generic: Add select_dr_mode operation > usb: dwc3: Fix a compilation error with the edison defconfig > > arch/arm/Kconfig | 2 + > board/sunxi/board.c | 2 +- > cmd/fastboot.c | 4 +- > cmd/rockusb.c | 4 +- > cmd/thordown.c | 4 +- > cmd/usb_gadget_sdp.c | 4 +- > cmd/usb_mass_storage.c | 4 +- > common/dfu.c | 6 +- > configs/evb-rk3328_defconfig | 1 + > drivers/usb/Kconfig | 14 +++ > drivers/usb/dwc3/Kconfig | 7 +- > drivers/usb/dwc3/core.c | 89 ++++++++++++++- > drivers/usb/dwc3/dwc3-generic.c | 208 > ++++++++++++++++++++++++++++-------- > drivers/usb/dwc3/ep0.c | 2 +- > drivers/usb/gadget/ether.c | 40 ++----- > drivers/usb/gadget/udc/Makefile | 4 + > drivers/usb/gadget/udc/udc-core.c | 3 +- > drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ > drivers/usb/host/xhci-dwc3.c | 95 ++-------------- > drivers/usb/musb-new/omap2430.c | 2 +- > drivers/usb/musb-new/sunxi.c | 2 +- > include/dm/uclass-id.h | 1 + > include/dwc3-uboot.h | 19 ++++ > include/linux/usb/gadget.h | 18 ++++ 24 files changed, > 401 insertions(+), 192 deletions(-) create mode 100644 > drivers/usb/gadget/udc/udc-uclass.c
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
First off thanks for the work. I have imported it into my u-boot tree for the iMX8M and now have both usb host and gadget mode working simultaneously. There is one catch. Currently, the iMX8M codebase does not support clock and power device initialization from DM. I have patched the driver to punt back to the board to do these initializations in the following patch. Yes I know not ideal, but functional. I am wondering if we should support architecture specific implementation quirks for boards that don't fully support DM initialization yet.
That is not fitting the DM model. I had the same issue and finally enabled the clocks in the board_late_init(): board/ti/dra7xx/evm.c:662:int board_late_init(void)
I am open to writing something more complete if we decide it is something worth pursuing, otherwise I will carry this patch in my tree for time being.
The true solution would be to implement the support for clk.
Many other people on the ML (including me) see the urgent need to implement the DM_CLK for e.g. imx6/5/7/8, etc.
I think that it would be best to add it clock by clock. The stubs in board code/files is a dead end, IMHO.
I agree 100%.
We had a similar discussion for the TI platforms, but due to the specific design of the TI power/clk in Linux (hwmod), we chose to keep the clocks handling in the board file at the moment.
-Jon
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 6d9be9b245..90d4ff2ea7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -119,6 +119,15 @@ struct dwc3_glue_ops { enum usb_dr_mode mode); };
+__weak int board_usb_of_init(struct udevice *dev) +{
return 0;
+}
+__weak void board_usb_of_cleanup(struct udevice *dev) +{ +}
- static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob;
@@ -242,6 +251,8 @@ static int dwc3_glue_probe(struct udevice *dev) index++; }
ret = board_usb_of_init(dev);
}return 0;
@@ -249,6 +260,8 @@ static int dwc3_glue_remove(struct udevice *dev) { struct dwc3_glue_data *glue = dev_get_platdata(dev);
board_usb_of_cleanup(dev);
reset_release_bulk(&glue->resets); clk_release_bulk(&glue->clks);
@@ -257,6 +270,7 @@ static int dwc3_glue_remove(struct udevice *dev) }
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Obviously the proper solution is implementing a proper DM clk driver. I generally refrain from just enabling a bunch of clocks and code in our board file, since our devices are SOM + carrier, and many customers design their own boards and then continue to use our bootloader. I am fine carrying the patch until we have the time to build the proper infrastructure in mainline.

On Fri, Jan 4, 2019 at 12:22 PM Jon Nettleton jon@solid-run.com wrote:
On Fri, Jan 4, 2019 at 11:25 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 04/01/2019 11:19, Lukasz Majewski wrote:
Hi Jean-Jacques,
On 04/01/2019 08:05, Jon Nettleton wrote:
On Fri, Dec 7, 2018 at 8:46 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 06/12/2018 21:56, Loic Devulder wrote: > Hi, > > I re-tested this series on Khadas VIM1 and it still fix the USB > issue I had with 'usb reset' (I already tested v2 patches). > > I just have a message and I'm not sure that I had it last time: > "Error disabling PHY supply > Can't shutdown USB PHY1 for dwc3@c9000000" > > But USB stack looks ok, I can plug/unplug USB key and do the > reset, all works as expected. > > Since my last test lot of changes has been done in Amlogic SoCs, > maybe it's because of this? > > So if you want you can add my tested-by flag. > Tested-by: Loic Devulder ldevulder@suse.de Thank you for testing > On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote: >> This series aims at bringing improvements to the dwc3_generic >> driver so that it can be used by most of the platforms using the >> dwc3 controller. >> >> I tested this on with DRA7 and AM57x platforms for both >> Peripheral and Host operations. The code to enable DM USB host & >> dev support for those platforms will be submitted in a separate >> series. >> >> Michal Simek has tested this series: >> " I have tested it on zcu100 with usb stick, usb to ethernet >> converter and also dfu. >> Tested-by: Michal Simek michal.simek@xilinx.com" >> >> Enhancements: >> - use separate Kconfig option for DM USB Periphal and DM USB >> Host. This allow platforms to keep their non-DM USB peripheral >> code and use the DM USB host. >> - fixes the bind/probe confusion in dwc3_generic. The probe is >> done when the USB device is first needed. >> - handles PHYs when in the peripheral mode. The code to handle >> the PHYs is shared with the host side >> - handles clock and reset >> - bind host controller to the more generic driver 'xhci-dwc3' >> >> >> Changes in v4: >> - rebased on latest U-Boot >> - renamed DM_USB_DEV as DM_USB_GADGET >> - Add a new commit to create a new UCLASS for USB gadget drivers >> >> Changes in v3: >> - fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. >> This was visible only when the device is removed. >> - Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is >> false. This fixes all build issues but one (evb-rk3328). >> - Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. >> This has little impact on the footprint and should not break the >> runtime as the xhci-rockchip driver has its own probe function. >> Nevertheless this was !!! NOT TESTED !!! by lack of hw >> >> Changes in v2: >> - Updated commit log >> - Fixed typo in thordown.c >> - select DM_USB_DEV by default for zynqmp platforms >> >> Jean-Jacques Hiblot (10): >> usb: gadget: Do not call board_usb_xxx() directly in USB >> gadget drivers >> usb: introduce a separate config option for DM USB device >> usb: udc: implement DM versions of >> usb_gadget_initialize()/_release()/_handle_interrupt() >> dwc3_generic: do not probe the USB device driver when it's >> bound dwc3: move phy operation to core.c >> dm: usb: create a new UCLASS ID for USB gadget devices >> configs: evb-rk3328: Enable CONFIG_USB_DWC3 >> dwc3-generic: Handle the PHYs, the clocks and the reset lines >> dwc3-generic: Add select_dr_mode operation >> usb: dwc3: Fix a compilation error with the edison defconfig >> >> arch/arm/Kconfig | 2 + >> board/sunxi/board.c | 2 +- >> cmd/fastboot.c | 4 +- >> cmd/rockusb.c | 4 +- >> cmd/thordown.c | 4 +- >> cmd/usb_gadget_sdp.c | 4 +- >> cmd/usb_mass_storage.c | 4 +- >> common/dfu.c | 6 +- >> configs/evb-rk3328_defconfig | 1 + >> drivers/usb/Kconfig | 14 +++ >> drivers/usb/dwc3/Kconfig | 7 +- >> drivers/usb/dwc3/core.c | 89 ++++++++++++++- >> drivers/usb/dwc3/dwc3-generic.c | 208 >> ++++++++++++++++++++++++++++-------- >> drivers/usb/dwc3/ep0.c | 2 +- >> drivers/usb/gadget/ether.c | 40 ++----- >> drivers/usb/gadget/udc/Makefile | 4 + >> drivers/usb/gadget/udc/udc-core.c | 3 +- >> drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ >> drivers/usb/host/xhci-dwc3.c | 95 ++-------------- >> drivers/usb/musb-new/omap2430.c | 2 +- >> drivers/usb/musb-new/sunxi.c | 2 +- >> include/dm/uclass-id.h | 1 + >> include/dwc3-uboot.h | 19 ++++ >> include/linux/usb/gadget.h | 18 ++++ 24 files changed, >> 401 insertions(+), 192 deletions(-) create mode 100644 >> drivers/usb/gadget/udc/udc-uclass.c _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
First off thanks for the work. I have imported it into my u-boot tree for the iMX8M and now have both usb host and gadget mode working simultaneously. There is one catch. Currently, the iMX8M codebase does not support clock and power device initialization from DM. I have patched the driver to punt back to the board to do these initializations in the following patch. Yes I know not ideal, but functional. I am wondering if we should support architecture specific implementation quirks for boards that don't fully support DM initialization yet.
That is not fitting the DM model. I had the same issue and finally enabled the clocks in the board_late_init(): board/ti/dra7xx/evm.c:662:int board_late_init(void)
I am open to writing something more complete if we decide it is something worth pursuing, otherwise I will carry this patch in my tree for time being.
The true solution would be to implement the support for clk.
Many other people on the ML (including me) see the urgent need to implement the DM_CLK for e.g. imx6/5/7/8, etc.
I think that it would be best to add it clock by clock. The stubs in board code/files is a dead end, IMHO.
I agree 100%.
We had a similar discussion for the TI platforms, but due to the specific design of the TI power/clk in Linux (hwmod), we chose to keep the clocks handling in the board file at the moment.
-Jon
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 6d9be9b245..90d4ff2ea7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -119,6 +119,15 @@ struct dwc3_glue_ops { enum usb_dr_mode mode); };
+__weak int board_usb_of_init(struct udevice *dev) +{
return 0;
+}
+__weak void board_usb_of_cleanup(struct udevice *dev) +{ +}
- static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob;
@@ -242,6 +251,8 @@ static int dwc3_glue_probe(struct udevice *dev) index++; }
ret = board_usb_of_init(dev);
}return 0;
@@ -249,6 +260,8 @@ static int dwc3_glue_remove(struct udevice *dev) { struct dwc3_glue_data *glue = dev_get_platdata(dev);
board_usb_of_cleanup(dev);
reset_release_bulk(&glue->resets); clk_release_bulk(&glue->clks);
@@ -257,6 +270,7 @@ static int dwc3_glue_remove(struct udevice *dev) }
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Obviously the proper solution is implementing a proper DM clk driver. I generally refrain from just enabling a bunch of clocks and code in our board file, since our devices are SOM + carrier, and many customers design their own boards and then continue to use our bootloader. I am fine carrying the patch until we have the time to build the proper infrastructure in mainline.
Quick followup.
Has anyone tried to build this into SPL? I am getting lots of undefined symbols. undefined reference to `usb_get_dr_mode' , undefined reference to `device_bind_driver_to_node' etc.
-Jon

On 04/01/2019 14:54, Jon Nettleton wrote:
On Fri, Jan 4, 2019 at 12:22 PM Jon Nettleton jon@solid-run.com wrote:
On Fri, Jan 4, 2019 at 11:25 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote:
On 04/01/2019 11:19, Lukasz Majewski wrote:
Hi Jean-Jacques,
On 04/01/2019 08:05, Jon Nettleton wrote:
On Fri, Dec 7, 2018 at 8:46 AM Jean-Jacques Hiblot jjhiblot@ti.com wrote: > On 06/12/2018 21:56, Loic Devulder wrote: >> Hi, >> >> I re-tested this series on Khadas VIM1 and it still fix the USB >> issue I had with 'usb reset' (I already tested v2 patches). >> >> I just have a message and I'm not sure that I had it last time: >> "Error disabling PHY supply >> Can't shutdown USB PHY1 for dwc3@c9000000" >> >> But USB stack looks ok, I can plug/unplug USB key and do the >> reset, all works as expected. >> >> Since my last test lot of changes has been done in Amlogic SoCs, >> maybe it's because of this? >> >> So if you want you can add my tested-by flag. >> Tested-by: Loic Devulder ldevulder@suse.de > Thank you for testing >> On 11/29/18 10:52 AM, Jean-Jacques Hiblot wrote: >>> This series aims at bringing improvements to the dwc3_generic >>> driver so that it can be used by most of the platforms using the >>> dwc3 controller. >>> >>> I tested this on with DRA7 and AM57x platforms for both >>> Peripheral and Host operations. The code to enable DM USB host & >>> dev support for those platforms will be submitted in a separate >>> series. >>> >>> Michal Simek has tested this series: >>> " I have tested it on zcu100 with usb stick, usb to ethernet >>> converter and also dfu. >>> Tested-by: Michal Simek michal.simek@xilinx.com" >>> >>> Enhancements: >>> - use separate Kconfig option for DM USB Periphal and DM USB >>> Host. This allow platforms to keep their non-DM USB peripheral >>> code and use the DM USB host. >>> - fixes the bind/probe confusion in dwc3_generic. The probe is >>> done when the USB device is first needed. >>> - handles PHYs when in the peripheral mode. The code to handle >>> the PHYs is shared with the host side >>> - handles clock and reset >>> - bind host controller to the more generic driver 'xhci-dwc3' >>> >>> >>> Changes in v4: >>> - rebased on latest U-Boot >>> - renamed DM_USB_DEV as DM_USB_GADGET >>> - Add a new commit to create a new UCLASS for USB gadget drivers >>> >>> Changes in v3: >>> - fixes bug dwc3_setup_phy(): the phy arrays wasn't returned. >>> This was visible only when the device is removed. >>> - Stub the DWC3 PHY operations if CONFIG_IS_ENABLED(PHY) is >>> false. This fixes all build issues but one (evb-rk3328). >>> - Fix build issue with evb-rk3328 by enabling CONFIG_USB_DWC3. >>> This has little impact on the footprint and should not break the >>> runtime as the xhci-rockchip driver has its own probe function. >>> Nevertheless this was !!! NOT TESTED !!! by lack of hw >>> >>> Changes in v2: >>> - Updated commit log >>> - Fixed typo in thordown.c >>> - select DM_USB_DEV by default for zynqmp platforms >>> >>> Jean-Jacques Hiblot (10): >>> usb: gadget: Do not call board_usb_xxx() directly in USB >>> gadget drivers >>> usb: introduce a separate config option for DM USB device >>> usb: udc: implement DM versions of >>> usb_gadget_initialize()/_release()/_handle_interrupt() >>> dwc3_generic: do not probe the USB device driver when it's >>> bound dwc3: move phy operation to core.c >>> dm: usb: create a new UCLASS ID for USB gadget devices >>> configs: evb-rk3328: Enable CONFIG_USB_DWC3 >>> dwc3-generic: Handle the PHYs, the clocks and the reset lines >>> dwc3-generic: Add select_dr_mode operation >>> usb: dwc3: Fix a compilation error with the edison defconfig >>> >>> arch/arm/Kconfig | 2 + >>> board/sunxi/board.c | 2 +- >>> cmd/fastboot.c | 4 +- >>> cmd/rockusb.c | 4 +- >>> cmd/thordown.c | 4 +- >>> cmd/usb_gadget_sdp.c | 4 +- >>> cmd/usb_mass_storage.c | 4 +- >>> common/dfu.c | 6 +- >>> configs/evb-rk3328_defconfig | 1 + >>> drivers/usb/Kconfig | 14 +++ >>> drivers/usb/dwc3/Kconfig | 7 +- >>> drivers/usb/dwc3/core.c | 89 ++++++++++++++- >>> drivers/usb/dwc3/dwc3-generic.c | 208 >>> ++++++++++++++++++++++++++++-------- >>> drivers/usb/dwc3/ep0.c | 2 +- >>> drivers/usb/gadget/ether.c | 40 ++----- >>> drivers/usb/gadget/udc/Makefile | 4 + >>> drivers/usb/gadget/udc/udc-core.c | 3 +- >>> drivers/usb/gadget/udc/udc-uclass.c | 58 ++++++++++ >>> drivers/usb/host/xhci-dwc3.c | 95 ++-------------- >>> drivers/usb/musb-new/omap2430.c | 2 +- >>> drivers/usb/musb-new/sunxi.c | 2 +- >>> include/dm/uclass-id.h | 1 + >>> include/dwc3-uboot.h | 19 ++++ >>> include/linux/usb/gadget.h | 18 ++++ 24 files changed, >>> 401 insertions(+), 192 deletions(-) create mode 100644 >>> drivers/usb/gadget/udc/udc-uclass.c > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot First off thanks for the work. I have imported it into my u-boot tree for the iMX8M and now have both usb host and gadget mode working simultaneously. There is one catch. Currently, the iMX8M codebase does not support clock and power device initialization from DM. I have patched the driver to punt back to the board to do these initializations in the following patch. Yes I know not ideal, but functional. I am wondering if we should support architecture specific implementation quirks for boards that don't fully support DM initialization yet.
That is not fitting the DM model. I had the same issue and finally enabled the clocks in the board_late_init(): board/ti/dra7xx/evm.c:662:int board_late_init(void)
I am open to writing something more complete if
we decide it is something worth pursuing, otherwise I will carry this patch in my tree for time being.
The true solution would be to implement the support for clk.
Many other people on the ML (including me) see the urgent need to implement the DM_CLK for e.g. imx6/5/7/8, etc.
I think that it would be best to add it clock by clock. The stubs in board code/files is a dead end, IMHO.
I agree 100%.
We had a similar discussion for the TI platforms, but due to the specific design of the TI power/clk in Linux (hwmod), we chose to keep the clocks handling in the board file at the moment.
-Jon
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 6d9be9b245..90d4ff2ea7 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -119,6 +119,15 @@ struct dwc3_glue_ops { enum usb_dr_mode mode); };
+__weak int board_usb_of_init(struct udevice *dev) +{
return 0;
+}
+__weak void board_usb_of_cleanup(struct udevice *dev) +{ +}
- static int dwc3_glue_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob;
@@ -242,6 +251,8 @@ static int dwc3_glue_probe(struct udevice *dev) index++; }
ret = board_usb_of_init(dev);
}return 0;
@@ -249,6 +260,8 @@ static int dwc3_glue_remove(struct udevice *dev) { struct dwc3_glue_data *glue = dev_get_platdata(dev);
board_usb_of_cleanup(dev);
reset_release_bulk(&glue->resets); clk_release_bulk(&glue->clks);
@@ -257,6 +270,7 @@ static int dwc3_glue_remove(struct udevice *dev) }
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Obviously the proper solution is implementing a proper DM clk driver. I generally refrain from just enabling a bunch of clocks and code in our board file, since our devices are SOM + carrier, and many customers design their own boards and then continue to use our bootloader. I am fine carrying the patch until we have the time to build the proper infrastructure in mainline.
Quick followup.
Has anyone tried to build this into SPL? I am getting lots of undefined symbols. undefined reference to `usb_get_dr_mode' , undefined reference to `device_bind_driver_to_node' etc.
I've used it in SPL on am33xx based platforms. You may have to enable a couple of options, including SPL_DM.
-Jon
participants (7)
-
Adam Ford
-
Jagan Teki
-
Jean-Jacques Hiblot
-
Jon Nettleton
-
Loic Devulder
-
Lukasz Majewski
-
Simon Glass