xhci: Add a quirk for writing ERST in high-low order
authorDaehwan Jung <dh10.jung@samsung.com>
Mon, 10 Jun 2024 11:39:12 +0000 (20:39 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 20 Jun 2024 17:30:30 +0000 (19:30 +0200)
This quirk is for the controller that has a limitation in supporting
separate ERSTBA_HI and ERSTBA_LO programming. It's supported when
the ERSTBA is programmed ERSTBA_HI before ERSTBA_LO. That's because
the internal initialization of event ring fetches the
"Event Ring Segment Table Entry" based on the indication of ERSTBA_LO
written.

Signed-off-by: Daehwan Jung <dh10.jung@samsung.com>
Link: https://lore.kernel.org/r/1718019553-111939-3-git-send-email-dh10.jung@samsung.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.h

index 3100219d6496dd5061a30f9847f360590696146e..ef768e63e4d396062ef7b37fb619218494268c51 100644 (file)
@@ -2325,7 +2325,10 @@ xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir,
        erst_base = xhci_read_64(xhci, &ir->ir_set->erst_base);
        erst_base &= ERST_BASE_RSVDP;
        erst_base |= ir->erst.erst_dma_addr & ~ERST_BASE_RSVDP;
-       xhci_write_64(xhci, erst_base, &ir->ir_set->erst_base);
+       if (xhci->quirks & XHCI_WRITE_64_HI_LO)
+               hi_lo_writeq(erst_base, &ir->ir_set->erst_base);
+       else
+               xhci_write_64(xhci, erst_base, &ir->ir_set->erst_base);
 
        /* Set the event ring dequeue address of this interrupter */
        xhci_set_hc_event_deq(xhci, ir);
index 78d014c4d884a2a7d6780b5301c986d11864569f..5a8925474176dce0f93a27f7d004437a4730722d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/usb/hcd.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-hi-lo.h>
 
 /* Code sharing between pci-quirks and xhci hcd */
 #include       "xhci-ext-caps.h"
@@ -1628,6 +1629,7 @@ struct xhci_hcd {
 #define XHCI_RESET_TO_DEFAULT  BIT_ULL(44)
 #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
 #define XHCI_ZHAOXIN_HOST      BIT_ULL(46)
+#define XHCI_WRITE_64_HI_LO    BIT_ULL(47)
 
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;