Commit 757e8b95 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu: cache gpu pcie link width

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: default avatarYang Wang <kevinyang.wang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a8d42cd2
Loading
Loading
Loading
Loading
+120 −32
Original line number Diff line number Diff line
@@ -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
 *
@@ -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;
@@ -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 |
@@ -6252,12 +6288,64 @@ 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 |
				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 |
@@ -6266,7 +6354,7 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
							   CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
				break;
			case PCIE_LNK_X16:
				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_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 |
@@ -6274,29 +6362,29 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
							   CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
				break;
			case PCIE_LNK_X12:
				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_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);
				break;
			case PCIE_LNK_X8:
				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_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);
				break;
			case PCIE_LNK_X4:
				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
				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 |
				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;
+18 −0
Original line number Diff line number Diff line
@@ -49,6 +49,17 @@
				      | 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
@@ -56,6 +67,7 @@
#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 */
@@ -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