aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAdam Ford2022-02-03 15:20:11 -0600
committerMarek Vasut2022-02-11 00:03:48 +0100
commit078dfef931523b64c1904517a1a6f04511fe42a2 (patch)
tree45188fa5e775a175eda0d7193df8d728a4bcf185 /drivers
parent2ccd2bc8c3580e00c51094c5cc2b3e2ead8d35c3 (diff)
usb: ehci-mx6: Enable OTG detection on imx8mm and imx8mn
The imx8mm and imx8mn appear compatible with imx7d-usb flags in the OTG driver. If the dr_mode is defined as host or peripheral, the device appears to operate correctly, however the auto host/peripheral detection results in an error. The solution isn't just adding checks for imx8mm and imx8mn to the check for imx7, because the USB clock needs to be running to read from the USBNC_PHY_STATUS_OFFSET register or it will hang. Marek requested that I not enable the clocks in ehci_usb_of_to_plat, so I modified that function to return an unknown state if the device tree does not explicitly state whether it is a host or a peripheral. When the driver probes, it looks to see if it's in the unknown state, and only then will it read the register to auto-detect. Signed-off-by: Adam Ford <aford173@gmail.com> Tested-by: Tim Harvey <tharvey@gateworks.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ehci-mx6.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 1bd6147c76a..060b02accc5 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -543,7 +543,7 @@ static int ehci_usb_phy_mode(struct udevice *dev)
plat->init_type = USB_INIT_DEVICE;
else
plat->init_type = USB_INIT_HOST;
- } else if (is_mx7()) {
+ } else if (is_mx7() || is_imx8mm() || is_imx8mn()) {
phy_status = (void __iomem *)(addr +
USBNC_PHY_STATUS_OFFSET);
val = readl(phy_status);
@@ -573,9 +573,8 @@ static int ehci_usb_of_to_plat(struct udevice *dev)
case USB_DR_MODE_PERIPHERAL:
plat->init_type = USB_INIT_DEVICE;
break;
- case USB_DR_MODE_OTG:
- case USB_DR_MODE_UNKNOWN:
- return ehci_usb_phy_mode(dev);
+ default:
+ plat->init_type = USB_INIT_UNKNOWN;
};
return 0;
@@ -677,6 +676,20 @@ static int ehci_usb_probe(struct udevice *dev)
mdelay(1);
#endif
+ /*
+ * If the device tree didn't specify host or device,
+ * the default is USB_INIT_UNKNOWN, so we need to check
+ * the register. For imx8mm and imx8mn, the clocks need to be
+ * running first, so we defer the check until they are.
+ */
+ if (priv->init_type == USB_INIT_UNKNOWN) {
+ ret = ehci_usb_phy_mode(dev);
+ if (ret)
+ goto err_clk;
+ else
+ priv->init_type = plat->init_type;
+ }
+
#if CONFIG_IS_ENABLED(DM_REGULATOR)
ret = device_get_supply_regulator(dev, "vbus-supply",
&priv->vbus_supply);
@@ -741,8 +754,8 @@ err_regulator:
#if CONFIG_IS_ENABLED(DM_REGULATOR)
if (priv->vbus_supply)
regulator_set_enable(priv->vbus_supply, false);
-err_clk:
#endif
+err_clk:
#if CONFIG_IS_ENABLED(CLK)
clk_disable(&priv->clk);
#else