]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: dwc3: core: Disable USB2 retry for DWC_usb31 1.80a and prior
authorFaisal Hassan <quic_faisalh@quicinc.com>
Fri, 29 Nov 2024 17:34:22 +0000 (23:04 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Dec 2024 15:09:41 +0000 (16:09 +0100)
STAR 9001346572 addresses a USB 2.0 endpoint blocking issue in host mode
for controller versions DWC_usb31 1.70a and 1.80a. This issue affects
devices on both high-speed and full-speed bus instances. When all
endpoint caches are filled and a single active endpoint receives
continuous NAK responses, data transfers to other endpoints may get
blocked.

To resolve this, for controller versions DWC_usb31 1.70a and 1.80a, the
GUCTL3 bit[16] (USB2.0 Internal Retry Disable) is set to 1. This bit
disables the USB2.0 internal retry feature and ensures proper eviction
handling in the host controller endpoind cache. The GUCTL3[16] register
function is available only from DWC_usb31 version 1.70a.

Signed-off-by: Faisal Hassan <quic_faisalh@quicinc.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/20241129173422.20063-1-quic_faisalh@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h

index f219c82e9619d940300bda6d7cd01cca8977b578..c22b8678e02e4eb48f484e958480344d0342cd06 100644 (file)
@@ -1479,6 +1479,26 @@ static int dwc3_core_init(struct dwc3 *dwc)
                }
        }
 
+       /*
+        * STAR 9001346572: This issue affects DWC_usb31 versions 1.80a and
+        * prior. When an active endpoint not currently cached in the host
+        * controller is chosen to be cached to the same index as an endpoint
+        * receiving NAKs, the endpoint receiving NAKs enters continuous
+        * retry mode. This prevents it from being evicted from the host
+        * controller cache, blocking the new endpoint from being cached and
+        * serviced.
+        *
+        * To resolve this, for controller versions 1.70a and 1.80a, set the
+        * GUCTL3 bit[16] (USB2.0 Internal Retry Disable) to 1. This bit
+        * disables the USB2.0 internal retry feature. The GUCTL3[16] register
+        * function is available only from version 1.70a.
+        */
+       if (DWC3_VER_IS_WITHIN(DWC31, 170A, 180A)) {
+               reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+               reg |= DWC3_GUCTL3_USB20_RETRY_DISABLE;
+               dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+       }
+
        return 0;
 
 err_power_off_phy:
index 3be069c4520e2895131167721b1d09809ac14226..ff89df2cfb8a502bb91111eab708fa5245e38f93 100644 (file)
 
 /* Global User Control Register 3 */
 #define DWC3_GUCTL3_SPLITDISABLE               BIT(14)
+#define DWC3_GUCTL3_USB20_RETRY_DISABLE                BIT(16)
 
 /* Device Configuration Register */
 #define DWC3_DCFG_NUMLANES(n)  (((n) & 0x3) << 30) /* DWC_usb32 only */