Commit c46fd358 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

PCI/ASPM: Enable Latency Tolerance Reporting when supported



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: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarVidya Sagar <vidyas@nvidia.com>
parent 80d7d7a9
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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 */