Skip to content

Commit

Permalink
drm/amdgpu: cache gpu pcie link width
Browse files Browse the repository at this point in the history
Get the PCIe link with of the device itself (or it's
integrated upstream bridge) and cache that.

v2: fix typo

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3820
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Alex Deucher committed Jan 24, 2025
1 parent a8d42cd commit 757e8b9
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 32 deletions.
152 changes: 120 additions & 32 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -6157,6 +6157,44 @@ static void amdgpu_device_partner_bandwidth(struct amdgpu_device *adev,
}
}

/**
* amdgpu_device_gpu_bandwidth - find the bandwidth of the GPU
*
* @adev: amdgpu_device pointer
* @speed: pointer to the speed of the link
* @width: pointer to the width of the link
*
* Evaluate the hierarchy to find the speed and bandwidth capabilities of the
* AMD dGPU which may be a virtual upstream bridge.
*/
static void amdgpu_device_gpu_bandwidth(struct amdgpu_device *adev,
enum pci_bus_speed *speed,
enum pcie_link_width *width)
{
struct pci_dev *parent = adev->pdev;

if (!speed || !width)
return;

parent = pci_upstream_bridge(parent);
if (parent && parent->vendor == PCI_VENDOR_ID_ATI) {
/* use the upstream/downstream switches internal to dGPU */
*speed = pcie_get_speed_cap(parent);
*width = pcie_get_width_cap(parent);
while ((parent = pci_upstream_bridge(parent))) {
if (parent->vendor == PCI_VENDOR_ID_ATI) {
/* use the upstream/downstream switches internal to dGPU */
*speed = pcie_get_speed_cap(parent);
*width = pcie_get_width_cap(parent);
}
}
} else {
/* use the device itself */
*speed = pcie_get_speed_cap(parent);
*width = pcie_get_width_cap(parent);
}
}

/**
* amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
*
Expand All @@ -6168,9 +6206,8 @@ static void amdgpu_device_partner_bandwidth(struct amdgpu_device *adev,
*/
static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
{
struct pci_dev *pdev;
enum pci_bus_speed speed_cap, platform_speed_cap;
enum pcie_link_width platform_link_width;
enum pcie_link_width platform_link_width, link_width;

if (amdgpu_pcie_gen_cap)
adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap;
Expand All @@ -6192,11 +6229,10 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)

amdgpu_device_partner_bandwidth(adev, &platform_speed_cap,
&platform_link_width);
amdgpu_device_gpu_bandwidth(adev, &speed_cap, &link_width);

if (adev->pm.pcie_gen_mask == 0) {
/* asic caps */
pdev = adev->pdev;
speed_cap = pcie_get_speed_cap(pdev);
if (speed_cap == PCI_SPEED_UNKNOWN) {
adev->pm.pcie_gen_mask |= (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 |
CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 |
Expand Down Expand Up @@ -6252,51 +6288,103 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
}
}
if (adev->pm.pcie_mlw_mask == 0) {
/* asic caps */
if (link_width == PCIE_LNK_WIDTH_UNKNOWN) {
adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_ASIC_PCIE_MLW_MASK;
} else {
switch (link_width) {
case PCIE_LNK_X32:
adev->pm.pcie_mlw_mask |= (CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X32 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X16 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X16:
adev->pm.pcie_mlw_mask |= (CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X16 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X12:
adev->pm.pcie_mlw_mask |= (CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X8:
adev->pm.pcie_mlw_mask |= (CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X4:
adev->pm.pcie_mlw_mask |= (CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X2:
adev->pm.pcie_mlw_mask |= (CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X1:
adev->pm.pcie_mlw_mask |= CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1;
break;
default:
break;
}
}
/* platform caps */
if (platform_link_width == PCIE_LNK_WIDTH_UNKNOWN) {
adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_PCIE_MLW_MASK;
} else {
switch (platform_link_width) {
case PCIE_LNK_X32:
adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
adev->pm.pcie_mlw_mask |= (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X16:
adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
adev->pm.pcie_mlw_mask |= (CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X12:
adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
adev->pm.pcie_mlw_mask |= (CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X8:
adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
adev->pm.pcie_mlw_mask |= (CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X4:
adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
adev->pm.pcie_mlw_mask |= (CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X2:
adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
adev->pm.pcie_mlw_mask |= (CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
break;
case PCIE_LNK_X1:
adev->pm.pcie_mlw_mask = CAIL_PCIE_LINK_WIDTH_SUPPORT_X1;
adev->pm.pcie_mlw_mask |= CAIL_PCIE_LINK_WIDTH_SUPPORT_X1;
break;
default:
break;
Expand Down
18 changes: 18 additions & 0 deletions drivers/gpu/drm/amd/include/amd_pcie.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,25 @@
| CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3)

/* Following flags shows PCIe lane width switch supported in driver which are decided by chipset and ASIC */

#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1 0x00000001
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 0x00000002
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X4 0x00000004
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X8 0x00000008
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X12 0x00000010
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X16 0x00000020
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X32 0x00000040
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_MASK 0x0000FFFF
#define CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_SHIFT 0

#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X1 0x00010000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 0x00020000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 0x00040000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 0x00080000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 0x00100000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 0x00200000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 0x00400000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_MASK 0xFFFF0000
#define CAIL_PCIE_LINK_WIDTH_SUPPORT_SHIFT 16

/* 1/2/4/8/16 lanes */
Expand All @@ -65,4 +77,10 @@
| CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 \
| CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)

#define AMDGPU_DEFAULT_ASIC_PCIE_MLW_MASK (CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X1 \
| CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X2 \
| CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X4 \
| CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X8 \
| CAIL_ASIC_PCIE_LINK_WIDTH_SUPPORT_X16)

#endif

0 comments on commit 757e8b9

Please sign in to comment.