diff mbox series

[10/19] usb: ehci-mx6: Parse USB PHY and MISC offsets from DT

Message ID 20210402124812.186761-10-marex@denx.de
State Superseded
Delegated to: Marek Vasut
Headers show
Series [01/19] phy: nop-phy: Add standard usb-nop-xceiv compat string | expand

Commit Message

Marek Vasut April 2, 2021, 12:48 p.m. UTC
In case DM and OF controler is enabled, but PHY support is disabled,
parse USB PHY and MISC component addresses from DT manually. Those
component addresses will be used in subsequent patches to access the
ANATOP, PHY and MISC registers matching the controller and thus get
rid of the ad-hoc controller sequence number mapping.

Fixes: 4de51cc25b5 ("usb: ehci-mx6: Drop assignment of sequence number")
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Ye Li <ye.li@nxp.com>
Cc: uboot-imx <uboot-imx@nxp.com>
---
 drivers/usb/host/ehci-mx6.c | 59 +++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)
diff mbox series

Patch

diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index b0703502db0..008dca9bae7 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -417,6 +417,12 @@  struct ehci_mx6_priv_data {
 	struct clk clk;
 	enum usb_init_type init_type;
 	int portnr;
+#if !defined(CONFIG_PHY)
+	/* Legacy iMX6/iMX7/iMX7ULP compat, they do not use PHY framework yet */
+	void __iomem *phy_addr;
+	void __iomem *misc_addr;
+	void __iomem *anatop_addr;
+#endif
 };
 
 static int mx6_init_after_reset(struct ehci_ctrl *dev)
@@ -571,6 +577,55 @@  static int ehci_usb_bind(struct udevice *dev)
 	return 0;
 }
 
+static int mx6_parse_dt_addrs(struct udevice *dev)
+{
+#if !defined(CONFIG_PHY)
+	/*
+	 * Parse USB PHY/MISC/ANATOP addresses out of DT on platforms
+	 * which do not use PHY framework yet, that is MX6/MX7/MX7ULP.
+	 */
+	struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
+	int phy_off, misc_off, anatop_off;
+	const void *blob = gd->fdt_blob;
+	int offset = dev_of_offset(dev);
+	void *__iomem addr;
+
+	phy_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbphy");
+	if (phy_off < 0)
+		return -EINVAL;
+
+	misc_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbmisc");
+	if (misc_off < 0)
+		return -EINVAL;
+
+	addr = (void __iomem *)fdtdec_get_addr(blob, phy_off, "reg");
+	if ((fdt_addr_t)addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->phy_addr = addr;
+
+	addr = (void __iomem *)fdtdec_get_addr(blob, misc_off, "reg");
+	if ((fdt_addr_t)addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->misc_addr = addr;
+
+#if defined(CONFIG_MX6)
+	/* Resolve ANATOP offset through USB PHY node */
+	anatop_off = fdtdec_lookup_phandle(blob, phy_off, "fsl,anatop");
+	if (anatop_off < 0)
+		return -EINVAL;
+
+	addr = (void __iomem *)fdtdec_get_addr(blob, anatop_off, "reg");
+	if ((fdt_addr_t)addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->anatop_addr = addr;
+#endif
+#endif
+	return 0;
+}
+
 static int ehci_usb_probe(struct udevice *dev)
 {
 	struct usb_plat *plat = dev_get_plat(dev);
@@ -589,6 +644,10 @@  static int ehci_usb_probe(struct udevice *dev)
 		}
 	}
 
+	ret = mx6_parse_dt_addrs(dev);
+	if (ret)
+		return ret;
+
 	priv->ehci = ehci;
 	priv->portnr = dev_seq(dev);
 	priv->init_type = type;