[PATCH v1 3/7] usb: ehci-mx6: Extract PHY initialization into reusable function

alice.guo at oss.nxp.com alice.guo at oss.nxp.com
Tue Dec 16 07:38:35 CET 2025


From: Alice Guo <alice.guo at nxp.com>

Extract USB PHY initialization code from ehci-mx6.c into a new function
ehci_mx6_phy_init() that can be shared with the ChipIdea UDC driver.

Signed-off-by: Alice Guo <alice.guo at nxp.com>
---
 drivers/usb/host/ehci-mx6.c | 73 ++++++++++++++++++++++++++++++++++++++++++++-
 include/usb/ci_udc.h        |  9 ++++++
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 03ff4ce10d5..52f14e6eca0 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -12,6 +12,7 @@
 #include <asm/global_data.h>
 #include <linux/compiler.h>
 #include <linux/delay.h>
+#include <usb/ci_udc.h>
 #include <usb/ehci-ci.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
@@ -168,6 +169,54 @@ static void __maybe_unused
 usb_power_config_mx7ulp(void *usbphy) { }
 #endif
 
+#if defined(CONFIG_IMX8)
+static void usb_power_config_imx8(void __iomem *usbphy_base)
+{
+	struct usbphy_regs __iomem *usbphy = (struct usbphy_regs __iomem *)usbphy_base;
+
+	if (!is_imx8())
+		return;
+
+	int timeout = 1000000;
+
+	if (!(readl(&usbphy->usb1_pll_480_ctrl) & PLL_USB_LOCK_MASK)) {
+		/* Enable the regulator first */
+		writel(PLL_USB_REG_ENABLE_MASK,
+		       &usbphy->usb1_pll_480_ctrl_set);
+
+		/* Wait at least 25us */
+		udelay(25);
+
+		/* Enable the power */
+		writel(PLL_USB_PWR_MASK, &usbphy->usb1_pll_480_ctrl_set);
+
+		/* Wait lock */
+		while (timeout--) {
+			if (readl(&usbphy->usb1_pll_480_ctrl) &
+			    PLL_USB_LOCK_MASK)
+				break;
+			udelay(10);
+		}
+
+		if (timeout <= 0) {
+			/* If timeout, we power down the pll */
+			writel(PLL_USB_PWR_MASK,
+			       &usbphy->usb1_pll_480_ctrl_clr);
+			return;
+		}
+	}
+
+	/* Clear the bypass */
+	writel(PLL_USB_BYPASS_MASK, &usbphy->usb1_pll_480_ctrl_clr);
+
+	/* Enable the PLL clock out to USB */
+	writel((PLL_USB_EN_USB_CLKS_MASK | PLL_USB_ENABLE_MASK),
+	       &usbphy->usb1_pll_480_ctrl_set);
+}
+#else
+static void __maybe_unused usb_power_config_imx8(void __iomem *usbphy_base) { }
+#endif
+
 #if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) || defined(CONFIG_IMXRT) || \
     defined(CONFIG_IMX8ULP)
 static const ulong phy_bases[] = {
@@ -276,7 +325,6 @@ static void ehci_mx6_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 	*reg = ehci_readl(status_reg);
 }
 
-#if !defined(CONFIG_PHY)
 /* Should be done in the MXS PHY driver */
 static void usb_oc_config(struct usbnc_regs *usbnc, int index)
 {
@@ -298,7 +346,30 @@ static void usb_oc_config(struct usbnc_regs *usbnc, int index)
 	clrbits_le32(ctrl, UCTRL_PWR_POL);
 #endif
 }
+
+void ehci_mx6_phy_init(struct usb_ehci *ehci, struct ehci_mx6_phy_data *phy_data, int index)
+{
+	u32 portsc;
+
+	portsc = readl(&ehci->portsc);
+	if (portsc & PORT_PTS_PHCD) {
+		debug("suspended: portsc %x, enabled it.\n", portsc);
+		clrbits_le32(&ehci->portsc, PORT_PTS_PHCD);
+	}
+
+	usb_power_config_mx6(phy_data->anatop_addr, index);
+	usb_power_config_mx7(phy_data->misc_addr);
+	usb_power_config_mx7ulp(phy_data->phy_addr);
+	usb_power_config_imx8(phy_data->phy_addr);
+
+	usb_oc_config(phy_data->misc_addr, index);
+
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) || defined(CONFIG_IMXRT) || \
+    defined(CONFIG_IMX8) || defined(CONFIG_IMX8ULP)
+	usb_internal_phy_clock_gate(phy_data->phy_addr, 1);
+	usb_phy_enable(ehci, phy_data->phy_addr);
 #endif
+}
 
 #if !CONFIG_IS_ENABLED(DM_USB)
 /**
diff --git a/include/usb/ci_udc.h b/include/usb/ci_udc.h
index 9f15dbabe53..ccef4daf741 100644
--- a/include/usb/ci_udc.h
+++ b/include/usb/ci_udc.h
@@ -6,7 +6,16 @@
 
 #ifndef __CI_UDC_H__
 #define __CI_UDC_H__
+#include <usb/ehci-ci.h>
 
 #define EP_MAX_PACKET_SIZE	0x200
 #define EP0_MAX_PACKET_SIZE	64
+
+struct ehci_mx6_phy_data {
+	void __iomem *phy_addr;
+	void __iomem *misc_addr;
+	void __iomem *anatop_addr;
+};
+
+void ehci_mx6_phy_init(struct usb_ehci *ehci, struct ehci_mx6_phy_data *phy_data, int index);
 #endif /* __CI_UDC_H__ */

-- 
2.43.0



More information about the U-Boot mailing list