From e4c9200df51033e2394c165fdafb183dbd6100ab Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Fri, 24 Jul 2020 18:39:33 +0800 Subject: drm/amd/powerplay: implement SMU V11 common APIs for retrieving link speed/width This will be shared around all SMU V11 asics. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 8 ++++ drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 9 +--- drivers/gpu/drm/amd/powerplay/navi10_ppt.h | 3 -- drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c | 8 +--- drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.h | 3 -- drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 53 ++++++++++++++++++++++ 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h index 6a42331aba8a..aeb12654257e 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h @@ -264,5 +264,13 @@ int smu_v11_0_get_dpm_level_range(struct smu_context *smu, uint32_t *min_value, uint32_t *max_value); +int smu_v11_0_get_current_pcie_link_width_level(struct smu_context *smu); + +int smu_v11_0_get_current_pcie_link_width(struct smu_context *smu); + +int smu_v11_0_get_current_pcie_link_speed_level(struct smu_context *smu); + +int smu_v11_0_get_current_pcie_link_speed(struct smu_context *smu); + #endif #endif diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index c33bdc6747f2..45d2d6c2481c 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -917,7 +917,6 @@ static int navi10_print_clk_levels(struct smu_context *smu, uint32_t gen_speed, lane_width; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context; - struct amdgpu_device *adev = smu->adev; PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable; OverDriveTable_t *od_table = (OverDriveTable_t *)table_context->overdrive_table; @@ -971,12 +970,8 @@ static int navi10_print_clk_levels(struct smu_context *smu, } break; case SMU_PCIE: - gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & - PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) - >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; - lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & - PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) - >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; + gen_speed = smu_v11_0_get_current_pcie_link_speed_level(smu); + lane_width = smu_v11_0_get_current_pcie_link_width_level(smu); for (i = 0; i < NUM_LINK_LEVELS; i++) size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," : diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h index 2abb4ba01db1..84dc5a1b6830 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.h +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.h @@ -49,9 +49,6 @@ #define NAVI10_VOLTAGE_SCALE (4) -#define smnPCIE_LC_SPEED_CNTL 0x11140290 -#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 - extern void navi10_set_ppt_funcs(struct smu_context *smu); #endif diff --git a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c index f373e2d0d31c..05ad29fcfe68 100644 --- a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c @@ -960,12 +960,8 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu, } break; case SMU_PCIE: - gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & - PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) - >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; - lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & - PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) - >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; + gen_speed = smu_v11_0_get_current_pcie_link_speed(smu); + lane_width = smu_v11_0_get_current_pcie_link_width(smu); for (i = 0; i < NUM_LINK_LEVELS; i++) size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," : diff --git a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.h b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.h index 8078886e4cbc..57e120c440ea 100644 --- a/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.h +++ b/drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.h @@ -31,7 +31,4 @@ typedef enum { extern void sienna_cichlid_set_ppt_funcs(struct smu_context *smu); -#define smnPCIE_LC_SPEED_CNTL 0x11140290 -#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 - #endif diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index 7d7de854a826..ff90e20eed5c 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -67,6 +67,19 @@ MODULE_FIRMWARE("amdgpu/navy_flounder_smc.bin"); #define SMU11_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms +#define LINK_WIDTH_MAX 6 +#define LINK_SPEED_MAX 3 + +#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 +#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L +#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4 +#define smnPCIE_LC_SPEED_CNTL 0x11140290 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xC000 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE + +static int link_width[] = {0, 1, 2, 4, 8, 12, 16}; +static int link_speed[] = {25, 50, 80, 160}; + int smu_v11_0_init_microcode(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -1918,3 +1931,43 @@ int smu_v11_0_get_dpm_level_range(struct smu_context *smu, return ret; } + +int smu_v11_0_get_current_pcie_link_width_level(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + return (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & + PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) + >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; +} + +int smu_v11_0_get_current_pcie_link_width(struct smu_context *smu) +{ + uint32_t width_level; + + width_level = smu_v11_0_get_current_pcie_link_width_level(smu); + if (width_level > LINK_WIDTH_MAX) + width_level = 0; + + return link_width[width_level]; +} + +int smu_v11_0_get_current_pcie_link_speed_level(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + return (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & + PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) + >> PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; +} + +int smu_v11_0_get_current_pcie_link_speed(struct smu_context *smu) +{ + uint32_t speed_level; + + speed_level = smu_v11_0_get_current_pcie_link_speed_level(smu); + if (speed_level > LINK_SPEED_MAX) + speed_level = 0; + + return link_speed[speed_level]; +} -- cgit v1.2.3