[RFC 3/3] usb: ehci-omap: Enable phy drivers to enable/reset phy

Adam Ford aford173 at gmail.com
Mon Oct 4 02:24:07 CEST 2021


Several omap boards use CONFIG_OMAP_EHCI_PHYx_RESET_GPIO to pull
the phy out of reset, when this should really be done inside the
phy driver.  Add functions to determine which phys are associated
the EHCI driver, hold them in reset before EHCI is initialized,
initialize the EHCI, then release the phys from reset.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
This is an RFC because it hangs when generic_phy_get_bulk is called,
and more specifically dev_read_prop is hanging when called by
generic_phy_get_bulk.

The nop_phy shows before 'usb start' is run.
phy           0  [   ]   nop_phy               |-- hsusb2_phy

diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 324d2c0db1..3e707ccef5 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -17,7 +17,6 @@
 #include <usb/ulpi.h>
 #include <errno.h>
 #include <asm/io.h>
-#include <asm/gpio.h>
 #include <asm/arch/ehci.h>
 #include <asm/ehci-omap.h>
 #include <dm.h>
@@ -128,41 +127,6 @@ static void omap_ehci_soft_phy_reset(int port)
 }
 #endif
 
-#if defined(CONFIG_OMAP_EHCI_PHY1_RESET_GPIO) || \
-	defined(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO) || \
-	defined(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO)
-/* controls PHY(s) reset signal(s) */
-static inline void omap_ehci_phy_reset(int on, int delay)
-{
-	/*
-	 * Refer ISSUE1:
-	 * Hold the PHY in RESET for enough time till
-	 * PHY is settled and ready
-	 */
-	if (delay && !on)
-		udelay(delay);
-#ifdef CONFIG_OMAP_EHCI_PHY1_RESET_GPIO
-	gpio_request(CONFIG_OMAP_EHCI_PHY1_RESET_GPIO, "USB PHY1 reset");
-	gpio_direction_output(CONFIG_OMAP_EHCI_PHY1_RESET_GPIO, !on);
-#endif
-#ifdef CONFIG_OMAP_EHCI_PHY2_RESET_GPIO
-	gpio_request(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO, "USB PHY2 reset");
-	gpio_direction_output(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO, !on);
-#endif
-#ifdef CONFIG_OMAP_EHCI_PHY3_RESET_GPIO
-	gpio_request(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, "USB PHY3 reset");
-	gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, !on);
-#endif
-
-	/* Hold the PHY in RESET for enough time till DIR is high */
-	/* Refer: ISSUE1 */
-	if (delay && on)
-		udelay(delay);
-}
-#else
-#define omap_ehci_phy_reset(on, delay)	do {} while (0)
-#endif
-
 /*
  * Initialize the OMAP EHCI controller and PHY.
  * Based on "drivers/usb/host/ehci-omap.c" from Linux 3.1
@@ -180,9 +144,6 @@ int omap_ehci_hcd_init(int index, struct omap_usbhs_board_data *usbhs_pdata)
 	if (ret < 0)
 		return ret;
 
-	/* Put the PHY in RESET */
-	omap_ehci_phy_reset(1, 10);
-
 	ret = omap_uhh_reset();
 	if (ret < 0)
 		return ret;
@@ -260,8 +221,6 @@ int omap_ehci_hcd_init(int index, struct omap_usbhs_board_data *usbhs_pdata)
 		if (is_ehci_hsic_mode(usbhs_pdata->port_mode[i]))
 			omap_usbhs_hsic_init(i);
 
-	omap_ehci_phy_reset(0, 10);
-
 	/*
 	 * An undocumented "feature" in the OMAP3 EHCI controller,
 	 * causes suspended ports to be taken out of suspend when
@@ -337,7 +296,7 @@ struct ehci_omap_priv_data {
 #endif
 	enum usb_init_type init_type;
 	int portnr;
-	struct phy phy[OMAP_HS_USB_PORTS];
+	struct phy_bulk *phys;
 	int nports;
 };
 
@@ -356,6 +315,7 @@ static int omap_ehci_probe(struct udevice *dev)
 	struct ehci_omap_priv_data *priv = dev_get_priv(dev);
 	struct ehci_hccr *hccr;
 	struct ehci_hcor *hcor;
+	int i, ret;
 
 	priv->ehci = dev_read_addr_ptr(dev);
 	priv->portnr = dev_seq(dev);
@@ -364,7 +324,34 @@ static int omap_ehci_probe(struct udevice *dev)
 	hccr = (struct ehci_hccr *)&priv->ehci->hccapbase;
 	hcor = (struct ehci_hcor *)&priv->ehci->usbcmd;
 
-	return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+	/* Identify Phys */
+	ret = generic_phy_get_bulk(dev, priv->phys);
+	if (ret) {
+		printf("Failed to get bulk phys\n");
+		return ret;
+	}
+
+	/* Hold Phys in reset */
+	for (i = 0; i < priv->phys->count; i++) {
+		ret = generic_phy_reset(&priv->phys->phys[i]);
+		if (ret) {
+			printf("Failed to register EHCI\n");
+			return ret;
+		}
+	}
+
+	/* Register the EHCI */
+	ret = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+	if (ret) {
+		printf("Failed to register EHCI\n");
+		return ret;
+	}
+
+	/* Pull the phys out of reset */
+	ret = generic_phy_init_bulk(priv->phys);
+	if (ret)
+		printf("Failed to initialize phys\n");
+	return ret;
 }
 
 static const struct udevice_id omap_ehci_dt_ids[] = {
-- 
2.25.1



More information about the U-Boot mailing list