[PATCH] usb: host: ehci-generic: check for companion controller

Fabrice Gasnier fabrice.gasnier at foss.st.com
Wed Aug 30 10:00:08 CEST 2023


EHCI is usually used with companion controller (like OHCI) as companion
controller. This information on the companion is missing currently in
companion drivers.
So, if the usb-uclass isn't aware, it may scan busses in any order: OHCI
first, then EHCI.
This is seen on STM32MP1 where DT probing makes the probe order to occur
by increasing address (OHCI address < EHCI address).

When a low speed or full-speed device is plugged in, it's not detected as
EHCI should first detect it, and give ownership (handover) to OHCI.

Current situation on STM32MP1 (with a low speed device plugged-in)
STM32MP> usb start
starting USB...
Bus usb at 5800c000: USB OHCI 1.0
Bus usb at 5800d000: USB EHCI 1.00
scanning bus usb at 5800c000 for devices... 1 USB Device(s) found
scanning bus usb at 5800d000 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found

The "companion" property in the device tree allow to retrieve companion
controller information, from the EHCI node. This allow marking the
companion driver as such.

With this patch (same low speed device plugged in):
STM32MP> usb start
starting USB...
Bus usb at 5800c000: USB OHCI 1.0
Bus usb at 5800d000: USB EHCI 1.00
scanning bus usb at 5800d000 for devices... 1 USB Device(s) found
scanning bus usb at 5800c000 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
STM32MP> usb tree
USB device tree:
  1  Hub (12 Mb/s, 0mA)
  |   U-Boot Root Hub
  |
  +-2  Human Interface (1.5 Mb/s, 100mA)
       HP HP USB 1000dpi Laser Mouse

  1  Hub (480 Mb/s, 0mA)
     u-boot EHCI Host Controller

This also optimize bus scan when a High speed device is plugged in, as
the usb-uclass skips OHCI in this case:

STM32MP> usb reset
resetting USB...
Bus usb at 5800c000: USB OHCI 1.0
Bus usb at 5800d000: USB EHCI 1.00
scanning bus usb at 5800d000 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
STM32MP> usb tree
USB device tree:
  1  Hub (480 Mb/s, 0mA)
  |  u-boot EHCI Host Controller
  |
  +-2  Mass Storage (480 Mb/s, 200mA)
       SanDisk Cruzer Blade 03003432021922011407

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---

 drivers/usb/host/ehci-generic.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index a765a307a323..539c0d0e61bc 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -66,6 +66,7 @@ static int ehci_usb_probe(struct udevice *dev)
 	struct ehci_hccr *hccr;
 	struct ehci_hcor *hcor;
 	int err, ret;
+	struct udevice *companion_dev;
 
 	err = 0;
 	ret = clk_get_bulk(dev, &priv->clocks);
@@ -104,6 +105,29 @@ static int ehci_usb_probe(struct udevice *dev)
 	hcor = (struct ehci_hcor *)((uintptr_t)hccr +
 				    HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 
+	/*
+	 * Enforce optional companion controller is marked as such. This allows
+	 * the bus scan in usb-uclass to 1st scan the primary controller,
+	 * before the companion controller (ownership is given to companion
+	 * when low or full speed devices have been detected).
+	 */
+	err = uclass_get_device_by_phandle(UCLASS_USB, dev, "companion", &companion_dev);
+	if (!err) {
+		struct usb_bus_priv *companion_bus_priv;
+
+		dev_dbg(companion_dev, "companion of %s\n", dev->name);
+		companion_bus_priv = dev_get_uclass_priv(companion_dev);
+		companion_bus_priv->companion = true;
+	} else if (err && err != -ENOENT && err != -ENODEV) {
+		/*
+		 * Treat everything else than no companion or disabled
+		 * companion as an error. (It may not be enabled on boards
+		 * that have a High-Speed HUB to handle FS and LS traffic).
+		 */
+		dev_err(dev, "Failed to get companion (err=%d)\n", err);
+		goto phy_err;
+	}
+
 	err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
 	if (err)
 		goto phy_err;
-- 
2.25.1



More information about the U-Boot mailing list