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

Merge branch 'pci/bwctrl'

- Add read/modify/write locking for Link Control 2, which is used to manage
  Link speed (Ilpo Järvinen)

- Cache all supported Link speeds for use by the PCIe bandwidth controller
  (Ilpo Järvinen)

- Extract the Link Bandwidth Management Status check into pcie_lbms_seen(),
  where it can be shared between the bandwidth controller and quirks that
  use it to help retrain failed links (Ilpo Järvinen)

- Re-add Link Bandwidth notification support with updates to address the
  reasons it was previously reverted (Alexandru Gagniuc, Ilpo Järvinen)

- Add pcie_set_target_speed() and related functionality to manage PCIe Link
  speed based on thermal constraints (Ilpo Järvinen)

- Add a thermal cooling driver to throttle PCIe Links via the existing
  thermal management framework (Ilpo Järvinen)

- Add a userspace selftest for the PCIe bandwidth controller (Ilpo
  Järvinen)

- Drop duplicate pcie_get_speed_cap(), pcie_get_width_cap() declarations
  (Bjorn Helgaas)

* pci/bwctrl:
  PCI: Drop duplicate pcie_get_speed_cap(), pcie_get_width_cap() declarations
  selftests/pcie_bwctrl: Create selftests
  thermal: Add PCIe cooling driver
  PCI/bwctrl: Add pcie_set_target_speed() to set PCIe Link Speed
  PCI/bwctrl: Re-add BW notification portdrv as PCIe BW controller
  PCI: Abstract LBMS seen check into pcie_lbms_seen()
  PCI: Refactor pcie_update_link_speed()
  PCI: Store all PCIe Supported Link Speeds
  PCI: Protect Link Control 2 Register with RMW locking
  Documentation PCI: Reformat RMW ops documentation
parents 01824710 ba58eee1
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -217,8 +217,12 @@ capability structure except the PCI Express capability structure,
that is shared between many drivers including the service drivers.
RMW Capability accessors (pcie_capability_clear_and_set_word(),
pcie_capability_set_word(), and pcie_capability_clear_word()) protect
a selected set of PCI Express Capability Registers (Link Control
Register and Root Control Register). Any change to those registers
should be performed using RMW accessors to avoid problems due to
concurrent updates. For the up-to-date list of protected registers,
see pcie_capability_clear_and_set_word().
a selected set of PCI Express Capability Registers:

* Link Control Register
* Root Control Register
* Link Control 2 Register

Any change to those registers should be performed using RMW accessors to
avoid problems due to concurrent updates. For the up-to-date list of
protected registers, see pcie_capability_clear_and_set_word().
+9 −0
Original line number Diff line number Diff line
@@ -17933,6 +17933,15 @@ F: include/linux/of_pci.h
F:	include/linux/pci*
F:	include/uapi/linux/pci*
PCIE BANDWIDTH CONTROLLER
M:	Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
L:	linux-pci@vger.kernel.org
S:	Supported
F:	drivers/pci/pcie/bwctrl.c
F:	drivers/thermal/pcie_cooling.c
F:	include/linux/pci-bwctrl.h
F:	tools/testing/selftests/pcie_bwctrl/
PCIE DRIVER FOR AMAZON ANNAPURNA LABS
M:	Jonathan Chocron <jonnyc@amazon.com>
L:	linux-pci@vger.kernel.org
+5 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <linux/types.h>
#include <linux/pm_runtime.h>
#include <linux/pci.h>

#include "../pci.h"
#include "pciehp.h"

/* The following routines constitute the bulk of the
@@ -127,6 +129,9 @@ static void remove_board(struct controller *ctrl, bool safe_removal)

	pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
			      INDICATOR_NOOP);

	/* Don't carry LBMS indications across */
	pcie_reset_lbms_count(ctrl->pcie->port);
}

static int pciehp_enable_slot(struct controller *ctrl);
+1 −1
Original line number Diff line number Diff line
@@ -319,7 +319,7 @@ int pciehp_check_link_status(struct controller *ctrl)
		return -1;
	}

	pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
	__pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);

	if (!found) {
		ctrl_info(ctrl, "Slot(%s): No device found\n",
+43 −17
Original line number Diff line number Diff line
@@ -4740,7 +4740,7 @@ int pcie_retrain_link(struct pci_dev *pdev, bool use_lt)
	 * to track link speed or width changes made by hardware itself
	 * in attempt to correct unreliable link operation.
	 */
	pcie_capability_write_word(pdev, PCI_EXP_LNKSTA, PCI_EXP_LNKSTA_LBMS);
	pcie_reset_lbms_count(pdev);
	return rc;
}

@@ -6189,38 +6189,64 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
EXPORT_SYMBOL(pcie_bandwidth_available);

/**
 * pcie_get_speed_cap - query for the PCI device's link speed capability
 * pcie_get_supported_speeds - query Supported Link Speed Vector
 * @dev: PCI device to query
 *
 * Query the PCI device speed capability.  Return the maximum link speed
 * supported by the device.
 * Query @dev supported link speeds.
 *
 * Implementation Note in PCIe r6.0 sec 7.5.3.18 recommends determining
 * supported link speeds using the Supported Link Speeds Vector in the Link
 * Capabilities 2 Register (when available).
 *
 * Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18.
 *
 * Without Link Capabilities 2, i.e., prior to PCIe r3.0, Supported Link
 * Speeds field in Link Capabilities is used and only 2.5 GT/s and 5.0 GT/s
 * speeds were defined.
 *
 * For @dev without Supported Link Speed Vector, the field is synthesized
 * from the Max Link Speed field in the Link Capabilities Register.
 *
 * Return: Supported Link Speeds Vector (+ reserved 0 at LSB).
 */
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
u8 pcie_get_supported_speeds(struct pci_dev *dev)
{
	u32 lnkcap2, lnkcap;
	u8 speeds;

	/*
	 * Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18.  The
	 * implementation note there recommends using the Supported Link
	 * Speeds Vector in Link Capabilities 2 when supported.
	 *
	 * Without Link Capabilities 2, i.e., prior to PCIe r3.0, software
	 * should use the Supported Link Speeds field in Link Capabilities,
	 * where only 2.5 GT/s and 5.0 GT/s speeds were defined.
	 * Speeds retain the reserved 0 at LSB before PCIe Supported Link
	 * Speeds Vector to allow using SLS Vector bit defines directly.
	 */
	pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2);
	speeds = lnkcap2 & PCI_EXP_LNKCAP2_SLS;

	/* PCIe r3.0-compliant */
	if (lnkcap2)
		return PCIE_LNKCAP2_SLS2SPEED(lnkcap2);
	if (speeds)
		return speeds;

	pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);

	/* Synthesize from the Max Link Speed field */
	if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_5_0GB)
		return PCIE_SPEED_5_0GT;
		speeds = PCI_EXP_LNKCAP2_SLS_5_0GB | PCI_EXP_LNKCAP2_SLS_2_5GB;
	else if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_2_5GB)
		return PCIE_SPEED_2_5GT;
		speeds = PCI_EXP_LNKCAP2_SLS_2_5GB;

	return PCI_SPEED_UNKNOWN;
	return speeds;
}

/**
 * pcie_get_speed_cap - query for the PCI device's link speed capability
 * @dev: PCI device to query
 *
 * Query the PCI device speed capability.
 *
 * Return: the maximum link speed supported by the device.
 */
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
{
	return PCIE_LNKCAP2_SLS2SPEED(dev->supported_speeds);
}
EXPORT_SYMBOL(pcie_get_speed_cap);

Loading