summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2018-11-01 00:30:47 -0700
committerNitin Garg <nitin.garg@nxp.com>2018-11-02 20:50:10 -0500
commit477dd3a2cbd73a0ff67cbf15e1e6b7809864b516 (patch)
treea3696451d51c08960a743774131a7168338b943f /drivers
parentb84752f6de6c7dd74bd93c641b12f48e9846c8ab (diff)
MLK-20160-1 usb: ehci-mx6: Fix PHY power up issue on iMX8 platforms
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@nxp.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ehci-mx6.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 8f9d90a5ac..d04f703afa 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -526,6 +526,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;
};
@@ -595,11 +596,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 = (void *__iomem)devfdt_get_addr(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()) {
+ 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
@@ -628,23 +657,9 @@ static int ehci_usb_phy_mode(struct udevice *dev)
return -EINVAL;
}
#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()) {
- 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;
}
@@ -719,6 +734,12 @@ static int ehci_usb_probe(struct udevice *dev)
if (ret)
debug("%s: No vbus supply\n", dev->name);
+ 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;