On Tue, Mar 9, 2021 at 8:17 AM Kenneth Feng <kenneth.feng@xxxxxxx> wrote: > > Currently the pcie dpm has two problems. > 1. Only the high dpm level speed/width can be overrided > if the requested values are out of the pcie capability. > 2. The high dpm level is always overrided though sometimes > it's not necesarry. > > Signed-off-by: Kenneth Feng <kenneth.feng@xxxxxxx> Reviewed-by: Alex Deucher <alexander.deucher@xxxxxxx> > --- > .../drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 48 ++++++++++++++ > .../drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 66 +++++++++++++++++++ > .../drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 48 ++++++++------ > 3 files changed, 141 insertions(+), 21 deletions(-) > > diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c > index 5e875ad8d633..408b35866704 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c > @@ -1505,6 +1505,48 @@ static int vega10_populate_single_lclk_level(struct pp_hwmgr *hwmgr, > return 0; > } > > +static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr) > +{ > + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); > + struct vega10_hwmgr *data = > + (struct vega10_hwmgr *)(hwmgr->backend); > + uint32_t pcie_gen = 0, pcie_width = 0; > + PPTable_t *pp_table = &(data->smc_state_table.pp_table); > + int i; > + > + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) > + pcie_gen = 3; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) > + pcie_gen = 2; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) > + pcie_gen = 1; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) > + pcie_gen = 0; > + > + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) > + pcie_width = 6; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) > + pcie_width = 5; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) > + pcie_width = 4; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) > + pcie_width = 3; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) > + pcie_width = 2; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) > + pcie_width = 1; > + > + for (i = 0; i < NUM_LINK_LEVELS; i++) { > + if (pp_table->PcieGenSpeed[i] > pcie_gen) > + pp_table->PcieGenSpeed[i] = pcie_gen; > + > + if (pp_table->PcieLaneCount[i] > pcie_width) > + pp_table->PcieLaneCount[i] = pcie_width; > + } > + > + return 0; > +} > + > static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr) > { > int result = -1; > @@ -2556,6 +2598,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) > "Failed to initialize Link Level!", > return result); > > + result = vega10_override_pcie_parameters(hwmgr); > + PP_ASSERT_WITH_CODE(!result, > + "Failed to override pcie parameters!", > + return result); > + > result = vega10_populate_all_graphic_levels(hwmgr); > PP_ASSERT_WITH_CODE(!result, > "Failed to initialize Graphics Level!", > @@ -2922,6 +2969,7 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap) > return 0; > } > > + > static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable) > { > struct vega10_hwmgr *data = hwmgr->backend; > diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c > index a827f2bc7904..196ac2a4d145 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c > @@ -481,6 +481,67 @@ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state) > dpm_state->hard_max_level = 0xffff; > } > > +static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr) > +{ > + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); > + struct vega12_hwmgr *data = > + (struct vega12_hwmgr *)(hwmgr->backend); > + uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; > + PPTable_t *pp_table = &(data->smc_state_table.pp_table); > + int i; > + int ret; > + > + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) > + pcie_gen = 3; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) > + pcie_gen = 2; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) > + pcie_gen = 1; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) > + pcie_gen = 0; > + > + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) > + pcie_width = 6; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) > + pcie_width = 5; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) > + pcie_width = 4; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) > + pcie_width = 3; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) > + pcie_width = 2; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) > + pcie_width = 1; > + > + /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 > + * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 > + * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 > + */ > + for (i = 0; i < NUM_LINK_LEVELS; i++) { > + pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : > + pp_table->PcieGenSpeed[i]; > + pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : > + pp_table->PcieLaneCount[i]; > + > + if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != > + pp_table->PcieLaneCount[i]) { > + smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; > + ret = smum_send_msg_to_smc_with_parameter(hwmgr, > + PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, > + NULL); > + PP_ASSERT_WITH_CODE(!ret, > + "[OverridePcieParameters] Attempt to override pcie params failed!", > + return ret); > + } > + > + /* update the pptable */ > + pp_table->PcieGenSpeed[i] = pcie_gen_arg; > + pp_table->PcieLaneCount[i] = pcie_width_arg; > + } > + > + return 0; > +} > + > static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, > PPCLK_e clk_id, uint32_t *num_of_levels) > { > @@ -968,6 +1029,11 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) > "Failed to enable all smu features!", > return result); > > + result = vega12_override_pcie_parameters(hwmgr); > + PP_ASSERT_WITH_CODE(!result, > + "[EnableDPMTasks] Failed to override pcie parameters!", > + return result); > + > tmp_result = vega12_power_control_set_level(hwmgr); > PP_ASSERT_WITH_CODE(!tmp_result, > "Failed to power control set level!", > diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c > index e8eec2539c17..78bbd4d666f2 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c > @@ -831,7 +831,9 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) > struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); > struct vega20_hwmgr *data = > (struct vega20_hwmgr *)(hwmgr->backend); > - uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; > + uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; > + PPTable_t *pp_table = &(data->smc_state_table.pp_table); > + int i; > int ret; > > if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) > @@ -860,17 +862,27 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) > * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 > * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 > */ > - smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width; > - ret = smum_send_msg_to_smc_with_parameter(hwmgr, > - PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, > - NULL); > - PP_ASSERT_WITH_CODE(!ret, > - "[OverridePcieParameters] Attempt to override pcie params failed!", > - return ret); > + for (i = 0; i < NUM_LINK_LEVELS; i++) { > + pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : > + pp_table->PcieGenSpeed[i]; > + pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : > + pp_table->PcieLaneCount[i]; > + > + if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != > + pp_table->PcieLaneCount[i]) { > + smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; > + ret = smum_send_msg_to_smc_with_parameter(hwmgr, > + PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, > + NULL); > + PP_ASSERT_WITH_CODE(!ret, > + "[OverridePcieParameters] Attempt to override pcie params failed!", > + return ret); > + } > > - data->pcie_parameters_override = true; > - data->pcie_gen_level1 = pcie_gen; > - data->pcie_width_level1 = pcie_width; > + /* update the pptable */ > + pp_table->PcieGenSpeed[i] = pcie_gen_arg; > + pp_table->PcieLaneCount[i] = pcie_width_arg; > + } > > return 0; > } > @@ -3319,9 +3331,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, > data->od8_settings.od8_settings_array; > OverDriveTable_t *od_table = > &(data->smc_state_table.overdrive_table); > - struct phm_ppt_v3_information *pptable_information = > - (struct phm_ppt_v3_information *)hwmgr->pptable; > - PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable; > + PPTable_t *pptable = &(data->smc_state_table.pp_table); > struct pp_clock_levels_with_latency clocks; > struct vega20_single_dpm_table *fclk_dpm_table = > &(data->dpm_table.fclk_table); > @@ -3420,13 +3430,9 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, > current_lane_width = > vega20_get_current_pcie_link_width_level(hwmgr); > for (i = 0; i < NUM_LINK_LEVELS; i++) { > - if (i == 1 && data->pcie_parameters_override) { > - gen_speed = data->pcie_gen_level1; > - lane_width = data->pcie_width_level1; > - } else { > - gen_speed = pptable->PcieGenSpeed[i]; > - lane_width = pptable->PcieLaneCount[i]; > - } > + gen_speed = pptable->PcieGenSpeed[i]; > + lane_width = pptable->PcieLaneCount[i]; > + > size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, > (gen_speed == 0) ? "2.5GT/s," : > (gen_speed == 1) ? "5.0GT/s," : > -- > 2.17.1 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx