Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0dd7f0c authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu: store pcie gen mask and link width



We'll need this later for pcie dpm.

Reviewed-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 60d8edd4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1637,8 +1637,12 @@ struct amdgpu_pm {
	const struct firmware	*fw;	/* SMC firmware */
	uint32_t                fw_version;
	const struct amdgpu_dpm_funcs *funcs;
	uint32_t                pcie_gen_mask;
	uint32_t                pcie_mlw_mask;
};

void amdgpu_get_pcie_info(struct amdgpu_device *adev);

/*
 * UVD
 */
+78 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "amdgpu_i2c.h"
#include "atom.h"
#include "amdgpu_atombios.h"
#include "amd_pcie.h"
#ifdef CONFIG_DRM_AMDGPU_CIK
#include "cik.h"
#endif
@@ -1932,6 +1933,83 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
	return r;
}

void amdgpu_get_pcie_info(struct amdgpu_device *adev)
{
	u32 mask;
	int ret;

	if (pci_is_root_bus(adev->pdev->bus))
		return;

	if (amdgpu_pcie_gen2 == 0)
		return;

	if (adev->flags & AMD_IS_APU)
		return;

	ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
	if (!ret) {
		adev->pm.pcie_gen_mask = (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 |
					  CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 |
					  CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3);

		if (mask & DRM_PCIE_SPEED_25)
			adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1;
		if (mask & DRM_PCIE_SPEED_50)
			adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2;
		if (mask & DRM_PCIE_SPEED_80)
			adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3;
	}
	ret = drm_pcie_get_max_link_width(adev->ddev, &mask);
	if (!ret) {
		switch (mask) {
		case 32:
			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 16:
			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 12:
			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 8:
			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 4:
			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 2:
			adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
						  CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
			break;
		case 1:
			adev->pm.pcie_mlw_mask = CAIL_PCIE_LINK_WIDTH_SUPPORT_X1;
			break;
		default:
			break;
		}
	}
}

/*
 * Debugfs
+12 −12
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "amdgpu_vce.h"
#include "cikd.h"
#include "atom.h"
#include "amd_pcie.h"

#include "cik.h"
#include "gmc_v7_0.h"
@@ -1595,8 +1596,8 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
{
	struct pci_dev *root = adev->pdev->bus->self;
	int bridge_pos, gpu_pos;
	u32 speed_cntl, mask, current_data_rate;
	int ret, i;
	u32 speed_cntl, current_data_rate;
	int i;
	u16 tmp16;

	if (pci_is_root_bus(adev->pdev->bus))
@@ -1608,23 +1609,20 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
	if (adev->flags & AMD_IS_APU)
		return;

	ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
	if (ret != 0)
		return;

	if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
		return;

	speed_cntl = RREG32_PCIE(ixPCIE_LC_SPEED_CNTL);
	current_data_rate = (speed_cntl & PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) >>
		PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
	if (mask & DRM_PCIE_SPEED_80) {
	if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
		if (current_data_rate == 2) {
			DRM_INFO("PCIE gen 3 link speeds already enabled\n");
			return;
		}
		DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n");
	} else if (mask & DRM_PCIE_SPEED_50) {
	} else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) {
		if (current_data_rate == 1) {
			DRM_INFO("PCIE gen 2 link speeds already enabled\n");
			return;
@@ -1640,7 +1638,7 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
	if (!gpu_pos)
		return;

	if (mask & DRM_PCIE_SPEED_80) {
	if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
		/* re-try equalization if gen3 is not already enabled */
		if (current_data_rate != 2) {
			u16 bridge_cfg, gpu_cfg;
@@ -1735,9 +1733,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)

	pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
	tmp16 &= ~0xf;
	if (mask & DRM_PCIE_SPEED_80)
	if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
		tmp16 |= 3; /* gen3 */
	else if (mask & DRM_PCIE_SPEED_50)
	else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
		tmp16 |= 2; /* gen2 */
	else
		tmp16 |= 1; /* gen1 */
@@ -2450,6 +2448,8 @@ static int cik_common_early_init(void *handle)
		return -EINVAL;
	}

	amdgpu_get_pcie_info(adev);

	return 0;
}

+5 −8
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "amdgpu_vce.h"
#include "amdgpu_ucode.h"
#include "atom.h"
#include "amd_pcie.h"

#include "gmc/gmc_8_1_d.h"
#include "gmc/gmc_8_1_sh_mask.h"
@@ -1052,9 +1053,6 @@ static int vi_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)

static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
{
	u32 mask;
	int ret;

	if (pci_is_root_bus(adev->pdev->bus))
		return;

@@ -1064,11 +1062,8 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
	if (adev->flags & AMD_IS_APU)
		return;

	ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
	if (ret != 0)
		return;

	if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
		return;

	/* todo */
@@ -1473,6 +1468,8 @@ static int vi_common_early_init(void *handle)
	if (amdgpu_smc_load_fw && smc_enabled)
		adev->firmware.smu_load = true;

	amdgpu_get_pcie_info(adev);

	return 0;
}