]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
UBUNTU: SAUCE: PCI/ASPM: Enable LTR for endpoints behind VMD
authorKai-Heng Feng <kai.heng.feng@canonical.com>
Tue, 22 Sep 2020 10:42:54 +0000 (18:42 +0800)
committerPaolo Pisati <paolo.pisati@canonical.com>
Tue, 2 Nov 2021 07:24:50 +0000 (08:24 +0100)
BugLink: https://bugs.launchpad.net/bugs/1896598
In addition to ASPM, LTR also needs to be programmed with a reasonable
value to let PCIe link reaches L1.2.

For now, program a hardcoded value that is used under Windows.

While at it, consolidate ASPM and LTR enabling logic to share a same pci
device table.

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
drivers/pci/quirks.c

index d029295d27c82a5a35afeb6ff5b0deb4205ec7c3..4b2fd0b0965761c51883d55552aca3a36783ca8e 100644 (file)
@@ -5812,13 +5812,55 @@ DECLARE_PCI_FIXUP_CLASS_HEADER(0x1ac1, 0x089a,
                               PCI_CLASS_NOT_DEFINED, 8, apex_pci_fixup_class);
 
 /*
- * Device [8086:9a09]
+ * Device [8086:9a09], [8086:a0b0] and [8086:a0bc]
  * BIOS may not be able to access config space of devices under VMD domain, so
  * it relies on software to enable ASPM for links under VMD.
  */
+static const struct pci_device_id vmd_bridge_tbl[] = {
+       { PCI_VDEVICE(INTEL, 0x9a09) },
+       { PCI_VDEVICE(INTEL, 0xa0b0) },
+       { PCI_VDEVICE(INTEL, 0xa0bc) },
+       { }
+};
+
 static void pci_fixup_enable_aspm(struct pci_dev *pdev)
 {
+       if (!pci_match_id(vmd_bridge_tbl, pdev))
+               return;
+
        pdev->dev_flags |= PCI_DEV_FLAGS_ENABLE_ASPM;
 }
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a09, pci_fixup_enable_aspm);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa0b0, pci_fixup_enable_aspm);
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+                              PCI_CLASS_BRIDGE_PCI, 8, pci_fixup_enable_aspm);
+
+static void pci_fixup_enable_vmd_nvme_ltr(struct pci_dev *pdev)
+{
+       struct pci_dev *parent;
+       int pos;
+       u16 val;
+
+       parent = pci_upstream_bridge(pdev);
+       if (!parent)
+               return;
+
+       if (!pci_match_id(vmd_bridge_tbl, parent))
+               return;
+
+       pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR);
+       if (!pos)
+               return;
+
+       pci_read_config_word(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, &val);
+       if (val)
+               return;
+
+       pci_read_config_word(pdev, pos + PCI_LTR_MAX_NOSNOOP_LAT, &val);
+       if (val)
+               return;
+
+       /* 3145728ns, i.e. 0x300000ns */
+       pci_write_config_word(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, 0x1003);
+       pci_write_config_word(pdev, pos + PCI_LTR_MAX_NOSNOOP_LAT, 0x1003);
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
+                             PCI_CLASS_STORAGE_EXPRESS, 0, pci_fixup_enable_vmd_nvme_ltr);