usb: dwc3: Add support to reset usb ULPI phy
authorT Karthik Reddy <t.karthik.reddy@xilinx.com>
Fri, 8 Jul 2022 09:21:59 +0000 (11:21 +0200)
committerMarek Vasut <marex@denx.de>
Tue, 12 Jul 2022 19:59:54 +0000 (21:59 +0200)
When usb PHY initialization is done, the PHY need to be reset.

Signed-off-by: T Karthik Reddy <t.karthik.reddy@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
drivers/usb/dwc3/dwc3-generic.c

index c5310e4..466b25a 100644 (file)
@@ -26,6 +26,7 @@
 #include <reset.h>
 #include <clk.h>
 #include <usb/xhci.h>
+#include <asm/gpio.h>
 
 struct dwc3_glue_data {
        struct clk_bulk         clks;
@@ -43,6 +44,7 @@ struct dwc3_generic_priv {
        void *base;
        struct dwc3 dwc3;
        struct phy_bulk phys;
+       struct gpio_desc ulpi_reset;
 };
 
 struct dwc3_generic_host_priv {
@@ -78,6 +80,27 @@ static int dwc3_generic_probe(struct udevice *dev,
        if (rc && rc != -ENOTSUPP)
                return rc;
 
+       if (CONFIG_IS_ENABLED(DM_GPIO) &&
+           device_is_compatible(dev->parent, "xlnx,zynqmp-dwc3")) {
+               rc = gpio_request_by_name(dev->parent, "reset-gpios", 0,
+                                         &priv->ulpi_reset, GPIOD_ACTIVE_LOW);
+               if (rc)
+                       return rc;
+
+               /* Toggle ulpi to reset the phy. */
+               rc = dm_gpio_set_value(&priv->ulpi_reset, 1);
+               if (rc)
+                       return rc;
+
+               mdelay(5);
+
+               rc = dm_gpio_set_value(&priv->ulpi_reset, 0);
+               if (rc)
+                       return rc;
+
+               mdelay(5);
+       }
+
        if (device_is_compatible(dev->parent, "rockchip,rk3399-dwc3"))
                reset_deassert_bulk(&glue->resets);
 
@@ -99,6 +122,13 @@ static int dwc3_generic_remove(struct udevice *dev,
 {
        struct dwc3 *dwc3 = &priv->dwc3;
 
+       if (CONFIG_IS_ENABLED(DM_GPIO) &&
+           device_is_compatible(dev->parent, "xlnx,zynqmp-dwc3")) {
+               struct gpio_desc *ulpi_reset = &priv->ulpi_reset;
+
+               dm_gpio_free(ulpi_reset->dev, ulpi_reset);
+       }
+
        dwc3_remove(dwc3);
        dwc3_shutdown_phy(dev, &priv->phys);
        unmap_physmem(dwc3->regs, MAP_NOCACHE);