bcm27xx: add support for linux v5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.15 / 950-0606-usb-xhci-add-VLI_TRB_CACHE_BUG-quirk.patch
1 From a1d5ce866f2e2062246343af757c22e9abe4e844 Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Mon, 13 Dec 2021 16:04:03 +0000
4 Subject: [PATCH] usb: xhci: add VLI_TRB_CACHE_BUG quirk
5
6 The VL805 fetches up to 4 transfer TRBs at a time. TRB reads don't cross
7 a 64B boundary, and if a TRB is fetched and is not on a 64B boundary,
8 the read is sized up to the next 64B boundary.
9
10 However the VL805 implements a readahead prefetch for TRBs on a transfer
11 ring. This fetches the next 64B after any TRB read has happened. Near
12 the end of a ring segment, the prefetcher can read the first 64B of the
13 next page in physical memory and this is where the behaviour causes a
14 bug.
15
16 The controller does not tag reads with which endpoint they are for, so
17 if the start of the next page is a ring segment used by a victim
18 endpoint, and the victim endpoint is about to fetch TRBs from the start
19 of the segment, the victim endpoint will read from the prefetched data
20 and not perform a read to main memory. If the data is stale, the ring
21 cycle state bit may not be correct and the endpoint will silently halt.
22
23 Adjust trbs_per_seg for transfer rings allocated for this controller.
24
25 See https://github.com/raspberrypi/linux/issues/4685
26
27 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
28 ---
29 drivers/usb/host/xhci-mem.c | 11 +++++++++++
30 drivers/usb/host/xhci-pci.c | 1 +
31 drivers/usb/host/xhci.h | 1 +
32 3 files changed, 13 insertions(+)
33
34 --- a/drivers/usb/host/xhci-mem.c
35 +++ b/drivers/usb/host/xhci-mem.c
36 @@ -392,6 +392,17 @@ struct xhci_ring *xhci_ring_alloc(struct
37 return ring;
38
39 ring->trbs_per_seg = TRBS_PER_SEGMENT;
40 + /*
41 + * The Via VL805 has a bug where cache readahead will fetch off the end
42 + * of a page if the Link TRB of a transfer ring is in the last 4 slots.
43 + * Where there are consecutive physical pages containing ring segments,
44 + * this can cause a desync between the controller's view of a ring
45 + * and the host.
46 + */
47 + if (xhci->quirks & XHCI_VLI_TRB_CACHE_BUG &&
48 + type != TYPE_EVENT && type != TYPE_COMMAND)
49 + ring->trbs_per_seg -= 4;
50 +
51 ret = xhci_alloc_segments_for_ring(xhci, &ring->first_seg,
52 &ring->last_seg, num_segs, ring->trbs_per_seg,
53 cycle_state, type, max_packet, flags);
54 --- a/drivers/usb/host/xhci-pci.c
55 +++ b/drivers/usb/host/xhci-pci.c
56 @@ -299,6 +299,7 @@ static void xhci_pci_quirks(struct devic
57 xhci->quirks |= XHCI_LPM_SUPPORT;
58 xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
59 xhci->quirks |= XHCI_AVOID_DQ_ON_LINK;
60 + xhci->quirks |= XHCI_VLI_TRB_CACHE_BUG;
61 }
62
63 if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
64 --- a/drivers/usb/host/xhci.h
65 +++ b/drivers/usb/host/xhci.h
66 @@ -1905,6 +1905,7 @@ struct xhci_hcd {
67 #define XHCI_BROKEN_D3COLD BIT_ULL(41)
68 #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42)
69 #define XHCI_AVOID_DQ_ON_LINK BIT_ULL(43)
70 +#define XHCI_VLI_TRB_CACHE_BUG BIT_ULL(44)
71
72 unsigned int num_active_eps;
73 unsigned int limit_active_eps;