diff mbox series

usb: dwc3: Add support to reset usb ULPI phy

Message ID a47c6e52ff9de2035402b042a0369a5eea876708.1645628815.git.michal.simek@xilinx.com
State Superseded
Delegated to: Bin Meng
Headers show
Series usb: dwc3: Add support to reset usb ULPI phy | expand

Commit Message

Michal Simek Feb. 23, 2022, 3:06 p.m. UTC
From: T Karthik Reddy <t.karthik.reddy@xilinx.com>

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@xilinx.com>
---

 drivers/usb/dwc3/Kconfig        |  2 +-
 drivers/usb/dwc3/dwc3-generic.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

Comments

Marek Vasut Feb. 23, 2022, 5:31 p.m. UTC | #1
On 2/23/22 16:06, Michal Simek wrote:
> From: T Karthik Reddy <t.karthik.reddy@xilinx.com>
> 
> 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@xilinx.com>
> ---
> 
>   drivers/usb/dwc3/Kconfig        |  2 +-
>   drivers/usb/dwc3/dwc3-generic.c | 28 ++++++++++++++++++++++++++++
>   2 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index 62aa65bf0cd2..685bda3729e5 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -25,7 +25,7 @@ config USB_DWC3_OMAP
>   
>   config USB_DWC3_GENERIC
>   	bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
> -	depends on DM_USB && USB_DWC3 && MISC
> +	depends on DM_USB && USB_DWC3 && MISC && DM_GPIO
>   	help
>   	  Select this for Xilinx ZynqMP and similar Platforms.
>   	  This wrapper supports Host and Peripheral operation modes.
> diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
> index b1e019b5b91a..17d35a6dc60c 100644
> --- a/drivers/usb/dwc3/dwc3-generic.c
> +++ b/drivers/usb/dwc3/dwc3-generic.c
> @@ -25,6 +25,7 @@
>   #include <reset.h>
>   #include <clk.h>
>   #include <usb/xhci.h>
> +#include <asm/gpio.h>
>   
>   struct dwc3_glue_data {
>   	struct clk_bulk		clks;
> @@ -42,6 +43,7 @@ struct dwc3_generic_priv {
>   	void *base;
>   	struct dwc3 dwc3;
>   	struct phy_bulk phys;
> +	struct gpio_desc ulpi_reset;
>   };
>   
>   struct dwc3_generic_host_priv {
> @@ -77,6 +79,26 @@ static int dwc3_generic_probe(struct udevice *dev,
>   	if (rc && rc != -ENOTSUPP)
>   		return rc;
>   
> +	if (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 != -EBUSY && 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);
>   
> @@ -98,6 +120,12 @@ static int dwc3_generic_remove(struct udevice *dev,
>   {
>   	struct dwc3 *dwc3 = &priv->dwc3;
>   
> +	if (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);

CC Bin please.
Bin Meng March 3, 2022, 8:47 a.m. UTC | #2
On Wed, Feb 23, 2022 at 11:07 PM Michal Simek <michal.simek@xilinx.com> wrote:
>
> From: T Karthik Reddy <t.karthik.reddy@xilinx.com>
>
> 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@xilinx.com>
> ---
>
>  drivers/usb/dwc3/Kconfig        |  2 +-
>  drivers/usb/dwc3/dwc3-generic.c | 28 ++++++++++++++++++++++++++++
>  2 files changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index 62aa65bf0cd2..685bda3729e5 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -25,7 +25,7 @@ config USB_DWC3_OMAP
>
>  config USB_DWC3_GENERIC
>         bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
> -       depends on DM_USB && USB_DWC3 && MISC
> +       depends on DM_USB && USB_DWC3 && MISC && DM_GPIO
>         help
>           Select this for Xilinx ZynqMP and similar Platforms.
>           This wrapper supports Host and Peripheral operation modes.
> diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
> index b1e019b5b91a..17d35a6dc60c 100644
> --- a/drivers/usb/dwc3/dwc3-generic.c
> +++ b/drivers/usb/dwc3/dwc3-generic.c
> @@ -25,6 +25,7 @@
>  #include <reset.h>
>  #include <clk.h>
>  #include <usb/xhci.h>
> +#include <asm/gpio.h>
>
>  struct dwc3_glue_data {
>         struct clk_bulk         clks;
> @@ -42,6 +43,7 @@ struct dwc3_generic_priv {
>         void *base;
>         struct dwc3 dwc3;
>         struct phy_bulk phys;
> +       struct gpio_desc ulpi_reset;
>  };
>
>  struct dwc3_generic_host_priv {
> @@ -77,6 +79,26 @@ static int dwc3_generic_probe(struct udevice *dev,
>         if (rc && rc != -ENOTSUPP)
>                 return rc;
>
> +       if (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 != -EBUSY && rc)
> +                       return rc;

What happens if rc == -EBUSY?

> +
> +               /* 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);
>
> @@ -98,6 +120,12 @@ static int dwc3_generic_remove(struct udevice *dev,
>  {
>         struct dwc3 *dwc3 = &priv->dwc3;
>
> +       if (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);
>

Regards,
Bin
T Karthik Reddy March 4, 2022, 11:35 a.m. UTC | #3
Hi Bin Meng,

> -----Original Message-----
> From: Bin Meng <bmeng.cn@gmail.com>
> Sent: Thursday, March 3, 2022 2:18 PM
> To: Michal Simek <michals@xilinx.com>
> Cc: U-Boot Mailing List <u-boot@lists.denx.de>; git <git@xilinx.com>; T
> Karthik Reddy <tkarthik@xilinx.com>; Angus Ainslie <angus@akkea.ca>;
> Kunihiko Hayashi <hayashi.kunihiko@socionext.com>; Marek Vasut
> <marex@denx.de>; Michael Walle <michael@walle.cc>; Priyanka Jain
> <priyanka.jain@nxp.com>; Simon Glass <sjg@chromium.org>
> Subject: Re: [PATCH] usb: dwc3: Add support to reset usb ULPI phy
> 
> On Wed, Feb 23, 2022 at 11:07 PM Michal Simek <michal.simek@xilinx.com>
> wrote:
> >
> > From: T Karthik Reddy <t.karthik.reddy@xilinx.com>
> >
> > 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@xilinx.com>
> > ---
> >
> >  drivers/usb/dwc3/Kconfig        |  2 +-
> >  drivers/usb/dwc3/dwc3-generic.c | 28
> ++++++++++++++++++++++++++++
> >  2 files changed, 29 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index
> > 62aa65bf0cd2..685bda3729e5 100644
> > --- a/drivers/usb/dwc3/Kconfig
> > +++ b/drivers/usb/dwc3/Kconfig
> > @@ -25,7 +25,7 @@ config USB_DWC3_OMAP
> >
> >  config USB_DWC3_GENERIC
> >         bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
> > -       depends on DM_USB && USB_DWC3 && MISC
> > +       depends on DM_USB && USB_DWC3 && MISC && DM_GPIO
> >         help
> >           Select this for Xilinx ZynqMP and similar Platforms.
> >           This wrapper supports Host and Peripheral operation modes.
> > diff --git a/drivers/usb/dwc3/dwc3-generic.c
> > b/drivers/usb/dwc3/dwc3-generic.c index b1e019b5b91a..17d35a6dc60c
> > 100644
> > --- a/drivers/usb/dwc3/dwc3-generic.c
> > +++ b/drivers/usb/dwc3/dwc3-generic.c
> > @@ -25,6 +25,7 @@
> >  #include <reset.h>
> >  #include <clk.h>
> >  #include <usb/xhci.h>
> > +#include <asm/gpio.h>
> >
> >  struct dwc3_glue_data {
> >         struct clk_bulk         clks;
> > @@ -42,6 +43,7 @@ struct dwc3_generic_priv {
> >         void *base;
> >         struct dwc3 dwc3;
> >         struct phy_bulk phys;
> > +       struct gpio_desc ulpi_reset;
> >  };
> >
> >  struct dwc3_generic_host_priv {
> > @@ -77,6 +79,26 @@ static int dwc3_generic_probe(struct udevice *dev,
> >         if (rc && rc != -ENOTSUPP)
> >                 return rc;
> >
> > +       if (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 != -EBUSY && rc)
> > +                       return rc;
> 
> What happens if rc == -EBUSY?

Every time we do usb reset, gpio is requested again and returns EBUSY.
We want to avoid returning probe with error, if rc == -EBUSY.

Thanks
T Karthik

> 
> > +
> > +               /* 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);
> >
> > @@ -98,6 +120,12 @@ static int dwc3_generic_remove(struct udevice
> > *dev,  {
> >         struct dwc3 *dwc3 = &priv->dwc3;
> >
> > +       if (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);
> >
> 
> Regards,
> Bin
Bin Meng March 4, 2022, 2:45 p.m. UTC | #4
On Fri, Mar 4, 2022 at 7:36 PM T Karthik Reddy <tkarthik@xilinx.com> wrote:
>
> Hi Bin Meng,
>
> > -----Original Message-----
> > From: Bin Meng <bmeng.cn@gmail.com>
> > Sent: Thursday, March 3, 2022 2:18 PM
> > To: Michal Simek <michals@xilinx.com>
> > Cc: U-Boot Mailing List <u-boot@lists.denx.de>; git <git@xilinx.com>; T
> > Karthik Reddy <tkarthik@xilinx.com>; Angus Ainslie <angus@akkea.ca>;
> > Kunihiko Hayashi <hayashi.kunihiko@socionext.com>; Marek Vasut
> > <marex@denx.de>; Michael Walle <michael@walle.cc>; Priyanka Jain
> > <priyanka.jain@nxp.com>; Simon Glass <sjg@chromium.org>
> > Subject: Re: [PATCH] usb: dwc3: Add support to reset usb ULPI phy
> >
> > On Wed, Feb 23, 2022 at 11:07 PM Michal Simek <michal.simek@xilinx.com>
> > wrote:
> > >
> > > From: T Karthik Reddy <t.karthik.reddy@xilinx.com>
> > >
> > > 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@xilinx.com>
> > > ---
> > >
> > >  drivers/usb/dwc3/Kconfig        |  2 +-
> > >  drivers/usb/dwc3/dwc3-generic.c | 28
> > ++++++++++++++++++++++++++++
> > >  2 files changed, 29 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index
> > > 62aa65bf0cd2..685bda3729e5 100644
> > > --- a/drivers/usb/dwc3/Kconfig
> > > +++ b/drivers/usb/dwc3/Kconfig
> > > @@ -25,7 +25,7 @@ config USB_DWC3_OMAP
> > >
> > >  config USB_DWC3_GENERIC
> > >         bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
> > > -       depends on DM_USB && USB_DWC3 && MISC
> > > +       depends on DM_USB && USB_DWC3 && MISC && DM_GPIO
> > >         help
> > >           Select this for Xilinx ZynqMP and similar Platforms.
> > >           This wrapper supports Host and Peripheral operation modes.
> > > diff --git a/drivers/usb/dwc3/dwc3-generic.c
> > > b/drivers/usb/dwc3/dwc3-generic.c index b1e019b5b91a..17d35a6dc60c
> > > 100644
> > > --- a/drivers/usb/dwc3/dwc3-generic.c
> > > +++ b/drivers/usb/dwc3/dwc3-generic.c
> > > @@ -25,6 +25,7 @@
> > >  #include <reset.h>
> > >  #include <clk.h>
> > >  #include <usb/xhci.h>
> > > +#include <asm/gpio.h>
> > >
> > >  struct dwc3_glue_data {
> > >         struct clk_bulk         clks;
> > > @@ -42,6 +43,7 @@ struct dwc3_generic_priv {
> > >         void *base;
> > >         struct dwc3 dwc3;
> > >         struct phy_bulk phys;
> > > +       struct gpio_desc ulpi_reset;
> > >  };
> > >
> > >  struct dwc3_generic_host_priv {
> > > @@ -77,6 +79,26 @@ static int dwc3_generic_probe(struct udevice *dev,
> > >         if (rc && rc != -ENOTSUPP)
> > >                 return rc;
> > >
> > > +       if (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 != -EBUSY && rc)
> > > +                       return rc;
> >
> > What happens if rc == -EBUSY?
>
> Every time we do usb reset, gpio is requested again and returns EBUSY.
> We want to avoid returning probe with error, if rc == -EBUSY.
>

What about the very first time it returns EBUSY?

Regards,
Bin
Michal Simek March 4, 2022, 3:10 p.m. UTC | #5
On 3/4/22 15:45, Bin Meng wrote:
> On Fri, Mar 4, 2022 at 7:36 PM T Karthik Reddy <tkarthik@xilinx.com> wrote:
>>
>> Hi Bin Meng,
>>
>>> -----Original Message-----
>>> From: Bin Meng <bmeng.cn@gmail.com>
>>> Sent: Thursday, March 3, 2022 2:18 PM
>>> To: Michal Simek <michals@xilinx.com>
>>> Cc: U-Boot Mailing List <u-boot@lists.denx.de>; git <git@xilinx.com>; T
>>> Karthik Reddy <tkarthik@xilinx.com>; Angus Ainslie <angus@akkea.ca>;
>>> Kunihiko Hayashi <hayashi.kunihiko@socionext.com>; Marek Vasut
>>> <marex@denx.de>; Michael Walle <michael@walle.cc>; Priyanka Jain
>>> <priyanka.jain@nxp.com>; Simon Glass <sjg@chromium.org>
>>> Subject: Re: [PATCH] usb: dwc3: Add support to reset usb ULPI phy
>>>
>>> On Wed, Feb 23, 2022 at 11:07 PM Michal Simek <michal.simek@xilinx.com>
>>> wrote:
>>>>
>>>> From: T Karthik Reddy <t.karthik.reddy@xilinx.com>
>>>>
>>>> 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@xilinx.com>
>>>> ---
>>>>
>>>>   drivers/usb/dwc3/Kconfig        |  2 +-
>>>>   drivers/usb/dwc3/dwc3-generic.c | 28
>>> ++++++++++++++++++++++++++++
>>>>   2 files changed, 29 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index
>>>> 62aa65bf0cd2..685bda3729e5 100644
>>>> --- a/drivers/usb/dwc3/Kconfig
>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>> @@ -25,7 +25,7 @@ config USB_DWC3_OMAP
>>>>
>>>>   config USB_DWC3_GENERIC
>>>>          bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
>>>> -       depends on DM_USB && USB_DWC3 && MISC
>>>> +       depends on DM_USB && USB_DWC3 && MISC && DM_GPIO
>>>>          help
>>>>            Select this for Xilinx ZynqMP and similar Platforms.
>>>>            This wrapper supports Host and Peripheral operation modes.
>>>> diff --git a/drivers/usb/dwc3/dwc3-generic.c
>>>> b/drivers/usb/dwc3/dwc3-generic.c index b1e019b5b91a..17d35a6dc60c
>>>> 100644
>>>> --- a/drivers/usb/dwc3/dwc3-generic.c
>>>> +++ b/drivers/usb/dwc3/dwc3-generic.c
>>>> @@ -25,6 +25,7 @@
>>>>   #include <reset.h>
>>>>   #include <clk.h>
>>>>   #include <usb/xhci.h>
>>>> +#include <asm/gpio.h>
>>>>
>>>>   struct dwc3_glue_data {
>>>>          struct clk_bulk         clks;
>>>> @@ -42,6 +43,7 @@ struct dwc3_generic_priv {
>>>>          void *base;
>>>>          struct dwc3 dwc3;
>>>>          struct phy_bulk phys;
>>>> +       struct gpio_desc ulpi_reset;
>>>>   };
>>>>
>>>>   struct dwc3_generic_host_priv {
>>>> @@ -77,6 +79,26 @@ static int dwc3_generic_probe(struct udevice *dev,
>>>>          if (rc && rc != -ENOTSUPP)
>>>>                  return rc;
>>>>
>>>> +       if (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 != -EBUSY && rc)
>>>> +                       return rc;
>>>
>>> What happens if rc == -EBUSY?
>>
>> Every time we do usb reset, gpio is requested again and returns EBUSY.
>> We want to avoid returning probe with error, if rc == -EBUSY.
>>
> 
> What about the very first time it returns EBUSY?

Was chatting with Karthik. We have free gpio in remove function that this stayed 
there and we forget to remove it. It is not needed when you free gpio.

I sent v2 already.

Thanks,
Michal
diff mbox series

Patch

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 62aa65bf0cd2..685bda3729e5 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -25,7 +25,7 @@  config USB_DWC3_OMAP
 
 config USB_DWC3_GENERIC
 	bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
-	depends on DM_USB && USB_DWC3 && MISC
+	depends on DM_USB && USB_DWC3 && MISC && DM_GPIO
 	help
 	  Select this for Xilinx ZynqMP and similar Platforms.
 	  This wrapper supports Host and Peripheral operation modes.
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index b1e019b5b91a..17d35a6dc60c 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -25,6 +25,7 @@ 
 #include <reset.h>
 #include <clk.h>
 #include <usb/xhci.h>
+#include <asm/gpio.h>
 
 struct dwc3_glue_data {
 	struct clk_bulk		clks;
@@ -42,6 +43,7 @@  struct dwc3_generic_priv {
 	void *base;
 	struct dwc3 dwc3;
 	struct phy_bulk phys;
+	struct gpio_desc ulpi_reset;
 };
 
 struct dwc3_generic_host_priv {
@@ -77,6 +79,26 @@  static int dwc3_generic_probe(struct udevice *dev,
 	if (rc && rc != -ENOTSUPP)
 		return rc;
 
+	if (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 != -EBUSY && 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);
 
@@ -98,6 +120,12 @@  static int dwc3_generic_remove(struct udevice *dev,
 {
 	struct dwc3 *dwc3 = &priv->dwc3;
 
+	if (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);