]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
PCI/ASPM: Enable Latency Tolerance Reporting when supported
authorBjorn Helgaas <bhelgaas@google.com>
Tue, 28 Nov 2017 22:43:50 +0000 (16:43 -0600)
committerSeth Forshee <seth.forshee@canonical.com>
Fri, 16 Mar 2018 15:43:15 +0000 (10:43 -0500)
BugLink: http://bugs.launchpad.net/bugs/1756094
Enable Latency Tolerance Reporting (LTR).  Note that LTR must be enabled in
the Root Port first, and must not be enabled in any downstream device
unless the Root Port and all intermediate Switches also support LTR.
See PCIe r3.1, sec 6.18.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Vidya Sagar <vidyas@nvidia.com>
(cherry picked from commit c46fd358070f22ba68d6e74c22016a33b914c20a)
Signed-off-by: Manoj Iyer <manoj.iyer@canonical.com>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
drivers/pci/probe.c
include/linux/pci.h

index 14e0ea1ff38b3745111ead4fba31a9fc124c1235..3761b13035296f82bee25461e0d97dc8cf175ae4 100644 (file)
@@ -1875,6 +1875,38 @@ static void pci_configure_relaxed_ordering(struct pci_dev *dev)
        }
 }
 
+static void pci_configure_ltr(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCIEASPM
+       u32 cap;
+       struct pci_dev *bridge;
+
+       if (!pci_is_pcie(dev))
+               return;
+
+       pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
+       if (!(cap & PCI_EXP_DEVCAP2_LTR))
+               return;
+
+       /*
+        * Software must not enable LTR in an Endpoint unless the Root
+        * Complex and all intermediate Switches indicate support for LTR.
+        * PCIe r3.1, sec 6.18.
+        */
+       if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+               dev->ltr_path = 1;
+       else {
+               bridge = pci_upstream_bridge(dev);
+               if (bridge && bridge->ltr_path)
+                       dev->ltr_path = 1;
+       }
+
+       if (dev->ltr_path)
+               pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
+                                        PCI_EXP_DEVCTL2_LTR_EN);
+#endif
+}
+
 static void pci_configure_device(struct pci_dev *dev)
 {
        struct hotplug_params hpp;
@@ -1883,6 +1915,7 @@ static void pci_configure_device(struct pci_dev *dev)
        pci_configure_mps(dev);
        pci_configure_extended_tags(dev, NULL);
        pci_configure_relaxed_ordering(dev);
+       pci_configure_ltr(dev);
 
        memset(&hpp, 0, sizeof(hpp));
        ret = pci_get_hp_params(dev, &hpp);
index abe9c2e4fdc0daed87fc57aa8826963481ea3fcc..0962a3a36d6242ad9073a6fea361c413b2527a00 100644 (file)
@@ -350,6 +350,8 @@ struct pci_dev {
 
 #ifdef CONFIG_PCIEASPM
        struct pcie_link_state  *link_state;    /* ASPM link state */
+       unsigned int    ltr_path:1;     /* Latency Tolerance Reporting
+                                          supported from root to here */
 #endif
 
        pci_channel_state_t error_state;        /* current connectivity state */