]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/pci-work-around-pericom-pcie-to-pci-bridge-retrain-link-erratum.patch
Linux 5.0.19
[thirdparty/kernel/stable-queue.git] / queue-4.19 / pci-work-around-pericom-pcie-to-pci-bridge-retrain-link-erratum.patch
1 From 4ec73791a64bab25cabf16a6067ee478692e506d Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Stefan=20M=C3=A4tje?= <stefan.maetje@esd.eu>
3 Date: Fri, 29 Mar 2019 18:07:35 +0100
4 Subject: PCI: Work around Pericom PCIe-to-PCI bridge Retrain Link erratum
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 From: Stefan Mätje <stefan.maetje@esd.eu>
10
11 commit 4ec73791a64bab25cabf16a6067ee478692e506d upstream.
12
13 Due to an erratum in some Pericom PCIe-to-PCI bridges in reverse mode
14 (conventional PCI on primary side, PCIe on downstream side), the Retrain
15 Link bit needs to be cleared manually to allow the link training to
16 complete successfully.
17
18 If it is not cleared manually, the link training is continuously restarted
19 and no devices below the PCI-to-PCIe bridge can be accessed. That means
20 drivers for devices below the bridge will be loaded but won't work and may
21 even crash because the driver is only reading 0xffff.
22
23 See the Pericom Errata Sheet PI7C9X111SLB_errata_rev1.2_102711.pdf for
24 details. Devices known as affected so far are: PI7C9X110, PI7C9X111SL,
25 PI7C9X130.
26
27 Add a new flag, clear_retrain_link, in struct pci_dev. Quirks for affected
28 devices set this bit.
29
30 Note that pcie_retrain_link() lives in aspm.c because that's currently the
31 only place we use it, but this erratum is not specific to ASPM, and we may
32 retrain links for other reasons in the future.
33
34 Signed-off-by: Stefan Mätje <stefan.maetje@esd.eu>
35 [bhelgaas: apply regardless of CONFIG_PCIEASPM]
36 Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
37 Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
38 CC: stable@vger.kernel.org
39 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
40
41 ---
42 drivers/pci/pcie/aspm.c | 9 +++++++++
43 drivers/pci/quirks.c | 17 +++++++++++++++++
44 include/linux/pci.h | 2 ++
45 3 files changed, 28 insertions(+)
46
47 --- a/drivers/pci/pcie/aspm.c
48 +++ b/drivers/pci/pcie/aspm.c
49 @@ -207,6 +207,15 @@ static bool pcie_retrain_link(struct pci
50 pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &reg16);
51 reg16 |= PCI_EXP_LNKCTL_RL;
52 pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
53 + if (parent->clear_retrain_link) {
54 + /*
55 + * Due to an erratum in some devices the Retrain Link bit
56 + * needs to be cleared again manually to allow the link
57 + * training to succeed.
58 + */
59 + reg16 &= ~PCI_EXP_LNKCTL_RL;
60 + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16);
61 + }
62
63 /* Wait for link training end. Break out after waiting for timeout */
64 start_jiffies = jiffies;
65 --- a/drivers/pci/quirks.c
66 +++ b/drivers/pci/quirks.c
67 @@ -2220,6 +2220,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
68 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
69 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
70
71 +/*
72 + * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain
73 + * Link bit cleared after starting the link retrain process to allow this
74 + * process to finish.
75 + *
76 + * Affected devices: PI7C9X110, PI7C9X111SL, PI7C9X130. See also the
77 + * Pericom Errata Sheet PI7C9X111SLB_errata_rev1.2_102711.pdf.
78 + */
79 +static void quirk_enable_clear_retrain_link(struct pci_dev *dev)
80 +{
81 + dev->clear_retrain_link = 1;
82 + pci_info(dev, "Enable PCIe Retrain Link quirk\n");
83 +}
84 +DECLARE_PCI_FIXUP_HEADER(0x12d8, 0xe110, quirk_enable_clear_retrain_link);
85 +DECLARE_PCI_FIXUP_HEADER(0x12d8, 0xe111, quirk_enable_clear_retrain_link);
86 +DECLARE_PCI_FIXUP_HEADER(0x12d8, 0xe130, quirk_enable_clear_retrain_link);
87 +
88 static void fixup_rev1_53c810(struct pci_dev *dev)
89 {
90 u32 class = dev->class;
91 --- a/include/linux/pci.h
92 +++ b/include/linux/pci.h
93 @@ -346,6 +346,8 @@ struct pci_dev {
94 unsigned int hotplug_user_indicators:1; /* SlotCtl indicators
95 controlled exclusively by
96 user sysfs */
97 + unsigned int clear_retrain_link:1; /* Need to clear Retrain Link
98 + bit manually */
99 unsigned int d3_delay; /* D3->D0 transition time in ms */
100 unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */
101