12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- From d0375d97a100054ab79539522b458855a6127e27 Mon Sep 17 00:00:00 2001
- From: Jonathan Bell <[email protected]>
- Date: Mon, 26 Oct 2020 14:03:35 +0000
- Subject: [PATCH] xhci: quirks: add link TRB quirk for VL805
- The VL805 controller can't cope with the TR Dequeue Pointer for an endpoint
- being set to a Link TRB. The hardware-maintained endpoint context ends up
- stuck at the address of the Link TRB, leading to erroneous ring expansion
- events whenever the enqueue pointer wraps to the dequeue position.
- If the search for the end of the current TD and ring cycle state lands on
- a Link TRB, move to the next segment.
- See: https://github.com/raspberrypi/linux/issues/3919
- Signed-off-by: Jonathan Bell <[email protected]>
- ---
- drivers/usb/host/xhci-pci.c | 1 +
- drivers/usb/host/xhci-ring.c | 9 +++++++++
- drivers/usb/host/xhci.h | 1 +
- 3 files changed, 11 insertions(+)
- --- a/drivers/usb/host/xhci-pci.c
- +++ b/drivers/usb/host/xhci-pci.c
- @@ -293,8 +293,10 @@ static void xhci_pci_quirks(struct devic
- pdev->device == 0x3432)
- xhci->quirks |= XHCI_BROKEN_STREAMS;
-
- - if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483)
- + if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) {
- xhci->quirks |= XHCI_LPM_SUPPORT;
- + xhci->quirks |= XHCI_AVOID_DQ_ON_LINK;
- + }
-
- if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
- pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) {
- --- a/drivers/usb/host/xhci-ring.c
- +++ b/drivers/usb/host/xhci-ring.c
- @@ -664,6 +664,15 @@ static int xhci_move_dequeue_past_td(str
- } while (!cycle_found || !td_last_trb_found);
-
- deq_found:
- + /*
- + * Quirk: the xHC does not correctly parse link TRBs if the HW Dequeue
- + * pointer is set to one. Advance to the next TRB (and next segment).
- + */
- + if (xhci->quirks & XHCI_AVOID_DQ_ON_LINK && trb_is_link(new_deq)) {
- + if (link_trb_toggles_cycle(new_deq))
- + new_cycle ^= 0x1;
- + next_trb(xhci, ep_ring, &new_seg, &new_deq);
- + }
-
- /* Don't update the ring cycle state for the producer (us). */
- addr = xhci_trb_virt_to_dma(new_seg, new_deq);
- --- a/drivers/usb/host/xhci.h
- +++ b/drivers/usb/host/xhci.h
- @@ -1902,6 +1902,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_AVOID_DQ_ON_LINK BIT_ULL(47)
-
- unsigned int num_active_eps;
- unsigned int limit_active_eps;
|