Enable USBH2 and USBH3 in uboot environment on custom carrier board

Hello, we try to use the USBH2 and the USBH3 for usb update of the Apalis iMX8QM.
But we can’t find these USB ports in the device tree in uboot.
We know that both USB ports are connected via the Microchip USB3503A.

This is the output of usb reset/start:

resetting USB...
Bus usb@5b0d0000: USB EHCI 1.00
Bus usbh3: XHCI-imx8 init hccr 0x000000005b130000 and hcor 0x000000005b130080 hc_length 128
Register 2000820 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus usb@5b0d0000 for devices... 1 USB Device(s) found
scanning bus usbh3 for devices... 4 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found

But these two ports are already connected on our custom carrier board and can’t be used for a usb update.

Now we are looking for a solution to use the USBH2 and/or the USBH3 for the usb update.
The usb ports are powered on (Voltage of 5V can be measured) via PIN 84.

Additional information:

U-Boot 2022.04-6.6.0+git.d262075124dc (Mar 08 2024 - 14:27:40 +0000)

CPU:   NXP i.MX8QM RevB A53 at 1200 MHz at 38C

DRAM:  4 GiB
Core:  194 devices, 20 uclasses, devicetree: separate
MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Model: Toradex 0047 Apalis iMX8QM 4GB IT V1.1B
Serial#: 06738708

 BuildInfo: 
  - SCFW 6638c032, SECO-FW c9de51c0, IMX-MKIMAGE 3bfcfccb, ATF 3c1583b
  - U-Boot 2022.04-6.6.0+git.d262075124dc 

Under linux all usb ports are working.

Do we have to adjust the uboot devicetree or compile configuration?

Thank you in advance.

Best regards
Alex

Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello,

Thank you for reaching out with your question about the USB configuration on the Apalis iMX8X. Based on the available documentation, USBH2 and USBH3 are connected through a Microchip USB5744T USB 3.1 Gen 1 hub. Here are the specific pin assignments for these interfaces:

For USBH2:

  • USB data pins (D+/D-) are on X1 pins 80/82.
  • SuperSpeed signals are on pins 85/83 (RX) and 91/89 (TX).

For USBH3:

  • USB data pins (D+/D-) are on X1 pins 86/88.
  • SuperSpeed signals are on pins 62/64 (RX) and 68/70 (TX).

While I don’t have specific information about modifying the U-Boot device tree or compile configuration to enable these ports, since you mentioned that all ports are working under Linux, you might consider the following steps:

  1. Use the printenv command in U-Boot to check the environment variables related to USB configurations.
  2. Compare the working Linux device tree configuration with your U-Boot device tree to identify any discrepancies.

If you need further guidance on U-Boot configuration or have other questions, feel free to ask!

Best regards,
Toradex AI Assistant

Hello @abest,

As you mentioned, on the Apalis iMX8, the USBH2 and USBH3 ports go through an on-module USB hub.
This USB hub is not configured on u-boot and this is the reason that the devices are not seen via these USB ports on u-boot.

It is likely that adding its configuration to the u-boot device tree is enough to get it to work, but additional changes may be needed.
You can see how we configure this for Linux on the following file: https://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi?h=toradex_5.15-2.2.x-imx#n898
Please note that this is not just done in the linked line, but throughout this file when we have USB HSIC mentioned.

Best Regards,
Bruno

Hey @bruno.tx,

thank you for you suggestion. I’m working at the same problem as Alex. We created the following patch for the u-boot-toradex recipe in yocto:

diff --git a/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi b/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi
index 22b34c8febe..d122ac25a59 100644
--- a/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi
+++ b/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0+ OR X11
+
 /*
  * Copyright 2019 Toradex AG
  */
@@ -208,3 +209,32 @@
 &usdhc3 {
        u-boot,dm-pre-proper;
 };
+
+&{/mu@5d1c0000/iomuxc/apalis-imx8} {
+       /* On-module USB HSIC HUB (active) */
+       pinctrl_usb_hsic_active: usbh1activegrp {
+               fsl,pins =
+                       <SC_P_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA                0x000000cf>,
+                       <SC_P_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE            0x000000ff>;
+       };
+
+       /* On-module USB HSIC HUB (idle) */
+       pinctrl_usb_hsic_idle: usbh1idlegrp {
+               fsl,pins =
+                       <SC_P_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA                0x000000cf>,
+                       <SC_P_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE            0x000000cf>;
+       };
+};
+
+/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */
+&usbh1 {
+       adp-disable;
+       disable-over-current;
+       hnp-disable;
+       pinctrl-names = "idle", "active";
+       pinctrl-0 = <&pinctrl_usb_hsic_idle>;
+       pinctrl-1 = <&pinctrl_usb_hsic_active>;
+       srp-disable;
+       status = "okay";
+       vbus-supply = <&reg_usb_host_vbus>;
+};

We cloned this from the linux kernel device tree and adapted the macro names from the the file pads-imx8qm.h, because the prefix differs (IMX8QMSC_P).

Everything compiles fine and the new USB hub is also found if we run usb start in the u-boot console, but then an undefined error occurs:

Apalis iMX8 # usb start
starting USB...
Bus usb@5b0d0000: USB EHCI 1.00
Bus usb@5b0e0000: "Synchronous Abort" handler, esr 0x96000007
elr: 0000000080075df4 lr : 0000000080075de4 (reloc)
elr: 00000000ffededf4 lr : 00000000ffedede4
x0 : 0000000000000090 x1 : 0000000000000001
x2 : 0000000000000001 x3 : 0000000000000020
x4 : 00000000fd674570 x5 : 0000000000000020
x6 : 00000000ffecd568 x7 : 00000000fd674410
x8 : 00000000fd674990 x9 : 0000000000000008
x10: 000000000000d000 x11: 00000000fd67442c
x12: 000000000000a3a8 x13: 0000000000000000
x14: 00000000fd674990 x15: 0000000000000021
x16: 00000000ffecd568 x17: 0000000000000000
x18: 00000000fd686d90 x19: 000000005b0e0000
x20: 0000000000000000 x21: 00000000fd6b32b0
x22: 000000005b0e0000 x23: 00000000fff0ae54
x24: 00000000fd6b31d0 x25: 0000000000000000
x26: 00000000fd674990 x27: 000000000000b310
x28: 00000000fd6935d0 x29: 00000000fd6745b0

Code: 530c7c00 121c0c00 7102401f 54000281 (b940a280)
Resetting CPU ...

resetting ...

I’ve also tried to patch the u-boot defconfig by adding the following to configs/apalis-imx8_defconfig in the u-boot-toradex recipe:

+CONFIG_CMD_USB=y
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_HSIC=y
+CONFIG_DM_USB_DEBUG=y

This has no effect and also CONFIG_DM_USB_DEBUG=y does not produce a more verbose error message.

Do you have any advice or idea what else we can try to get the USB hub accessible from u-boot?

Thank you very much in advance for your help.

Best regards
Andreas

Hello @andi1337,

I think the USB hub may be powered off or in reset state at this point and for this reason you get the error above.
Please check the following additional configurations present in the linux device tree which are likely also needed on u-boot:

Best Regards,
Bruno

Hey @bruno.tx,

thank you very much for your help and your suggestion. I’ve tried to add the mentioned device tree nodes, but the error message remains:

Apalis iMX8 # usb start
starting USB...
Bus usb@5b0d0000: USB EHCI 1.00
Bus usb@5b0e0000: "Synchronous Abort" handler, esr 0x96000007
elr: 0000000080075df4 lr : 0000000080075de4 (reloc)
elr: 00000000ffededf4 lr : 00000000ffedede4
x0 : 0000000000000090 x1 : 0000000000000001
x2 : 0000000000000001 x3 : 0000000000000020
x4 : 00000000fd673ef0 x5 : 0000000000000020
x6 : 00000000ffecd568 x7 : 00000000fd673d90
x8 : 00000000fd674310 x9 : 0000000000000008
x10: 000000000000d1f4 x11: 00000000fd673dac
x12: 000000000000a55c x13: 0000000000000000
x14: 00000000fd674310 x15: 0000000000000021
x16: 00000000ffecd568 x17: 0000000000000000
x18: 00000000fd686d90 x19: 000000005b0e0000
x20: 0000000000000000 x21: 00000000fd6b2630
x22: 000000005b0e0000 x23: 00000000fff0ae54
x24: 00000000fd6b2550 x25: 0000000000000000
x26: 00000000fd674310 x27: 000000000000b4c4
x28: 00000000fd693930 x29: 00000000fd673f30

Code: 530c7c00 121c0c00 7102401f 54000281 (b940a280)
Resetting CPU ...

resetting ...

The u-boot version is U-Boot 2022.04-6.1.0-devel+git.d262075124dc (Mar 08 2024 - 14:27:40 +0000). The complete patch for the u-boot device tree looks like this at the moment:

diff --git a/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi b/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi
index 22b34c8febe..a125884b4da 100644
--- a/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi
+++ b/arch/arm/dts/fsl-imx8qm-apalis-u-boot.dtsi
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0+ OR X11
+
 /*
  * Copyright 2019 Toradex AG
  */
@@ -6,6 +7,8 @@
 	aliases {
 		usbhost1 = &usbh3;
 		usbgadget0 = &usbg1;
+		lsiosubsys = &lsio_subsys;
+		usbh1 = &usbh1;
 	};
 
 	usbh3: usbh3 {
@@ -22,6 +25,48 @@
 		status = "okay";
 		u-boot,dm-pre-proper;
 	};
+
+	lsio_subsys: bus@5d000000 {
+		
+		lsio_gpio0: gpio@5d080000 {
+			u-boot,dm-pre-proper;
+			compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+			reg = <0x5d080000 0x10000>;
+			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			power-domains = <&pd_lsio_gpio0>;
+			status = "okay";
+		};
+
+		lsio_gpio1: gpio@5d090000 {
+			u-boot,dm-pre-proper;
+			compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+			reg = <0x5d090000 0x10000>;
+			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			power-domains = <&pd_lsio_gpio1>;
+			status = "okay";
+		};
+	};
+
+	reg_usb_hsic: regulator-usb-hsic {
+			compatible = "regulator-fixed";
+			regulator-name = "usb-hsic-dummy";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+	};
+	reg_usb_phy: regulator-usb-hsic1 {
+			compatible = "regulator-fixed";
+			regulator-name = "usb-phy-dummy";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+	};
 };
 
 &{/imx8qm-pm} {
@@ -208,3 +253,75 @@
 &usdhc3 {
 	u-boot,dm-pre-proper;
 };
+
+&iomuxc {
+	/* On-module USB HSIC HUB (active) */
+	pinctrl_usb_hsic_active: usbh1activegrp {
+		fsl,pins =
+			<SC_P_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA		0x000000cf>,
+			<SC_P_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE		0x000000ff>;
+	};
+
+	/* On-module USB HSIC HUB (idle) */
+	pinctrl_usb_hsic_idle: usbh1idlegrp {
+		fsl,pins =
+			<SC_P_USB_HSIC0_DATA_CONN_USB_HSIC0_DATA		0x000000cf>,
+			<SC_P_USB_HSIC0_STROBE_CONN_USB_HSIC0_STROBE		0x000000cf>;
+	};
+
+	/* On-module USB HSIC HUB */
+	pinctrl_usb3503a: usb3503agrp {
+		fsl,pins =
+			/* On-module HSIC_HUB_CONNECT */
+			<SC_P_SCU_GPIO0_03_LSIO_GPIO0_IO31			0x00000041>,
+			/* On-module HSIC_INT_N */
+			<SC_P_SCU_GPIO0_05_LSIO_GPIO1_IO01			0x00000021>,
+			/* On-module HSIC_RESET_N */
+			<SC_P_SCU_GPIO0_06_LSIO_GPIO1_IO02			0x00000041>;
+	};
+
+		/* Apalis USBH_EN */
+	pinctrl_usbh_en: usbhengrp {
+		fsl,pins =
+			<SC_P_USB_SS3_TC1_LSIO_GPIO4_IO04			0x00000021>;
+	};
+};
+
+/* On-module I2C */
+&i2c1 {
+	/* USB3503A */
+	usb3503@8 {
+		u-boot,dm-pre-proper;
+		compatible = "smsc,usb3503a";
+		connect-gpios = <&lsio_gpio0 31 GPIO_ACTIVE_LOW>;
+		initial-mode = <1>;
+		intn-gpios = <&lsio_gpio1 1 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usb3503a>;
+		refclk-frequency = <25000000>;
+		reg = <0x08>;
+		reset-gpios = <&lsio_gpio1 2 GPIO_ACTIVE_LOW>;
+		status = "okay";
+	};
+};
+
+/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */
+&usbh1 {
+	u-boot,dm-pre-proper;
+	adp-disable;
+	disable-over-current;
+	hnp-disable;
+	pinctrl-names = "idle", "active";
+	pinctrl-0 = <&pinctrl_usb_hsic_idle>;
+	pinctrl-1 = <&pinctrl_usb_hsic_active>;
+	srp-disable;
+	status = "okay";
+	vbus-supply = <&reg_usb_host_vbus>;
+};
+
+&usbphynop2 {
+	vcc-supply = <&reg_usb_phy>;
+	vbus-supply = <&reg_usb_hsic>;
+	status = "okay";
+};
+

I have also added the u-boot,drm-pre-proper property to some nodes and set the status to okay, but it is frustrating that it still does not work. I am running the Apalis with the Ixora Evaluation Board V1.3A. I will try to measure the voltage of the corresponding USB port to see if this is still the problem.

I’m unfortunately not a device tree expert either, so I apologize in advance for any obvious errors. Fortunately, the dtsi already compiles once after my changes ^^

Do you have any additional idea what we can try next?
Many thanks in advance.

Best regards
Andreas

Hello @andi1337,

I looked a bit more into this and it looks like u-boot does not have a driver for the USB3503A hub.
At least a minimal part of the initialization logic for this IC would be needed to be added on u-boot.
This should be doable in the board_late_init function on the board initialization file board/toradex/apalis-imx8/apalis-imx8.c.

There, it is likely that you will need to configure the GPIOs under pinctrl_usb3503a to follow the initialization sequence.
The HSIC reference clock is always on from a reference clock in the SoM.
Looking at the linux driver may help to better understand what is needed on the initialization: usb3503.c « misc « usb « drivers - linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules
It does not look to complex for this USB hub, but some work and testing will be needed.

Best Regards,
Bruno

Hello @bruno.tx,

Thanks a lot for your input and the helpful pointers regarding the USB3503A initialization in U-Boot.

I’ve implemented the suggested initialization logic in the board_late_init() function within board/toradex/apalis-imx8/apalis-imx8.c, including the GPIO configuration for USBH_EN, RESET_N, and CONNECT, following the sequence outlined in the Linux driver (usb3503.c). I also verified that the I2C1 bus is active and accessible in U-Boot, and I’m using the correct GPIO numbers based on the LSIO mappings.

However, despite all of this, the USB3503A still does not respond to I2C probes at address 0x08. I’ve confirmed that:

  • The GPIOs are toggled correctly (verified via debug output and manual testing in the U-Boot shell)
  • The USBH_EN signal is set high
  • The reset and connect sequence is executed with appropriate delays
  • The I2C bus is functional and other devices respond as expected

Given that, I suspect the issue might be related to either:

  1. The USB3503A not being properly powered (though USBH_EN is high), or
  2. The 25 MHz reference clock not being active during U-Boot, despite the assumption that it is always on from the SoM

Do you happen to know if the reference clock for the USB3503A is guaranteed to be active during U-Boot on the Apalis iMX8? Or is there any additional clock or power domain configuration required in U-Boot to ensure the hub is operational?

Any further insights or suggestions would be greatly appreciated.

Best regards,
Andi

Function to perform the initialization sequence called in the function board_late_init(void) as a last command:

#if defined(CONFIG_IMX8QM)

#define USB3503_I2C_ADDR 0x08

// GPIO definitions based on LSIO GPIOs
#define GPIO_USBH_EN     132  // LSIO_GPIO4_IO04
#define GPIO_USB_CONNECT 31   // LSIO_GPIO0_IO31
#define GPIO_USB_RESET   34   // LSIO_GPIO1_IO02
#define GPIO_USB_INTN    33   // LSIO_GPIO1_IO01 (optional)

int initialize_usb3503a_hub(void)
{
    int ret;

    printf("USB3503A: Starting USB hub initialization...\n");

    // Enable USBH_EN (power supply to the hub)
    ret = gpio_request(GPIO_USBH_EN, "usbh_en");
    if (!ret) {
        gpio_direction_output(GPIO_USBH_EN, 1);
        printf("USB3503A: USBH_EN set to HIGH\n");
    } else {
        printf("USB3503A: Failed to request USBH_EN GPIO: %d\n", ret);
    }

    // Request GPIOs for RESET and CONNECT
    gpio_request(GPIO_USB_RESET, "usb_reset");
    gpio_request(GPIO_USB_CONNECT, "usb_connect");

    // Perform reset sequence
    gpio_direction_output(GPIO_USB_RESET, 0);   // Assert reset (LOW)
    gpio_direction_output(GPIO_USB_CONNECT, 0); // Disconnect (LOW)
    mdelay(10);

    gpio_set_value(GPIO_USB_RESET, 1);          // Deassert reset (HIGH)
    mdelay(10);

    gpio_set_value(GPIO_USB_CONNECT, 1);        // Connect (HIGH)
    mdelay(10);

    // Optional: Probe the USB3503A via I2C
    struct udevice *bus, *dev;
    ret = uclass_get_device_by_seq(UCLASS_I2C, 1, &bus); // I2C1 is typically bus 1
    if (ret) {
        printf("USB3503A: I2C bus 1 not found: %d\n", ret);
        return 0; // Not fatal
    }

    ret = dm_i2c_probe(bus, USB3503_I2C_ADDR, 0, &dev);
    if (ret) {
        printf("USB3503A: Device not found at I2C bus %s address 0x08: %d\n", bus->name, ret);
    } else {
        printf("USB3503A: Device successfully detected at I2C address 0x08\n");
    }

    return 0;
}

#else
__maybe_unused void initialize_usb3503a_hub(void) { }
#endif

My u-boot snippet to scan the i2c1 bus on the u-boot console for the address 0x08 (-> the USB hub)

   env set usb_hub_init '\
      gpio clear 132 && \
      sleep 1 \
      gpio set 132 && \
      gpio clear 34 && \
      gpio clear 31 && \
      sleep 0.01 && \
      gpio set 34 && \
      sleep 0.01 && \
      gpio set 31 && \
      sleep 0.01 && \
      i2c dev 1 && \
      i2c probe'
saveenv
run usb_hub_init

# The returned valid chip addresses are empty :-(

Hello @andi1337,

The reference clock is driven by an IC which is fed directly by the 3.3V rail within the SoM, so I believe it will be up in u-boot.
The USB3503A hub is powered by this same rail and another internal rail.

Double-checking our schematics, I saw the following note:

INT_N needs to be driven low during reset release in order to strap the correct input clock frequency

So maybe this is also needed on your initialization code.

Best Regards,
Bruno

Hello @bruno.tx,

thanks again for your help. I also tried to set INT_N to low, but unfortunately this does not change the behavior when calling usb start. I also tried changing some things in the device tree and also ported the complete usb3503 driver from the linux-toradex kernel to u-boot, but nothing changes.

I have observed that when I run this code from the u-boot console, after calling reboot from the running Linux, I get 0x08 as the valid chip address.

env set usb_hub_init '\
    i2c dev 1 && \
    echo “Delete USB_INTNT” && gpio clear 33 && \
    echo “Disconnect” && gpio set 31 && \
    echo “Start reset” && gpio clear 34 && \
    sleep 0.1 && \
    echo “Stop reset” && gpio set 34 && \
    echo “Connect” && gpio clear 31 && \
    sleep 0.1 && \
    i2c probe'
run usb_hub_init

The I2C communication now seems to work. But even this does not solve the error.

At this point I will give up and not invest any more time in this topic. We will probably be forced to find another alternative.

Many thanks again and best regards
Andreas

P.S.: For everyone who is interested, here is the current patch for the u-boot-toradex recipe:
0006_most_promising_usb.patch (11.7 KB)