Re: usb: dwc3: some USB devices not working after 6.4.8

From: Thinh Nguyen
Date: Tue Sep 05 2023 - 21:32:56 EST


On Mon, Sep 04, 2023, Bagas Sanjaya wrote:
> On Sun, Sep 03, 2023 at 09:19:13PM +0900, Kenta Sato wrote:
> > Hi,
> >
> > I am using the FriendlyElec NanoPi R4S board.
> > When I update the kernel from 6.4.7 to 6.4.11, 6.4.13, and 6.5.1, it
> > doesn't recognize some USB devices.
> >
> > The board has two USB 3.0 ports. I connected 1) BUFFALO USB Flash Disk
> > (high-speed) and 2) NETGEAR A6210 (SuperSpeed) to each port.
> > 1) is often not recognized. On the other hand, 2) was working while I
> > was testing.
> > Regardless of whether a USB device is connected, I could see the below
> > message on dmesg:
> >
> > [ 0.740993] phy phy-ff7c0000.phy.8: phy poweron failed --> -110
> > [ 0.741585] dwc3 fe800000.usb: error -ETIMEDOUT: failed to initialize core
> > [ 0.742334] dwc3: probe of fe800000.usb failed with error -110
> > [ 0.751635] rockchip-usb2phy ff770000.syscon:usb2phy@e460:
> > Requested PHY is disabled
> >
> > Is there any idea on this?
> >
> > The cause seems to be related to this commit. I tried reverting this
> > change and the issue seemed to be solved.
> >
> > >From 317d6e4c12b46bde61248ea4ab5e19f68cbd1c57 Mon Sep 17 00:00:00 2001
> > From: Jisheng Zhang <jszhang@xxxxxxxxxx>
> > Date: Wed, 28 Jun 2023 00:20:18 +0800
> > Subject: usb: dwc3: don't reset device side if dwc3 was configured as
> > host-only
> >
> > commit e835c0a4e23c38531dcee5ef77e8d1cf462658c7 upstream.
> >
> > Commit c4a5153e87fd ("usb: dwc3: core: Power-off core/PHYs on
> > system_suspend in host mode") replaces check for HOST only dr_mode with
> > current_dr_role. But during booting, the current_dr_role isn't
> > initialized, thus the device side reset is always issued even if dwc3
> > was configured as host-only. What's more, on some platforms with host
> > only dwc3, aways issuing device side reset by accessing device register
> > block can cause kernel panic.
> >
> > Fixes: c4a5153e87fd ("usb: dwc3: core: Power-off core/PHYs on
> > system_suspend in host mode")
> > Cc: stable <stable@xxxxxxxxxx>
> > Signed-off-by: Jisheng Zhang <jszhang@xxxxxxxxxx>
> > Acked-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx>
> > Link: https://lore.kernel.org/r/20230627162018.739-1-jszhang@xxxxxxxxxx
> > Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> > ---
> > drivers/usb/dwc3/core.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.4.8&id=317d6e4c12b46bde61248ea4ab5e19f68cbd1c57
> >
>
> Thanks for the regression report. I'm adding it to regzbot:
>
> #regzbot ^introduced: e835c0a4e23c38
> #regzbot title: some USB devices unrecognized caused by not resetting dwc3 device if it is host-only
>

When there's phy reconfiguration, we need follow through a soft reset
sequence. It may be done when we pass to xHCI driver through its
initialization of USBCMD.HCRST. However, looks like we need to do a
soft reset before setting more core parameters in dwc3.

Can we try to just reset the phy instead to see if it helps? If not, we
may have to teach dwc3 about xHCI's USBCMD.HCRST.

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 9c6bf054f15d..66186ef34c6d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1104,9 +1104,42 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (ret)
goto err_exit_ulpi;

- ret = dwc3_core_soft_reset(dwc);
- if (ret)
- goto err_exit_phy;
+ /*
+ * Note: GUSB3PIPECTL[n] and GUSB2PHYCFG[n] are port settings where n
+ * is port index. If this is a multiport host, then we need to reset
+ * all active ports.
+ */
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+ reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+
+ /*
+ * Must meet usb3 phy reset assertion timing,
+ * should be much less than 20ms.
+ */
+ msleep(20);
+
+ reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+ /*
+ * Must meet usb2 phy reset assertion timing,
+ * should be much less than 20ms.
+ */
+ msleep(20);
+
+ reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+ /*
+ * Some platforms may need more time to synchronize the clocks,
+ * 100ms should be enough for all.
+ */
+ msleep(100);

if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) {


--

Thanks,
Thinh