usb: dwc3: Update soft-reset wait polling rate
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>
Thu, 8 Aug 2019 23:39:42 +0000 (16:39 -0700)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 9 Aug 2019 05:31:38 +0000 (08:31 +0300)
Starting from DWC_usb31 version 1.90a and later, the DCTL.CSFRST bit
will not be cleared until after all the internal clocks are synchronized
during soft-reset. This may take a little more than 50ms. Set the
polling rate at 20ms instead.

Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h

index 98bce85c29d0299f88687ddbc3fa425d604efeea..252c397860ef6422fe2a254585a0ce4a134c95e9 100644 (file)
@@ -252,12 +252,25 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
        reg |= DWC3_DCTL_CSFTRST;
        dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 
+       /*
+        * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit
+        * is cleared only after all the clocks are synchronized. This can
+        * take a little more than 50ms. Set the polling rate at 20ms
+        * for 10 times instead.
+        */
+       if (dwc3_is_usb31(dwc) && dwc->revision >= DWC3_USB31_REVISION_190A)
+               retries = 10;
+
        do {
                reg = dwc3_readl(dwc->regs, DWC3_DCTL);
                if (!(reg & DWC3_DCTL_CSFTRST))
                        goto done;
 
-               udelay(1);
+               if (dwc3_is_usb31(dwc) &&
+                   dwc->revision >= DWC3_USB31_REVISION_190A)
+                       msleep(20);
+               else
+                       udelay(1);
        } while (--retries);
 
        phy_exit(dwc->usb3_generic_phy);
@@ -267,11 +280,11 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
 
 done:
        /*
-        * For DWC_usb31 controller, once DWC3_DCTL_CSFTRST bit is cleared,
-        * we must wait at least 50ms before accessing the PHY domain
-        * (synchronization delay). DWC_usb31 programming guide section 1.3.2.
+        * For DWC_usb31 controller 1.80a and prior, once DCTL.CSFRST bit
+        * is cleared, we must wait at least 50ms before accessing the PHY
+        * domain (synchronization delay).
         */
-       if (dwc3_is_usb31(dwc))
+       if (dwc3_is_usb31(dwc) && dwc->revision <= DWC3_USB31_REVISION_180A)
                msleep(50);
 
        return 0;
index 3dd783b889cb9d4d43fb1064df53da61170768e5..1c8b349379af24fcd9c1e6e48e137799398363a7 100644 (file)
@@ -1137,6 +1137,8 @@ struct dwc3 {
 #define DWC3_USB31_REVISION_120A       (0x3132302a | DWC3_REVISION_IS_DWC31)
 #define DWC3_USB31_REVISION_160A       (0x3136302a | DWC3_REVISION_IS_DWC31)
 #define DWC3_USB31_REVISION_170A       (0x3137302a | DWC3_REVISION_IS_DWC31)
+#define DWC3_USB31_REVISION_180A       (0x3138302a | DWC3_REVISION_IS_DWC31)
+#define DWC3_USB31_REVISION_190A       (0x3139302a | DWC3_REVISION_IS_DWC31)
 
        u32                     version_type;