brcm2708: update to latest patches from RPi foundation
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0666-xhci-Use-more-event-ring-segment-table-entries.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0666-xhci-Use-more-event-ring-segment-table-entries.patch b/target/linux/brcm2708/patches-4.19/950-0666-xhci-Use-more-event-ring-segment-table-entries.patch
new file mode 100644 (file)
index 0000000..0949f97
--- /dev/null
@@ -0,0 +1,60 @@
+From c2e02902a3b75b24306dac06cb6f75b683fa0267 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.org>
+Date: Tue, 13 Aug 2019 15:53:29 +0100
+Subject: [PATCH] xhci: Use more event ring segment table entries
+
+Users have reported log spam created by "Event Ring Full" xHC event
+TRBs. These are caused by interrupt latency in conjunction with a very
+busy set of devices on the bus. The errors are benign, but throughput
+will suffer as the xHC will pause processing of transfers until the
+event ring is drained by the kernel. Expand the number of event TRB slots
+available by increasing the number of event ring segments in the ERST.
+
+Controllers have a hardware-defined limit as to the number of ERST
+entries they can process, so make the actual number in use
+min(ERST_MAX_SEGS, hw_max).
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
+---
+ drivers/usb/host/xhci-mem.c | 8 +++++---
+ drivers/usb/host/xhci.h     | 4 ++--
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2495,9 +2495,11 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+        * Event ring setup: Allocate a normal ring, but also setup
+        * the event ring segment table (ERST).  Section 4.9.3.
+        */
++      val2 = 1 << HCS_ERST_MAX(xhci->hcs_params2);
++      val2 = min_t(unsigned int, ERST_MAX_SEGS, val2);
+       xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Allocating event ring");
+-      xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, 1, TYPE_EVENT,
+-                                      0, flags);
++      xhci->event_ring = xhci_ring_alloc(xhci, val2, 1, TYPE_EVENT,
++                                         0, flags);
+       if (!xhci->event_ring)
+               goto fail;
+       if (xhci_check_trb_in_td_math(xhci) < 0)
+@@ -2510,7 +2512,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+       /* set ERST count with the number of entries in the segment table */
+       val = readl(&xhci->ir_set->erst_size);
+       val &= ERST_SIZE_MASK;
+-      val |= ERST_NUM_SEGS;
++      val |= val2;
+       xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+                       "// Write ERST size = %i to ir_set 0 (some bits preserved)",
+                       val);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1643,8 +1643,8 @@ struct urb_priv {
+  * Each segment table entry is 4*32bits long.  1K seems like an ok size:
+  * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
+  * meaning 64 ring segments.
+- * Initial allocated size of the ERST, in number of entries */
+-#define       ERST_NUM_SEGS   1
++ * Maximum number of segments in the ERST */
++#define       ERST_MAX_SEGS   8
+ /* Initial allocated size of the ERST, in number of entries */
+ #define       ERST_SIZE       64
+ /* Initial number of event segment rings allocated */