[UBOOT PATCH 1/3] usb: dwc3: core: improve reset sequence

Eugen Hristev eugen.hristev at collabora.com
Mon Jun 19 15:26:29 CEST 2023


On 5/8/23 06:00, Venkatesh Yadav Abbarapu wrote:
> [ Felipe: Ported from Linux kernel commit
> 	  f59dcab17629 ("usb: dwc3: core: improve reset sequence") ]
> 
> According to Synopsys Databook, we shouldn't be relying on
> GCTL.CORESOFTRESET bit as that's only for debugging purposes.
> Instead, let's use DCTL.CSFTRST if we're OTG or PERIPHERAL mode.
> 
> Host side block will be reset by XHCI driver if necessary. Note that this
> reduces amount of time spent on dwc3_probe() by a long margin.
> 
> We're still gonna wait for reset to finish for a long time
> (default to 1ms max), but tests show that the reset polling loop executed
> at most 19 times (modprobe dwc3 && modprobe -r dwc3 executed 1000
> times in a row).
> 
> Without proper core reset, observing random issues like when the
> USB(DWC3) is in device mode, the host device is not able to detect the
> USB device.
> 
> Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu at amd.com>
> ---
>   drivers/usb/dwc3/core.c | 50 +++++++++++++++--------------------------
>   1 file changed, 18 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 49f6a1900b..8702a54efa 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -60,42 +60,28 @@ static void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
>   static int dwc3_core_soft_reset(struct dwc3 *dwc)
>   {
>   	u32		reg;
> +	int		retries = 1000;
>   
> -	/* Before Resetting PHY, put Core in Reset */
> -	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
> -	reg |= DWC3_GCTL_CORESOFTRESET;
> -	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
> -
> -	/* Assert USB3 PHY reset */
> -	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
> -	reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
> -	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
> -
> -	/* Assert USB2 PHY reset */
> -	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
> -	reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
> -	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
> -
> -	mdelay(100);
> -
> -	/* Clear USB3 PHY reset */
> -	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
> -	reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
> -	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
> -
> -	/* Clear USB2 PHY reset */
> -	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
> -	reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
> -	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
> +	/*
> +	 * We're resetting only the device side because, if we're in host mode,
> +	 * XHCI driver will reset the host block. If dwc3 was configured for
> +	 * host-only mode, then we can return early.
> +	 */
> +	if (dwc->dr_mode == USB_DR_MODE_HOST)
> +		return 0;
>   
> -	mdelay(100);
> +	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
> +	reg |= DWC3_DCTL_CSFTRST;
> +	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
>   
> -	/* After PHYs are stable we can take Core out of reset state */
> -	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
> -	reg &= ~DWC3_GCTL_CORESOFTRESET;
> -	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
> +	do {
> +		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
> +		if (!(reg & DWC3_DCTL_CSFTRST))
> +			return 0;
> +		udelay(1);
> +	} while (--retries);
>   
> -	return 0;
> +	return -ETIMEDOUT;
>   }
>   
>   /*

Hello Venkatesh, Michal,

I randomly found this patch while testing the Dwc3 on rockchip RK3588 , 
I noticed that you removed the code that resets the PHYs in this patch 
hence DWC3 is no longer starting in my case.
Was this intentional with this patch ?

Thanks,
Eugen


More information about the U-Boot mailing list