[PATCH 12/13] usb: ehci-mx6: Fix PHY power up issue on iMX8 platforms
peng.fan at nxp.com
peng.fan at nxp.com
Wed Sep 16 14:57:04 CEST 2020
From: Ye Li <ye.li at nxp.com>
On iMX8 platforms like 8QM/QXP, we must power up the USB PHY resource
before accessing the PHY. However, current init flow access the USB PHY
in ehci_mx6_common_init prior than ehci_usb_phy_mode where the PHY is power
up.
Fix the issue by adding ehci_get_usb_phy function to parse the PHY address
from DTB and power up the PHY before ehci_mx6_common_init.
Signed-off-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
drivers/usb/host/ehci-mx6.c | 58 +++++++++++++++++++++++++------------
1 file changed, 40 insertions(+), 18 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 7079750a93..080bde71d3 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -517,6 +517,7 @@ struct ehci_mx6_priv_data {
struct usb_ehci *ehci;
struct udevice *vbus_supply;
enum usb_init_type init_type;
+ void *__iomem phy_base;
int portnr;
};
@@ -592,11 +593,39 @@ int __weak board_ehci_usb_phy_mode(struct udevice *dev)
static int ehci_usb_phy_mode(struct udevice *dev)
{
struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
- void *__iomem addr = dev_read_addr_ptr(dev);
void *__iomem phy_ctrl, *__iomem phy_status;
+ u32 val;
+
+ if (is_mx6() || is_mx7ulp() || is_imx8()) {
+ phy_ctrl = (void __iomem *)(priv->phy_base + USBPHY_CTRL);
+ val = readl(phy_ctrl);
+
+ if (val & USBPHY_CTRL_OTG_ID)
+ priv->init_type = USB_INIT_DEVICE;
+ else
+ priv->init_type = USB_INIT_HOST;
+ } else if (is_mx7() || is_imx8mm() || is_imx8mn()) {
+ phy_status = (void __iomem *)(priv->phy_base +
+ USBNC_PHY_STATUS_OFFSET);
+ val = readl(phy_status);
+
+ if (val & USBNC_PHYSTATUS_ID_DIG)
+ priv->init_type = USB_INIT_DEVICE;
+ else
+ priv->init_type = USB_INIT_HOST;
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ehci_get_usb_phy(struct udevice *dev)
+{
+ struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
+ void *__iomem addr = (void *__iomem)devfdt_get_addr(dev);
const void *blob = gd->fdt_blob;
int offset = dev_of_offset(dev), phy_off;
- u32 val;
/*
* About fsl,usbphy, Refer to
@@ -627,23 +656,9 @@ static int ehci_usb_phy_mode(struct udevice *dev)
return ret;
}
#endif
-
- phy_ctrl = (void __iomem *)(addr + USBPHY_CTRL);
- val = readl(phy_ctrl);
-
- if (val & USBPHY_CTRL_OTG_ID)
- priv->init_type = USB_INIT_DEVICE;
- else
- priv->init_type = USB_INIT_HOST;
+ priv->phy_base = addr;
} else if (is_mx7() || is_imx8mm() || is_imx8mn()) {
- phy_status = (void __iomem *)(addr +
- USBNC_PHY_STATUS_OFFSET);
- val = readl(phy_status);
-
- if (val & USBNC_PHYSTATUS_ID_DIG)
- priv->init_type = USB_INIT_DEVICE;
- else
- priv->init_type = USB_INIT_HOST;
+ priv->phy_base = addr;
} else {
return -EINVAL;
}
@@ -765,6 +780,13 @@ static int ehci_usb_probe(struct udevice *dev)
if (ret)
debug("%s: No vbus supply\n", dev->name);
#endif
+
+ ret = ehci_get_usb_phy(dev);
+ if (ret) {
+ debug("%s: fail to get USB PHY base\n", dev->name);
+ return ret;
+ }
+
ret = ehci_mx6_common_init(ehci, priv->portnr);
if (ret)
return ret;
--
2.28.0
More information about the U-Boot
mailing list