Sending another one, please ignore. Thanks, Lijo On 2/9/2024 12:04 PM, Lijo Lazar wrote: > Allow reducing max UCLK in MANUAL performance level. New UCLK value > should be less than the max DPM level UCLK level value. > > Ex: > echo manual > "/sys/bus/pci/devices/.../power_dpm_force_performance_level" > echo m 1 900 > "/sys/bus/pci/devices/.../pp_od_clk_voltage” > echo c > "/sys/bus/pci/devices/.../pp_od_clk_voltage” > > Signed-off-by: Lijo Lazar <lijo.lazar@xxxxxxx> > --- > .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 103 ++++++++++++++++-- > 1 file changed, 92 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c > index 03873d784be6..9929981ff6c5 100644 > --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c > +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c > @@ -1578,6 +1578,8 @@ static int smu_v13_0_6_set_performance_level(struct smu_context *smu, > struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context; > struct smu_13_0_dpm_table *gfx_table = > &dpm_context->dpm_tables.gfx_table; > + struct smu_13_0_dpm_table *uclk_table = > + &dpm_context->dpm_tables.uclk_table; > struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; > int ret; > > @@ -1604,6 +1606,15 @@ static int smu_v13_0_6_set_performance_level(struct smu_context *smu, > > pstate_table->gfxclk_pstate.curr.min = gfx_table->min; > pstate_table->gfxclk_pstate.curr.max = gfx_table->max; > + > + /* Min UCLK is not expected to be changed */ > + ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_UCLK, 0, > + uclk_table->max); > + if (ret) > + return ret; > + pstate_table->uclk_pstate.curr.max = uclk_table->max; > + pstate_table->uclk_pstate.custom.max = 0; > + > return 0; > case AMD_DPM_FORCED_LEVEL_MANUAL: > return 0; > @@ -1626,7 +1637,8 @@ static int smu_v13_0_6_set_soft_freq_limited_range(struct smu_context *smu, > uint32_t max_clk; > int ret = 0; > > - if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) > + if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK && > + clk_type != SMU_UCLK) > return -EINVAL; > > if ((smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) && > @@ -1636,18 +1648,31 @@ static int smu_v13_0_6_set_soft_freq_limited_range(struct smu_context *smu, > if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) { > if (min >= max) { > dev_err(smu->adev->dev, > - "Minimum GFX clk should be less than the maximum allowed clock\n"); > + "Minimum clk should be less than the maximum allowed clock\n"); > return -EINVAL; > } > > - if ((min == pstate_table->gfxclk_pstate.curr.min) && > - (max == pstate_table->gfxclk_pstate.curr.max)) > - return 0; > + if (clk_type == SMU_GFXCLK) { > + if ((min == pstate_table->gfxclk_pstate.curr.min) && > + (max == pstate_table->gfxclk_pstate.curr.max)) > + return 0; > > - ret = smu_v13_0_6_set_gfx_soft_freq_limited_range(smu, min, max); > - if (!ret) { > - pstate_table->gfxclk_pstate.curr.min = min; > - pstate_table->gfxclk_pstate.curr.max = max; > + ret = smu_v13_0_6_set_gfx_soft_freq_limited_range( > + smu, min, max); > + if (!ret) { > + pstate_table->gfxclk_pstate.curr.min = min; > + pstate_table->gfxclk_pstate.curr.max = max; > + } > + } > + > + if (clk_type == SMU_UCLK) { > + if (max == pstate_table->uclk_pstate.curr.max) > + return 0; > + /* Only max clock limiting is allowed for UCLK */ > + ret = smu_v13_0_set_soft_freq_limited_range( > + smu, SMU_UCLK, 0, max); > + if (!ret) > + pstate_table->uclk_pstate.curr.max = max; > } > > return ret; > @@ -1740,6 +1765,40 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu, > return -EINVAL; > } > break; > + case PP_OD_EDIT_MCLK_VDDC_TABLE: > + if (size != 2) { > + dev_err(smu->adev->dev, > + "Input parameter number not correct\n"); > + return -EINVAL; > + } > + > + if (!smu_cmn_feature_is_enabled(smu, > + SMU_FEATURE_DPM_UCLK_BIT)) { > + dev_warn(smu->adev->dev, > + "UCLK_LIMITS setting not supported!\n"); > + return -EOPNOTSUPP; > + } > + > + if (input[0] == 0) { > + dev_info(smu->adev->dev, > + "Setting min UCLK level is not supported"); > + return -EINVAL; > + } else if (input[0] == 1) { > + if (input[1] > dpm_context->dpm_tables.uclk_table.max) { > + dev_warn( > + smu->adev->dev, > + "Maximum UCLK (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n", > + input[1], > + dpm_context->dpm_tables.uclk_table.max); > + pstate_table->uclk_pstate.custom.max = > + pstate_table->uclk_pstate.curr.max; > + return -EINVAL; > + } > + > + pstate_table->uclk_pstate.custom.max = input[1]; > + } > + break; > + > case PP_OD_RESTORE_DEFAULT_TABLE: > if (size != 0) { > dev_err(smu->adev->dev, > @@ -1750,8 +1809,19 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu, > min_clk = dpm_context->dpm_tables.gfx_table.min; > max_clk = dpm_context->dpm_tables.gfx_table.max; > > - return smu_v13_0_6_set_soft_freq_limited_range( > + ret = smu_v13_0_6_set_soft_freq_limited_range( > smu, SMU_GFXCLK, min_clk, max_clk); > + > + if (ret) > + return ret; > + > + min_clk = dpm_context->dpm_tables.uclk_table.min; > + max_clk = dpm_context->dpm_tables.uclk_table.max; > + ret = smu_v13_0_6_set_soft_freq_limited_range( > + smu, SMU_UCLK, min_clk, max_clk); > + if (ret) > + return ret; > + pstate_table->uclk_pstate.custom.max = 0; > } > break; > case PP_OD_COMMIT_DPM_TABLE: > @@ -1771,8 +1841,19 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu, > min_clk = pstate_table->gfxclk_pstate.custom.min; > max_clk = pstate_table->gfxclk_pstate.custom.max; > > - return smu_v13_0_6_set_soft_freq_limited_range( > + ret = smu_v13_0_6_set_soft_freq_limited_range( > smu, SMU_GFXCLK, min_clk, max_clk); > + > + if (ret) > + return ret; > + > + if (!pstate_table->uclk_pstate.custom.max) > + return 0; > + > + min_clk = pstate_table->uclk_pstate.curr.min; > + max_clk = pstate_table->uclk_pstate.custom.max; > + return smu_v13_0_6_set_soft_freq_limited_range( > + smu, SMU_UCLK, min_clk, max_clk); > } > break; > default: