Replace generic_setup_phy() to handle fsl,usbphy in addition to the
standard phys property.

This allows the USB controller of the i.MX7D to work in HSIC mode if the
following configs are enabled:

- CONFIG_NOP_PHY
- CONFIG_IMX_GPCV2_POWER_DOMAIN
- CONFIG_DM_REGULATOR_ANATOP

Signed-off-by: Nora Schiffer <[email protected]>
---
 drivers/usb/host/ehci-mx6.c | 47 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index eae18e22c57..c804af8ab45 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -571,6 +571,51 @@ static int ehci_usb_of_to_plat(struct udevice *dev)
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_PHY)
+/*
+ * ehci_mx6_setup_phy() is equivalent to generic_setup_phy(),
+ * but additionally supports fsl,usbphy
+ */
+static int ehci_mx6_setup_phy(struct udevice *dev)
+{
+       struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
+       struct ofnode_phandle_args args;
+       struct phy *phy = &priv->phy;
+       int ret;
+
+       ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "fsl,usbphy",
+                                            "#phy-cells", 0, 0, &args);
+
+       if (ret == -ENOENT)
+               ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "phys",
+                                                    "#phy-cells", 0, 0, &args);
+       if (ret)
+               return ret == -ENOENT ? 0 : ret;
+
+       ret = generic_phy_get_by_phandle_args(args, phy);
+       if (ret)
+               return ret == -ENOENT ? 0 : ret;
+
+       ret = generic_phy_init(phy);
+       if (ret)
+               return ret;
+
+       ret = generic_phy_set_mode(phy, PHY_MODE_USB_HOST, 0);
+       if (ret)
+               goto phys_mode_err;
+
+       ret = generic_phy_power_on(phy);
+       if (ret)
+               goto phys_mode_err;
+
+       return 0;
+
+phys_mode_err:
+       generic_phy_exit(phy);
+       return ret;
+}
+#endif
+
 static int mx6_parse_dt_addrs(struct udevice *dev)
 {
        struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
@@ -700,7 +745,7 @@ static int ehci_usb_probe(struct udevice *dev)
        usb_phy_enable(ehci, priv->phy_addr);
 #endif
 #else
-       ret = generic_setup_phy(dev, &priv->phy, 0, PHY_MODE_USB_HOST, 0);
+       ret = ehci_mx6_setup_phy(dev);
        if (ret)
                goto err_regulator;
 #endif
-- 
2.55.0

Reply via email to