Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From f8a8c2abc45442acf0c7bca1fa8868140d9a2dc8 Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Timur=20Krist=C3=B3f?= <timur.kristof@gmail.com>
- Date: Sun, 14 Jul 2019 13:07:05 +0200
- Subject: [PATCH] add pcie_bandwidth_cap_available
- ---
- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +-
- drivers/pci/pci.c | 59 ++++++++++++++++++++++
- include/linux/pci.h | 3 ++
- 3 files changed, 63 insertions(+), 1 deletion(-)
- diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
- index 7401bc95c15b..3e23c402a9a9 100644
- --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
- +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
- @@ -3871,7 +3871,7 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
- if (adev->pm.pcie_gen_mask && adev->pm.pcie_mlw_mask)
- return;
- - pcie_bandwidth_available(adev->pdev, NULL,
- + pcie_bandwidth_cap_available(adev->pdev, NULL,
- &platform_speed_cap, &platform_link_width);
- if (adev->pm.pcie_gen_mask == 0) {
- diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
- index b1f563916036..7cf4edf04c2c 100644
- --- a/drivers/pci/pci.c
- +++ b/drivers/pci/pci.c
- @@ -5647,6 +5647,65 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
- }
- EXPORT_SYMBOL(pcie_bandwidth_available);
- +/**
- + * pcie_bandwidth_cap_available - determine minimum link settings of a PCIe
- + * device and the maximum bandwidth it is capable of
- + * @dev: PCI device to query
- + * @limiting_dev: storage for device causing the bandwidth limitation
- + * @speed: storage for speed of limiting device
- + * @width: storage for width of limiting device
- + *
- + * Walk up the PCI device chain and find the point where the minimum
- + * link width and minimum bandwidth capability is available.
- + * Return the bandwidth available there and (if
- + * limiting_dev, speed, and width pointers are supplied) information about
- + * that point. The bandwidth returned is in Mb/s, i.e., megabits/second of
- + * raw bandwidth.
- + */
- +u32 pcie_bandwidth_cap_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
- + enum pci_bus_speed *speed,
- + enum pcie_link_width *width)
- +{
- + u16 lnksta;
- + enum pci_bus_speed next_speed;
- + enum pcie_link_width next_width;
- + u32 bw, next_bw;
- +
- + if (speed)
- + *speed = PCI_SPEED_UNKNOWN;
- + if (width)
- + *width = PCIE_LNK_WIDTH_UNKNOWN;
- +
- + bw = 0;
- +
- + while (dev) {
- + pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
- +
- + next_speed = pcie_get_speed_cap(dev);
- + next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
- + PCI_EXP_LNKSTA_NLW_SHIFT;
- +
- + next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed);
- +
- + /* Check if current device limits the total bandwidth */
- + if (!bw || next_bw <= bw) {
- + bw = next_bw;
- +
- + if (limiting_dev)
- + *limiting_dev = dev;
- + if (speed)
- + *speed = next_speed;
- + if (width)
- + *width = next_width;
- + }
- +
- + dev = pci_upstream_bridge(dev);
- + }
- +
- + return bw;
- +}
- +EXPORT_SYMBOL(pcie_bandwidth_cap_available);
- +
- /**
- * pcie_get_speed_cap - query for the PCI device's link speed capability
- * @dev: PCI device to query
- diff --git a/include/linux/pci.h b/include/linux/pci.h
- index dd436da7eccc..c27b3bf70bc8 100644
- --- a/include/linux/pci.h
- +++ b/include/linux/pci.h
- @@ -1135,6 +1135,9 @@ int pcie_set_mps(struct pci_dev *dev, int mps);
- u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
- enum pci_bus_speed *speed,
- enum pcie_link_width *width);
- +u32 pcie_bandwidth_cap_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
- + enum pci_bus_speed *speed,
- + enum pcie_link_width *width);
- void pcie_print_link_status(struct pci_dev *dev);
- bool pcie_has_flr(struct pci_dev *dev);
- int pcie_flr(struct pci_dev *dev);
- --
- 2.21.0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement