U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards
@ 2026-08-24 18:29 Stefan Eichenberger
  2026-08-24 18:29 ` [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET Stefan Eichenberger
                   ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-24 18:29 UTC (permalink / raw)
  To: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke
  Cc: u-boot

This series fixes a few USB issues that show up on the Toradex i.MX95
based modules and finally enables USB support for them.

The i.MX95 has two USB controllers: a host-only DWC3 controller and a
ChipIdea OTG controller. Getting both of them to work together in
U-Boot requires a couple of fixes:

- Combining DWC3 (host only) with CI_UDC as the gadget driver, while
  DM_USB_GADGET is disabled, currently fails to link because DWC3 core
  provides dm_usb_gadget_handle_interrupts() even when the DWC3 gadget
  driver is not built (patch 1).

- The DWC3 reference clock lookup added by commit c6583354b7c1 ("usb:
  dwc3: Look up reference clock DT phandle in both controller DT nodes")
  resolves an index found in the child node's clock-names against the
  clk_bulk of the parent glue node. On the Verdin iMX95 the two lists
  have a different order, so the wrong clock is picked, which shows up
  as intermittent enumeration failures behind a USB hub (patch 2).

- ehci_gadget picks the first USB device it finds, which on the i.MX95
  is the host-only DWC3 controller instead of the ChipIdea OTG
  controller, so "ums" never enters device mode. Skip host-only
  controllers when looking for the gadget controller (patch 3).

The remaining patches enable CI_UDC on the Verdin iMX95 and turn on the
DWC3 host controller support for the Verdin iMX95 and the Toradex SMARC
iMX95.

Testing
-------

USB was tested on a Verdin iMX95, a Toradex SMARC iMX95 and an Apalis
iMX6 (as a regression test for the ehci_gadget change) with:

  usb start

and with:

  ums 0 mmc 0

All three boards were enumerating a USB stick and appeared as USB
devices on a PC connected to the USB device port.

Stefan Eichenberger (6):
  usb: dwc3: core: only provide legacy gadget IRQ handler when
    USB_DWC3_GADGET
  usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array
  usb: skip host-only devices when picking the ehci gadget controller
  configs: verdin-imx95: enable CI_UDC usb gadget driver
  toradex: verdin-imx95: enable DWC3 USB controller support
  toradex: smarc-imx95: enable DWC3 USB controller support

 .../dts/imx95-toradex-smarc-dev-u-boot.dtsi   |  8 -------
 .../arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi |  8 -------
 configs/toradex-smarc-imx95_defconfig         |  4 ++++
 configs/verdin-imx95_defconfig                |  3 ++-
 drivers/usb/dwc3/core.c                       |  2 +-
 drivers/usb/dwc3/dwc3-generic.c               | 24 +++++++++++++++++--
 drivers/usb/host/usb-uclass.c                 | 23 ++++++++++++++++--
 7 files changed, 50 insertions(+), 22 deletions(-)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET
  2026-08-24 18:29 [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards Stefan Eichenberger
@ 2026-08-24 18:29 ` Stefan Eichenberger
  2026-08-24 23:33   ` Marek Vasut
  2026-08-24 18:29 ` [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array Stefan Eichenberger
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-24 18:29 UTC (permalink / raw)
  To: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke
  Cc: u-boot

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

Building a board with USB_DWC3=y (DWC3 used purely as an XHCI host
controller), USB_DWC3_GADGET unset, and DM_USB_GADGET disabled (e.g.
to use CONFIG_CI_UDC for a separate ChipIdea gadget/OTG controller)
fails to link:

drivers/usb/gadget/ci_udc.o: in function `dm_usb_gadget_handle_interrupts':
drivers/usb/gadget/ci_udc.c:983: multiple definition of `dm_usb_gadget_handle_interrupts';
drivers/usb/dwc3/core.o:drivers/usb/dwc3/core.c:1034: first defined here
drivers/usb/dwc3/core.o: in function `dm_usb_gadget_handle_interrupts':
drivers/usb/dwc3/core.c:1044: undefined reference to `dwc3_gadget_uboot_handle_interrupt'

Add "&& CONFIG_IS_ENABLED(USB_DWC3_GADGET)" to the guard so this code
is only compiled when the DWC3 gadget driver it depends on is actually
present, matching the Makefile dependency. Boards that combine DWC3
(host) with a separate legacy gadget driver like CI_UDC, with
DM_USB_GADGET disabled, now link correctly. Boards that already use
DWC3 in gadget mode without DM_USB_GADGET are unaffected since
USB_DWC3_GADGET is set for them.

Fixes: 4d1589808970 ("usb: udc: dwc3: Fold board dm_usb_gadget_handle_interrupts() into DWC3 gadget")
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 drivers/usb/dwc3/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index be198041f08..9bff5149c5f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1016,7 +1016,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_GADGET)
+#if !CONFIG_IS_ENABLED(DM_USB_GADGET) && CONFIG_IS_ENABLED(USB_DWC3_GADGET)
 __weak int dwc3_uboot_interrupt_status(struct udevice *dev)
 {
 	return 1;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array
  2026-08-24 18:29 [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards Stefan Eichenberger
  2026-08-24 18:29 ` [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET Stefan Eichenberger
@ 2026-08-24 18:29 ` Stefan Eichenberger
  2026-08-24 23:40   ` Marek Vasut
  2026-08-24 18:29 ` [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller Stefan Eichenberger
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-24 18:29 UTC (permalink / raw)
  To: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke
  Cc: u-boot

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

On Verdin iMX95, with a USB hub permanently attached to the DWC3 host
port the hub itself enumerates fine but a USB stick plugged into it
fails intermittently:

  Verdin iMX95 # usb start
  starting USB...
  USB XHCI 1.10
  Device not responding to set address.

        USB device not accepting new address (error=80000000)
  Bus usb@4c100000: 2 USB Device(s) found
         scanning usb for storage devices... 0 Storage Device(s) found
  Verdin iMX95 # usb reset
  resetting USB...
  USB XHCI 1.10
  WARN endpoint is halted
  WARN endpoint is halted
  unable to get device descriptor (error=-22)

Commit c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in
both controller DT nodes") added a fallback that searches the DWC3
child node's "clock-names" for "ref"/"ref_clk" when it isn't found on
the parent glue node, but always resolves the found index against
glue->clks, a clk_bulk populated only from the parent glue node's own
clock-names list. This is wrong since the child node's clock-names list
is not guaranteed to be in the same order as the parent's, and indeed on
Verdin iMX95 the child node has a different order than the parent node.

Fix it by resolving the index against the child node's clk and ensure to
enable the clock before using it.

Fixes: c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in both controller DT nodes")
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 drivers/usb/dwc3/dwc3-generic.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 2356b3bc0aa..e16d236bd9d 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -31,6 +31,7 @@ struct dwc3_generic_priv {
 	struct dwc3 dwc3;
 	struct phy_bulk phys;
 	struct gpio_desc *ulpi_reset;
+	struct clk ref_clk;
 };
 
 struct dwc3_generic_host_priv {
@@ -76,9 +77,28 @@ static int dwc3_generic_probe(struct udevice *dev,
 		index = ofnode_stringlist_search(node, "clock-names", "ref");
 		if (index < 0)
 			index = ofnode_stringlist_search(node, "clock-names", "ref_clk");
-	}
-	if (index >= 0)
+		/*
+		 * glue->clks was populated from the parent glue node's own
+		 * clock-names list, which can differ in length/order from
+		 * this child node's list (e.g. i.MX95: glue has "hsio",
+		 * "suspend", the dwc3 child has "bus_early", "ref",
+		 * "suspend"). Reusing this index against glue->clks would
+		 * silently resolve to the wrong clock, so fetch it directly
+		 * from this node instead.
+		 */
+		if (index >= 0) {
+			if (!clk_get_by_index(dev, index, &priv->ref_clk)) {
+				clk_enable(&priv->ref_clk);
+				dwc3->ref_clk = &priv->ref_clk;
+			} else {
+				debug("%s: failed to get ref_clk from DT\n", dev->name);
+			}
+		} else {
+			debug("%s: no ref_clk found in DT\n", dev->name);
+		}
+	} else {
 		dwc3->ref_clk = &glue->clks.clks[index];
+	}
 #endif
 
 	/*
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller
  2026-08-24 18:29 [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards Stefan Eichenberger
  2026-08-24 18:29 ` [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET Stefan Eichenberger
  2026-08-24 18:29 ` [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array Stefan Eichenberger
@ 2026-08-24 18:29 ` Stefan Eichenberger
  2026-08-24 23:45   ` Marek Vasut
  2026-08-24 18:29 ` [PATCH v1 4/6] configs: verdin-imx95: enable CI_UDC usb gadget driver Stefan Eichenberger
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-24 18:29 UTC (permalink / raw)
  To: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke
  Cc: u-boot

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

The i.MX95 SoC has two USB controllers, a DWC3 host-only controller and
a ChipIdea OTG controller. The latter is the one that can be used for
USB gadget functionality. However, U-Boot incorrectly selects the
host-only controller when attempting to set up a USB gadget, leading to
failures in gadget mode.

Iterate over usb devices and skipping any that are host-only when
selecting the controller for gadget mode. This ensures that a device
only or otg controller is used for USB gadget functionality.

Verified on Verdin iMX95 hardware: "ums 0 mmc 0" now correctly flips
the ChipIdea OTG controller into device mode and enumerates on the
host PC.

Fixes: 821ca608d816 ("usb: Use the first available device for ehci_gadget")
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 1c74d6fd39a..b9e9ef7e86a 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -18,6 +18,7 @@
 #include <dm/device-internal.h>
 #include <dm/lists.h>
 #include <dm/uclass-internal.h>
+#include <linux/usb/otg.h>
 #include <time.h>
 
 static bool asynch_allowed;
@@ -484,10 +485,23 @@ int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
 	struct udevice *dev;
 	int ret;
 
-	/* Find the old device and remove it */
+	/*
+	 * Find the first UCLASS_USB device that isn't host-only. SoCs can
+	 * have more than one UCLASS_USB controller (e.g. i.MX95, where a
+	 * host-only DWC3 port and the ChipIdea OTG port both register under
+	 * UCLASS_USB); taking whichever device happens to be first could
+	 * pick the host-only controller instead of the OTG-capable one this
+	 * is actually meant to flip into device mode.
+	 */
 	ret = uclass_find_first_device(UCLASS_USB, &dev);
 	if (ret)
 		return ret;
+	while (dev && usb_get_dr_mode(dev_ofnode(dev)) == USB_DR_MODE_HOST)
+		uclass_find_next_device(&dev);
+	if (!dev)
+		return -ENODEV;
+
+	/* Remove the old device */
 	ret = device_remove(dev, DM_REMOVE_NORMAL);
 	if (ret)
 		return ret;
@@ -507,10 +521,15 @@ int usb_remove_ehci_gadget(struct ehci_ctrl **ctlrp)
 	struct udevice *dev;
 	int ret;
 
-	/* Find the old device and remove it */
+	/* Find the same non-host-only device usb_setup_ehci_gadget() used */
 	ret = uclass_find_first_device(UCLASS_USB, &dev);
 	if (ret)
 		return ret;
+	while (dev && usb_get_dr_mode(dev_ofnode(dev)) == USB_DR_MODE_HOST)
+		uclass_find_next_device(&dev);
+	if (!dev)
+		return -ENODEV;
+
 	ret = device_remove(dev, DM_REMOVE_NORMAL);
 	if (ret)
 		return ret;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v1 4/6] configs: verdin-imx95: enable CI_UDC usb gadget driver
  2026-08-24 18:29 [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards Stefan Eichenberger
                   ` (2 preceding siblings ...)
  2026-08-24 18:29 ` [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller Stefan Eichenberger
@ 2026-08-24 18:29 ` Stefan Eichenberger
  2026-08-24 18:29 ` [PATCH v1 5/6] toradex: verdin-imx95: enable DWC3 USB controller support Stefan Eichenberger
  2026-08-24 18:29 ` [PATCH v1 6/6] toradex: smarc-imx95: " Stefan Eichenberger
  5 siblings, 0 replies; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-24 18:29 UTC (permalink / raw)
  To: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke
  Cc: u-boot

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

The i.MX95 SoC has a ChipIdea USB device controller. This conflicts with
CONFIG_DM_USB_GADGET. For the Verdin iMX95 we want to have CONFIG_CI_UDC
enabled and CONFIG_DM_USB_GADGET disabled to make sure the ChipIdea USB
device controller is used.

Fixes: 60d8255d8dc0 ("board: toradex: add Toradex Verdin iMX95")
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 configs/verdin-imx95_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configs/verdin-imx95_defconfig b/configs/verdin-imx95_defconfig
index daf41a8b830..2635d899be0 100644
--- a/configs/verdin-imx95_defconfig
+++ b/configs/verdin-imx95_defconfig
@@ -167,7 +167,6 @@ CONFIG_FSL_LPUART=y
 CONFIG_SPI=y
 CONFIG_DM_THERMAL=y
 CONFIG_USB=y
-CONFIG_DM_USB_GADGET=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
@@ -179,6 +178,7 @@ CONFIG_USB_GADGET_MANUFACTURER="Toradex"
 CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
 CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
 CONFIG_USB_GADGET_OS_DESCRIPTORS=y
+CONFIG_CI_UDC=y
 CONFIG_SDP_LOADADDR=0x90400000
 CONFIG_ULP_WATCHDOG=y
 CONFIG_WDT=y
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v1 5/6] toradex: verdin-imx95: enable DWC3 USB controller support
  2026-08-24 18:29 [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards Stefan Eichenberger
                   ` (3 preceding siblings ...)
  2026-08-24 18:29 ` [PATCH v1 4/6] configs: verdin-imx95: enable CI_UDC usb gadget driver Stefan Eichenberger
@ 2026-08-24 18:29 ` Stefan Eichenberger
  2026-08-24 18:29 ` [PATCH v1 6/6] toradex: smarc-imx95: " Stefan Eichenberger
  5 siblings, 0 replies; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-24 18:29 UTC (permalink / raw)
  To: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke
  Cc: u-boot

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

Enable the DWC3 USB host controller on the Verdin iMX95. Enable the DWC3
driver support by enabling the wrapper driver CONFIG_USB_DWC3_GENERIC
and ensure the device tree nodes are kept enabled for U-Boot.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi | 8 --------
 configs/verdin-imx95_defconfig                 | 1 +
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi b/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi
index 8ab70cf7399..ab6e1054a9f 100644
--- a/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi
+++ b/arch/arm/dts/imx95-verdin-wifi-dev-u-boot.dtsi
@@ -90,14 +90,6 @@
 	/delete-property/power-domains;
 };
 
-&usb3 {
-	status = "disabled";
-};
-
-&usb3_dwc3 {
-	status = "disabled";
-};
-
 &usb_recov_ctrl {
 	bootph-pre-ram;
 };
diff --git a/configs/verdin-imx95_defconfig b/configs/verdin-imx95_defconfig
index 2635d899be0..4da705a91a0 100644
--- a/configs/verdin-imx95_defconfig
+++ b/configs/verdin-imx95_defconfig
@@ -172,6 +172,7 @@ CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_DWC3=y
 # CONFIG_USB_DWC3_GADGET is not set
+CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Toradex"
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v1 6/6] toradex: smarc-imx95: enable DWC3 USB controller support
  2026-08-24 18:29 [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards Stefan Eichenberger
                   ` (4 preceding siblings ...)
  2026-08-24 18:29 ` [PATCH v1 5/6] toradex: verdin-imx95: enable DWC3 USB controller support Stefan Eichenberger
@ 2026-08-24 18:29 ` Stefan Eichenberger
  5 siblings, 0 replies; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-24 18:29 UTC (permalink / raw)
  To: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke
  Cc: u-boot

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

The iMX95 USB controller is DWC3-based, but the DWC3 core/glue driver
was never enabled for this board, therefore enable CONFIG_USB_DWC3,
CONFIG_USB_XHCI_DWC3 and CONFIG_USB_DWC3_GENERIC to enable support for
USB in U-Boot for the Toradex SMARC iMX95.

Remove the dwc3 nodes from the U-Boot device tree to keep them enabled
now that the driver is there.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi | 8 --------
 configs/toradex-smarc-imx95_defconfig            | 4 ++++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi b/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi
index e4eda61e5c4..d9fe4abe877 100644
--- a/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi
+++ b/arch/arm/dts/imx95-toradex-smarc-dev-u-boot.dtsi
@@ -88,14 +88,6 @@
 	/delete-property/power-domains;
 };
 
-&usb3 {
-	status = "disabled";
-};
-
-&usb3_dwc3 {
-	status = "disabled";
-};
-
 &usdhc1 {
 	bootph-pre-ram;
 };
diff --git a/configs/toradex-smarc-imx95_defconfig b/configs/toradex-smarc-imx95_defconfig
index 9abadb0ed1a..5b687f9bb3d 100644
--- a/configs/toradex-smarc-imx95_defconfig
+++ b/configs/toradex-smarc-imx95_defconfig
@@ -166,7 +166,11 @@ CONFIG_SPI=y
 CONFIG_DM_THERMAL=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_DWC3=y
+# CONFIG_USB_DWC3_GADGET is not set
+CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Toradex"
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET
  2026-08-24 18:29 ` [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET Stefan Eichenberger
@ 2026-08-24 23:33   ` Marek Vasut
  2026-08-26  7:15     ` Stefan Eichenberger
  0 siblings, 1 reply; 18+ messages in thread
From: Marek Vasut @ 2026-08-24 23:33 UTC (permalink / raw)
  To: Stefan Eichenberger
  Cc: u-boot, francesco.dolcini, trini, ilias.apalodimas, sbabic,
	festevam, uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke

On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> 
> Building a board with USB_DWC3=y (DWC3 used purely as an XHCI host
> controller), USB_DWC3_GADGET unset, and DM_USB_GADGET disabled (e.g.
> to use CONFIG_CI_UDC for a separate ChipIdea gadget/OTG controller)
> fails to link:
> 
> drivers/usb/gadget/ci_udc.o: in function `dm_usb_gadget_handle_interrupts':
> drivers/usb/gadget/ci_udc.c:983: multiple definition of `dm_usb_gadget_handle_interrupts';
> drivers/usb/dwc3/core.o:drivers/usb/dwc3/core.c:1034: first defined here
> drivers/usb/dwc3/core.o: in function `dm_usb_gadget_handle_interrupts':
> drivers/usb/dwc3/core.c:1044: undefined reference to `dwc3_gadget_uboot_handle_interrupt'
> 
> Add "&& CONFIG_IS_ENABLED(USB_DWC3_GADGET)" to the guard so this code
> is only compiled when the DWC3 gadget driver it depends on is actually
> present, matching the Makefile dependency. Boards that combine DWC3
> (host) with a separate legacy gadget driver like CI_UDC, with
> DM_USB_GADGET disabled, now link correctly. Boards that already use
> DWC3 in gadget mode without DM_USB_GADGET are unaffected since
> USB_DWC3_GADGET is set for them.
> 
> Fixes: 4d1589808970 ("usb: udc: dwc3: Fold board dm_usb_gadget_handle_interrupts() into DWC3 gadget")
> Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> ---
>   drivers/usb/dwc3/core.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index be198041f08..9bff5149c5f 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1016,7 +1016,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_GADGET)
> +#if !CONFIG_IS_ENABLED(DM_USB_GADGET) && CONFIG_IS_ENABLED(USB_DWC3_GADGET)
>   __weak int dwc3_uboot_interrupt_status(struct udevice *dev)
Simply enable DM_USB_GADGET , then the 
drivers/usb/gadget/udc/udc-uclass.c dm_usb_gadget_handle_interrupts() is 
used which correctly invokes the per-controller IRQ handler. DWC3_GADGET 
should likely depend on DM_USB_GADGET.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array
  2026-08-24 18:29 ` [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array Stefan Eichenberger
@ 2026-08-24 23:40   ` Marek Vasut
  2026-08-26  7:18     ` Stefan Eichenberger
  0 siblings, 1 reply; 18+ messages in thread
From: Marek Vasut @ 2026-08-24 23:40 UTC (permalink / raw)
  To: Stefan Eichenberger, francesco.dolcini, trini, ilias.apalodimas,
	sbabic, festevam, uboot-imx, marek.vasut+usb, alice.guo,
	antoine.gouby, stefan.eichenberger, emanuele.ghidoli,
	franz.schnyder, balaji.selvanathan, gurumoorthy.santhakumar,
	mkorpershoek, xypron.glpk, casey.connolly, hayashi.kunihiko,
	sean.anderson, sjg, ernest.vanhoecke
  Cc: u-boot

On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> 
> On Verdin iMX95, with a USB hub permanently attached to the DWC3 host
> port the hub itself enumerates fine but a USB stick plugged into it
> fails intermittently:
> 
>    Verdin iMX95 # usb start
>    starting USB...
>    USB XHCI 1.10
>    Device not responding to set address.
> 
>          USB device not accepting new address (error=80000000)
>    Bus usb@4c100000: 2 USB Device(s) found
>           scanning usb for storage devices... 0 Storage Device(s) found
>    Verdin iMX95 # usb reset
>    resetting USB...
>    USB XHCI 1.10
>    WARN endpoint is halted
>    WARN endpoint is halted
>    unable to get device descriptor (error=-22)
> 
> Commit c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in
> both controller DT nodes") added a fallback that searches the DWC3
> child node's "clock-names" for "ref"/"ref_clk" when it isn't found on
> the parent glue node, but always resolves the found index against
> glue->clks, a clk_bulk populated only from the parent glue node's own
> clock-names list. This is wrong since the child node's clock-names list
> is not guaranteed to be in the same order as the parent's, and indeed on
> Verdin iMX95 the child node has a different order than the parent node.
> 
> Fix it by resolving the index against the child node's clk and ensure to
> enable the clock before using it.
> 
> Fixes: c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in both controller DT nodes")
> Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> ---
>   drivers/usb/dwc3/dwc3-generic.c | 24 ++++++++++++++++++++++--
>   1 file changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
> index 2356b3bc0aa..e16d236bd9d 100644
> --- a/drivers/usb/dwc3/dwc3-generic.c
> +++ b/drivers/usb/dwc3/dwc3-generic.c
> @@ -31,6 +31,7 @@ struct dwc3_generic_priv {
>   	struct dwc3 dwc3;
>   	struct phy_bulk phys;
>   	struct gpio_desc *ulpi_reset;
> +	struct clk ref_clk;
>   };
>   
>   struct dwc3_generic_host_priv {
> @@ -76,9 +77,28 @@ static int dwc3_generic_probe(struct udevice *dev,
>   		index = ofnode_stringlist_search(node, "clock-names", "ref");
>   		if (index < 0)
>   			index = ofnode_stringlist_search(node, "clock-names", "ref_clk");
> -	}
> -	if (index >= 0)
> +		/*
> +		 * glue->clks was populated from the parent glue node's own
> +		 * clock-names list, which can differ in length/order from
> +		 * this child node's list (e.g. i.MX95: glue has "hsio",
> +		 * "suspend", the dwc3 child has "bus_early", "ref",
> +		 * "suspend"). Reusing this index against glue->clks would
> +		 * silently resolve to the wrong clock, so fetch it directly
> +		 * from this node instead.
> +		 */
> +		if (index >= 0) {
> +			if (!clk_get_by_index(dev, index, &priv->ref_clk)) {

Would it be possible to call clk_get_by_name(dev, ...) and 
clk_get_by_name(dev->parent, ...) instead, until one of them succeeds ? 
That could make the code simpler.

> +				clk_enable(&priv->ref_clk);
> +				dwc3->ref_clk = &priv->ref_clk;
> +			} else {
> +				debug("%s: failed to get ref_clk from DT\n", dev->name);

dev_dbg()

> +			}
> +		} else {
> +			debug("%s: no ref_clk found in DT\n", dev->name);

dev_dbg()

> +		}
> +	} else {
>   		dwc3->ref_clk = &glue->clks.clks[index];
> +	}
>   #endif
>   
>   	/*


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller
  2026-08-24 18:29 ` [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller Stefan Eichenberger
@ 2026-08-24 23:45   ` Marek Vasut
  2026-08-26  7:16     ` Stefan Eichenberger
  0 siblings, 1 reply; 18+ messages in thread
From: Marek Vasut @ 2026-08-24 23:45 UTC (permalink / raw)
  To: Stefan Eichenberger, francesco.dolcini, trini, ilias.apalodimas,
	sbabic, festevam, uboot-imx, marek.vasut+usb, alice.guo,
	antoine.gouby, stefan.eichenberger, emanuele.ghidoli,
	franz.schnyder, balaji.selvanathan, gurumoorthy.santhakumar,
	mkorpershoek, xypron.glpk, casey.connolly, hayashi.kunihiko,
	sean.anderson, sjg, ernest.vanhoecke
  Cc: u-boot

On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> 
> The i.MX95 SoC has two USB controllers, a DWC3 host-only controller and
> a ChipIdea OTG controller. The latter is the one that can be used for
> USB gadget functionality.

Both DWC3 and CI HDRC controllers are dual-role on MX95, are they not ?

[...]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET
  2026-08-24 23:33   ` Marek Vasut
@ 2026-08-26  7:15     ` Stefan Eichenberger
  2026-08-26 12:27       ` Marek Vasut
  2026-08-26 16:11       ` Tom Rini
  0 siblings, 2 replies; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-26  7:15 UTC (permalink / raw)
  To: Marek Vasut
  Cc: u-boot, francesco.dolcini, trini, ilias.apalodimas, sbabic,
	festevam, uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke

On Tue, Aug 25, 2026 at 01:33:27AM +0200, Marek Vasut wrote:
> On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> > From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > 
> > Building a board with USB_DWC3=y (DWC3 used purely as an XHCI host
> > controller), USB_DWC3_GADGET unset, and DM_USB_GADGET disabled (e.g.
> > to use CONFIG_CI_UDC for a separate ChipIdea gadget/OTG controller)
> > fails to link:
> > 
> > drivers/usb/gadget/ci_udc.o: in function `dm_usb_gadget_handle_interrupts':
> > drivers/usb/gadget/ci_udc.c:983: multiple definition of `dm_usb_gadget_handle_interrupts';
> > drivers/usb/dwc3/core.o:drivers/usb/dwc3/core.c:1034: first defined here
> > drivers/usb/dwc3/core.o: in function `dm_usb_gadget_handle_interrupts':
> > drivers/usb/dwc3/core.c:1044: undefined reference to `dwc3_gadget_uboot_handle_interrupt'
> > 
> > Add "&& CONFIG_IS_ENABLED(USB_DWC3_GADGET)" to the guard so this code
> > is only compiled when the DWC3 gadget driver it depends on is actually
> > present, matching the Makefile dependency. Boards that combine DWC3
> > (host) with a separate legacy gadget driver like CI_UDC, with
> > DM_USB_GADGET disabled, now link correctly. Boards that already use
> > DWC3 in gadget mode without DM_USB_GADGET are unaffected since
> > USB_DWC3_GADGET is set for them.
> > 
> > Fixes: 4d1589808970 ("usb: udc: dwc3: Fold board dm_usb_gadget_handle_interrupts() into DWC3 gadget")
> > Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > ---
> >   drivers/usb/dwc3/core.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > index be198041f08..9bff5149c5f 100644
> > --- a/drivers/usb/dwc3/core.c
> > +++ b/drivers/usb/dwc3/core.c
> > @@ -1016,7 +1016,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_GADGET)
> > +#if !CONFIG_IS_ENABLED(DM_USB_GADGET) && CONFIG_IS_ENABLED(USB_DWC3_GADGET)
> >   __weak int dwc3_uboot_interrupt_status(struct udevice *dev)
> Simply enable DM_USB_GADGET , then the drivers/usb/gadget/udc/udc-uclass.c
> dm_usb_gadget_handle_interrupts() is used which correctly invokes the
> per-controller IRQ handler. DWC3_GADGET should likely depend on
> DM_USB_GADGET.

Unfortunately, CI_UDC is not a DM driver yet and it depends on
!DM_USB_GADGET that's why I can't enable DM_USB_GADGET in that specific
case. I think NXP is working on changing that driver to DM (at least
they did that in their BSP). So my hope was to have this as intermediate
solution. Also in our case we use the DWC3 controller in host mode only,
so we don't need DWC3_GADGET at all.

Regards,
Stefan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller
  2026-08-24 23:45   ` Marek Vasut
@ 2026-08-26  7:16     ` Stefan Eichenberger
  2026-08-26 12:28       ` Marek Vasut
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-26  7:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke, u-boot

On Tue, Aug 25, 2026 at 01:45:08AM +0200, Marek Vasut wrote:
> On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> > From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > 
> > The i.MX95 SoC has two USB controllers, a DWC3 host-only controller and
> > a ChipIdea OTG controller. The latter is the one that can be used for
> > USB gadget functionality.
> 
> Both DWC3 and CI HDRC controllers are dual-role on MX95, are they not ?

That's correct we only use the DWC3 controller in host mode. I will
update the commit message in the next version to make that clear.

Regards,
Stefan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array
  2026-08-24 23:40   ` Marek Vasut
@ 2026-08-26  7:18     ` Stefan Eichenberger
  2026-08-26 12:28       ` Marek Vasut
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-26  7:18 UTC (permalink / raw)
  To: Marek Vasut
  Cc: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke, u-boot

On Tue, Aug 25, 2026 at 01:40:44AM +0200, Marek Vasut wrote:
> On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> > From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > 
> > On Verdin iMX95, with a USB hub permanently attached to the DWC3 host
> > port the hub itself enumerates fine but a USB stick plugged into it
> > fails intermittently:
> > 
> >    Verdin iMX95 # usb start
> >    starting USB...
> >    USB XHCI 1.10
> >    Device not responding to set address.
> > 
> >          USB device not accepting new address (error=80000000)
> >    Bus usb@4c100000: 2 USB Device(s) found
> >           scanning usb for storage devices... 0 Storage Device(s) found
> >    Verdin iMX95 # usb reset
> >    resetting USB...
> >    USB XHCI 1.10
> >    WARN endpoint is halted
> >    WARN endpoint is halted
> >    unable to get device descriptor (error=-22)
> > 
> > Commit c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in
> > both controller DT nodes") added a fallback that searches the DWC3
> > child node's "clock-names" for "ref"/"ref_clk" when it isn't found on
> > the parent glue node, but always resolves the found index against
> > glue->clks, a clk_bulk populated only from the parent glue node's own
> > clock-names list. This is wrong since the child node's clock-names list
> > is not guaranteed to be in the same order as the parent's, and indeed on
> > Verdin iMX95 the child node has a different order than the parent node.
> > 
> > Fix it by resolving the index against the child node's clk and ensure to
> > enable the clock before using it.
> > 
> > Fixes: c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in both controller DT nodes")
> > Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > ---
> >   drivers/usb/dwc3/dwc3-generic.c | 24 ++++++++++++++++++++++--
> >   1 file changed, 22 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
> > index 2356b3bc0aa..e16d236bd9d 100644
> > --- a/drivers/usb/dwc3/dwc3-generic.c
> > +++ b/drivers/usb/dwc3/dwc3-generic.c
> > @@ -31,6 +31,7 @@ struct dwc3_generic_priv {
> >   	struct dwc3 dwc3;
> >   	struct phy_bulk phys;
> >   	struct gpio_desc *ulpi_reset;
> > +	struct clk ref_clk;
> >   };
> >   struct dwc3_generic_host_priv {
> > @@ -76,9 +77,28 @@ static int dwc3_generic_probe(struct udevice *dev,
> >   		index = ofnode_stringlist_search(node, "clock-names", "ref");
> >   		if (index < 0)
> >   			index = ofnode_stringlist_search(node, "clock-names", "ref_clk");
> > -	}
> > -	if (index >= 0)
> > +		/*
> > +		 * glue->clks was populated from the parent glue node's own
> > +		 * clock-names list, which can differ in length/order from
> > +		 * this child node's list (e.g. i.MX95: glue has "hsio",
> > +		 * "suspend", the dwc3 child has "bus_early", "ref",
> > +		 * "suspend"). Reusing this index against glue->clks would
> > +		 * silently resolve to the wrong clock, so fetch it directly
> > +		 * from this node instead.
> > +		 */
> > +		if (index >= 0) {
> > +			if (!clk_get_by_index(dev, index, &priv->ref_clk)) {
> 
> Would it be possible to call clk_get_by_name(dev, ...) and
> clk_get_by_name(dev->parent, ...) instead, until one of them succeeds ? That
> could make the code simpler.
> 

You are right, I try to rework that in the next version. Thanks for the
suggestion. I will also remove/replace the debug() calls.

Regards,
Stefan


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET
  2026-08-26  7:15     ` Stefan Eichenberger
@ 2026-08-26 12:27       ` Marek Vasut
  2026-08-26 16:11       ` Tom Rini
  1 sibling, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2026-08-26 12:27 UTC (permalink / raw)
  To: Stefan Eichenberger
  Cc: u-boot, francesco.dolcini, trini, ilias.apalodimas, sbabic,
	festevam, uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke

On 8/26/26 9:15 AM, Stefan Eichenberger wrote:
> On Tue, Aug 25, 2026 at 01:33:27AM +0200, Marek Vasut wrote:
>> On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
>>> From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
>>>
>>> Building a board with USB_DWC3=y (DWC3 used purely as an XHCI host
>>> controller), USB_DWC3_GADGET unset, and DM_USB_GADGET disabled (e.g.
>>> to use CONFIG_CI_UDC for a separate ChipIdea gadget/OTG controller)
>>> fails to link:
>>>
>>> drivers/usb/gadget/ci_udc.o: in function `dm_usb_gadget_handle_interrupts':
>>> drivers/usb/gadget/ci_udc.c:983: multiple definition of `dm_usb_gadget_handle_interrupts';
>>> drivers/usb/dwc3/core.o:drivers/usb/dwc3/core.c:1034: first defined here
>>> drivers/usb/dwc3/core.o: in function `dm_usb_gadget_handle_interrupts':
>>> drivers/usb/dwc3/core.c:1044: undefined reference to `dwc3_gadget_uboot_handle_interrupt'
>>>
>>> Add "&& CONFIG_IS_ENABLED(USB_DWC3_GADGET)" to the guard so this code
>>> is only compiled when the DWC3 gadget driver it depends on is actually
>>> present, matching the Makefile dependency. Boards that combine DWC3
>>> (host) with a separate legacy gadget driver like CI_UDC, with
>>> DM_USB_GADGET disabled, now link correctly. Boards that already use
>>> DWC3 in gadget mode without DM_USB_GADGET are unaffected since
>>> USB_DWC3_GADGET is set for them.
>>>
>>> Fixes: 4d1589808970 ("usb: udc: dwc3: Fold board dm_usb_gadget_handle_interrupts() into DWC3 gadget")
>>> Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
>>> ---
>>>    drivers/usb/dwc3/core.c | 2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index be198041f08..9bff5149c5f 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -1016,7 +1016,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_GADGET)
>>> +#if !CONFIG_IS_ENABLED(DM_USB_GADGET) && CONFIG_IS_ENABLED(USB_DWC3_GADGET)
>>>    __weak int dwc3_uboot_interrupt_status(struct udevice *dev)
>> Simply enable DM_USB_GADGET , then the drivers/usb/gadget/udc/udc-uclass.c
>> dm_usb_gadget_handle_interrupts() is used which correctly invokes the
>> per-controller IRQ handler. DWC3_GADGET should likely depend on
>> DM_USB_GADGET.
> 
> Unfortunately, CI_UDC is not a DM driver yet and it depends on
> !DM_USB_GADGET that's why I can't enable DM_USB_GADGET in that specific
> case. I think NXP is working on changing that driver to DM (at least
> they did that in their BSP). So my hope was to have this as intermediate
> solution. Also in our case we use the DWC3 controller in host mode only,
> so we don't need DWC3_GADGET at all.
Let's convert the CI to DM and be done with it, esp. if there is 
existing code which does it.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array
  2026-08-26  7:18     ` Stefan Eichenberger
@ 2026-08-26 12:28       ` Marek Vasut
  0 siblings, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2026-08-26 12:28 UTC (permalink / raw)
  To: Stefan Eichenberger
  Cc: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke, u-boot

On 8/26/26 9:18 AM, Stefan Eichenberger wrote:
> On Tue, Aug 25, 2026 at 01:40:44AM +0200, Marek Vasut wrote:
>> On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
>>> From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
>>>
>>> On Verdin iMX95, with a USB hub permanently attached to the DWC3 host
>>> port the hub itself enumerates fine but a USB stick plugged into it
>>> fails intermittently:
>>>
>>>     Verdin iMX95 # usb start
>>>     starting USB...
>>>     USB XHCI 1.10
>>>     Device not responding to set address.
>>>
>>>           USB device not accepting new address (error=80000000)
>>>     Bus usb@4c100000: 2 USB Device(s) found
>>>            scanning usb for storage devices... 0 Storage Device(s) found
>>>     Verdin iMX95 # usb reset
>>>     resetting USB...
>>>     USB XHCI 1.10
>>>     WARN endpoint is halted
>>>     WARN endpoint is halted
>>>     unable to get device descriptor (error=-22)
>>>
>>> Commit c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in
>>> both controller DT nodes") added a fallback that searches the DWC3
>>> child node's "clock-names" for "ref"/"ref_clk" when it isn't found on
>>> the parent glue node, but always resolves the found index against
>>> glue->clks, a clk_bulk populated only from the parent glue node's own
>>> clock-names list. This is wrong since the child node's clock-names list
>>> is not guaranteed to be in the same order as the parent's, and indeed on
>>> Verdin iMX95 the child node has a different order than the parent node.
>>>
>>> Fix it by resolving the index against the child node's clk and ensure to
>>> enable the clock before using it.
>>>
>>> Fixes: c6583354b7c1 ("usb: dwc3: Look up reference clock DT phandle in both controller DT nodes")
>>> Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
>>> ---
>>>    drivers/usb/dwc3/dwc3-generic.c | 24 ++++++++++++++++++++++--
>>>    1 file changed, 22 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
>>> index 2356b3bc0aa..e16d236bd9d 100644
>>> --- a/drivers/usb/dwc3/dwc3-generic.c
>>> +++ b/drivers/usb/dwc3/dwc3-generic.c
>>> @@ -31,6 +31,7 @@ struct dwc3_generic_priv {
>>>    	struct dwc3 dwc3;
>>>    	struct phy_bulk phys;
>>>    	struct gpio_desc *ulpi_reset;
>>> +	struct clk ref_clk;
>>>    };
>>>    struct dwc3_generic_host_priv {
>>> @@ -76,9 +77,28 @@ static int dwc3_generic_probe(struct udevice *dev,
>>>    		index = ofnode_stringlist_search(node, "clock-names", "ref");
>>>    		if (index < 0)
>>>    			index = ofnode_stringlist_search(node, "clock-names", "ref_clk");
>>> -	}
>>> -	if (index >= 0)
>>> +		/*
>>> +		 * glue->clks was populated from the parent glue node's own
>>> +		 * clock-names list, which can differ in length/order from
>>> +		 * this child node's list (e.g. i.MX95: glue has "hsio",
>>> +		 * "suspend", the dwc3 child has "bus_early", "ref",
>>> +		 * "suspend"). Reusing this index against glue->clks would
>>> +		 * silently resolve to the wrong clock, so fetch it directly
>>> +		 * from this node instead.
>>> +		 */
>>> +		if (index >= 0) {
>>> +			if (!clk_get_by_index(dev, index, &priv->ref_clk)) {
>>
>> Would it be possible to call clk_get_by_name(dev, ...) and
>> clk_get_by_name(dev->parent, ...) instead, until one of them succeeds ? That
>> could make the code simpler.
>>
> 
> You are right, I try to rework that in the next version. Thanks for the
> suggestion. I will also remove/replace the debug() calls.
Excellent, thank you !

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller
  2026-08-26  7:16     ` Stefan Eichenberger
@ 2026-08-26 12:28       ` Marek Vasut
  0 siblings, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2026-08-26 12:28 UTC (permalink / raw)
  To: Stefan Eichenberger
  Cc: francesco.dolcini, trini, ilias.apalodimas, sbabic, festevam,
	uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke, u-boot

On 8/26/26 9:16 AM, Stefan Eichenberger wrote:
> On Tue, Aug 25, 2026 at 01:45:08AM +0200, Marek Vasut wrote:
>> On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
>>> From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
>>>
>>> The i.MX95 SoC has two USB controllers, a DWC3 host-only controller and
>>> a ChipIdea OTG controller. The latter is the one that can be used for
>>> USB gadget functionality.
>>
>> Both DWC3 and CI HDRC controllers are dual-role on MX95, are they not ?
> 
> That's correct we only use the DWC3 controller in host mode. I will
> update the commit message in the next version to make that clear.
Thank you.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET
  2026-08-26  7:15     ` Stefan Eichenberger
  2026-08-26 12:27       ` Marek Vasut
@ 2026-08-26 16:11       ` Tom Rini
  2026-08-27  8:41         ` Stefan Eichenberger
  1 sibling, 1 reply; 18+ messages in thread
From: Tom Rini @ 2026-08-26 16:11 UTC (permalink / raw)
  To: Stefan Eichenberger
  Cc: Marek Vasut, u-boot, francesco.dolcini, ilias.apalodimas, sbabic,
	festevam, uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke

[-- Attachment #1: Type: text/plain, Size: 3175 bytes --]

On Wed, Aug 26, 2026 at 09:15:01AM +0200, Stefan Eichenberger wrote:
> On Tue, Aug 25, 2026 at 01:33:27AM +0200, Marek Vasut wrote:
> > On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> > > From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > > 
> > > Building a board with USB_DWC3=y (DWC3 used purely as an XHCI host
> > > controller), USB_DWC3_GADGET unset, and DM_USB_GADGET disabled (e.g.
> > > to use CONFIG_CI_UDC for a separate ChipIdea gadget/OTG controller)
> > > fails to link:
> > > 
> > > drivers/usb/gadget/ci_udc.o: in function `dm_usb_gadget_handle_interrupts':
> > > drivers/usb/gadget/ci_udc.c:983: multiple definition of `dm_usb_gadget_handle_interrupts';
> > > drivers/usb/dwc3/core.o:drivers/usb/dwc3/core.c:1034: first defined here
> > > drivers/usb/dwc3/core.o: in function `dm_usb_gadget_handle_interrupts':
> > > drivers/usb/dwc3/core.c:1044: undefined reference to `dwc3_gadget_uboot_handle_interrupt'
> > > 
> > > Add "&& CONFIG_IS_ENABLED(USB_DWC3_GADGET)" to the guard so this code
> > > is only compiled when the DWC3 gadget driver it depends on is actually
> > > present, matching the Makefile dependency. Boards that combine DWC3
> > > (host) with a separate legacy gadget driver like CI_UDC, with
> > > DM_USB_GADGET disabled, now link correctly. Boards that already use
> > > DWC3 in gadget mode without DM_USB_GADGET are unaffected since
> > > USB_DWC3_GADGET is set for them.
> > > 
> > > Fixes: 4d1589808970 ("usb: udc: dwc3: Fold board dm_usb_gadget_handle_interrupts() into DWC3 gadget")
> > > Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > > ---
> > >   drivers/usb/dwc3/core.c | 2 +-
> > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > > index be198041f08..9bff5149c5f 100644
> > > --- a/drivers/usb/dwc3/core.c
> > > +++ b/drivers/usb/dwc3/core.c
> > > @@ -1016,7 +1016,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_GADGET)
> > > +#if !CONFIG_IS_ENABLED(DM_USB_GADGET) && CONFIG_IS_ENABLED(USB_DWC3_GADGET)
> > >   __weak int dwc3_uboot_interrupt_status(struct udevice *dev)
> > Simply enable DM_USB_GADGET , then the drivers/usb/gadget/udc/udc-uclass.c
> > dm_usb_gadget_handle_interrupts() is used which correctly invokes the
> > per-controller IRQ handler. DWC3_GADGET should likely depend on
> > DM_USB_GADGET.
> 
> Unfortunately, CI_UDC is not a DM driver yet and it depends on
> !DM_USB_GADGET that's why I can't enable DM_USB_GADGET in that specific
> case. I think NXP is working on changing that driver to DM (at least
> they did that in their BSP). So my hope was to have this as intermediate
> solution. Also in our case we use the DWC3 controller in host mode only,
> so we don't need DWC3_GADGET at all.

So the NXP downstream tree has a DM_USB_GADGET driver that needs to be
upstreamed, to solve this? We're quite a ways past where enhancing the
non-DM side things is the normal workflow.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET
  2026-08-26 16:11       ` Tom Rini
@ 2026-08-27  8:41         ` Stefan Eichenberger
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Eichenberger @ 2026-08-27  8:41 UTC (permalink / raw)
  To: Tom Rini
  Cc: Marek Vasut, u-boot, francesco.dolcini, ilias.apalodimas, sbabic,
	festevam, uboot-imx, marek.vasut+usb, alice.guo, antoine.gouby,
	stefan.eichenberger, emanuele.ghidoli, franz.schnyder,
	balaji.selvanathan, gurumoorthy.santhakumar, mkorpershoek,
	xypron.glpk, casey.connolly, hayashi.kunihiko, sean.anderson, sjg,
	ernest.vanhoecke

On Wed, Aug 26, 2026 at 10:11:02AM -0600, Tom Rini wrote:
> On Wed, Aug 26, 2026 at 09:15:01AM +0200, Stefan Eichenberger wrote:
> > On Tue, Aug 25, 2026 at 01:33:27AM +0200, Marek Vasut wrote:
> > > On 8/24/26 8:29 PM, Stefan Eichenberger wrote:
> > > > From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > > > 
> > > > Building a board with USB_DWC3=y (DWC3 used purely as an XHCI host
> > > > controller), USB_DWC3_GADGET unset, and DM_USB_GADGET disabled (e.g.
> > > > to use CONFIG_CI_UDC for a separate ChipIdea gadget/OTG controller)
> > > > fails to link:
> > > > 
> > > > drivers/usb/gadget/ci_udc.o: in function `dm_usb_gadget_handle_interrupts':
> > > > drivers/usb/gadget/ci_udc.c:983: multiple definition of `dm_usb_gadget_handle_interrupts';
> > > > drivers/usb/dwc3/core.o:drivers/usb/dwc3/core.c:1034: first defined here
> > > > drivers/usb/dwc3/core.o: in function `dm_usb_gadget_handle_interrupts':
> > > > drivers/usb/dwc3/core.c:1044: undefined reference to `dwc3_gadget_uboot_handle_interrupt'
> > > > 
> > > > Add "&& CONFIG_IS_ENABLED(USB_DWC3_GADGET)" to the guard so this code
> > > > is only compiled when the DWC3 gadget driver it depends on is actually
> > > > present, matching the Makefile dependency. Boards that combine DWC3
> > > > (host) with a separate legacy gadget driver like CI_UDC, with
> > > > DM_USB_GADGET disabled, now link correctly. Boards that already use
> > > > DWC3 in gadget mode without DM_USB_GADGET are unaffected since
> > > > USB_DWC3_GADGET is set for them.
> > > > 
> > > > Fixes: 4d1589808970 ("usb: udc: dwc3: Fold board dm_usb_gadget_handle_interrupts() into DWC3 gadget")
> > > > Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
> > > > ---
> > > >   drivers/usb/dwc3/core.c | 2 +-
> > > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > > > index be198041f08..9bff5149c5f 100644
> > > > --- a/drivers/usb/dwc3/core.c
> > > > +++ b/drivers/usb/dwc3/core.c
> > > > @@ -1016,7 +1016,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_GADGET)
> > > > +#if !CONFIG_IS_ENABLED(DM_USB_GADGET) && CONFIG_IS_ENABLED(USB_DWC3_GADGET)
> > > >   __weak int dwc3_uboot_interrupt_status(struct udevice *dev)
> > > Simply enable DM_USB_GADGET , then the drivers/usb/gadget/udc/udc-uclass.c
> > > dm_usb_gadget_handle_interrupts() is used which correctly invokes the
> > > per-controller IRQ handler. DWC3_GADGET should likely depend on
> > > DM_USB_GADGET.
> > 
> > Unfortunately, CI_UDC is not a DM driver yet and it depends on
> > !DM_USB_GADGET that's why I can't enable DM_USB_GADGET in that specific
> > case. I think NXP is working on changing that driver to DM (at least
> > they did that in their BSP). So my hope was to have this as intermediate
> > solution. Also in our case we use the DWC3 controller in host mode only,
> > so we don't need DWC3_GADGET at all.
> 
> So the NXP downstream tree has a DM_USB_GADGET driver that needs to be
> upstreamed, to solve this? We're quite a ways past where enhancing the
> non-DM side things is the normal workflow.

Okay, so we can only make this work if we first convert the UI_UDC
driver to a DM driver. Thanks for the input, I will see what we can do
about that.

Regards,
Stefan

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2026-08-27 12:54 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24 18:29 [PATCH v1 0/6] usb: fix DWC3/gadget issues and enable USB on Toradex i.MX95 boards Stefan Eichenberger
2026-08-24 18:29 ` [PATCH v1 1/6] usb: dwc3: core: only provide legacy gadget IRQ handler when USB_DWC3_GADGET Stefan Eichenberger
2026-08-24 23:33   ` Marek Vasut
2026-08-26  7:15     ` Stefan Eichenberger
2026-08-26 12:27       ` Marek Vasut
2026-08-26 16:11       ` Tom Rini
2026-08-27  8:41         ` Stefan Eichenberger
2026-08-24 18:29 ` [PATCH v1 2/6] usb: dwc3-generic: fix ref clock lookup indexing wrong clk_bulk array Stefan Eichenberger
2026-08-24 23:40   ` Marek Vasut
2026-08-26  7:18     ` Stefan Eichenberger
2026-08-26 12:28       ` Marek Vasut
2026-08-24 18:29 ` [PATCH v1 3/6] usb: skip host-only devices when picking the ehci gadget controller Stefan Eichenberger
2026-08-24 23:45   ` Marek Vasut
2026-08-26  7:16     ` Stefan Eichenberger
2026-08-26 12:28       ` Marek Vasut
2026-08-24 18:29 ` [PATCH v1 4/6] configs: verdin-imx95: enable CI_UDC usb gadget driver Stefan Eichenberger
2026-08-24 18:29 ` [PATCH v1 5/6] toradex: verdin-imx95: enable DWC3 USB controller support Stefan Eichenberger
2026-08-24 18:29 ` [PATCH v1 6/6] toradex: smarc-imx95: " Stefan Eichenberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox