From: Asad Kamal <[email protected]>

Add od_edit_dpm_table support for smu_v15_0_8

v2: Skip Gl2clk/Fclk (Lijo)

Signed-off-by: Asad Kamal <[email protected]>
Signed-off-by: Yang Wang <[email protected]>
Reviewed-by: Lijo Lazar <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 .../drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c  | 155 ++++++++++++++++++
 1 file changed, 155 insertions(+)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
index 435798388b012..04f16fd0633b6 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
@@ -1529,6 +1529,160 @@ static int 
smu_v15_0_8_set_soft_freq_limited_range(struct smu_context *smu,
        return 0;
 }
 
+static int smu_v15_0_8_od_edit_dpm_table(struct smu_context *smu,
+                                        enum PP_OD_DPM_TABLE_COMMAND type,
+                                        long input[], uint32_t size)
+{
+       struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
+       struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
+       struct smu_15_0_dpm_context *dpm_context = smu_dpm->dpm_context;
+       uint32_t min_clk, max_clk;
+       int ret;
+
+       /* Only allowed in manual mode */
+       if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
+               return -EINVAL;
+
+       switch (type) {
+       case PP_OD_EDIT_SCLK_VDDC_TABLE:
+               if (size != 2) {
+                       dev_err(smu->adev->dev,
+                               "Input parameter number not correct\n");
+                       return -EINVAL;
+               }
+               min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table);
+               max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table);
+               if (input[0] == 0) {
+                       if (input[1] < min_clk) {
+                               dev_warn(smu->adev->dev,
+                                        "Minimum GFX clk (%ld) MHz specified 
is less than the minimum allowed (%d) MHz\n",
+                                       input[1], min_clk);
+                               pstate_table->gfxclk_pstate.custom.min =
+                                       pstate_table->gfxclk_pstate.curr.min;
+                               return -EINVAL;
+                       }
+
+                       pstate_table->gfxclk_pstate.custom.min = input[1];
+               } else if (input[0] == 1) {
+                       if (input[1] > max_clk) {
+                               dev_warn(smu->adev->dev,
+                                        "Maximum GFX clk (%ld) MHz specified 
is greater than the maximum allowed (%d) MHz\n",
+                                       input[1], max_clk);
+                               pstate_table->gfxclk_pstate.custom.max =
+                                       pstate_table->gfxclk_pstate.curr.max;
+                               return -EINVAL;
+                       }
+
+                       pstate_table->gfxclk_pstate.custom.max = input[1];
+               } else {
+                       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;
+               }
+               max_clk = 
SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table);
+               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] > max_clk) {
+                               dev_warn(smu->adev->dev,
+                                        "Maximum UCLK (%ld) MHz specified is 
greater than the maximum allowed (%d) MHz\n",
+                                       input[1], max_clk);
+                               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,
+                               "Input parameter number not correct\n");
+                       return -EINVAL;
+               }
+
+               /* Use the default frequencies for manual mode */
+               min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table);
+               max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table);
+
+               ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
+                                                             SMU_GFXCLK,
+                                                             min_clk, max_clk,
+                                                             false);
+               if (ret)
+                       return ret;
+
+               min_clk = 
SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.uclk_table);
+               max_clk = 
SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table);
+               ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
+                                                             SMU_UCLK,
+                                                             min_clk, max_clk,
+                                                             false);
+               if (ret)
+                       return ret;
+
+               smu_cmn_reset_custom_level(smu);
+               break;
+       case PP_OD_COMMIT_DPM_TABLE:
+               if (size != 0) {
+                       dev_err(smu->adev->dev,
+                               "Input parameter number not correct\n");
+                       return -EINVAL;
+               }
+
+               if (!pstate_table->gfxclk_pstate.custom.min)
+                       pstate_table->gfxclk_pstate.custom.min =
+                               pstate_table->gfxclk_pstate.curr.min;
+
+               if (!pstate_table->gfxclk_pstate.custom.max)
+                       pstate_table->gfxclk_pstate.custom.max =
+                               pstate_table->gfxclk_pstate.curr.max;
+
+               min_clk = pstate_table->gfxclk_pstate.custom.min;
+               max_clk = pstate_table->gfxclk_pstate.custom.max;
+
+               ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
+                                                             SMU_GFXCLK,
+                                                             min_clk, max_clk,
+                                                             false);
+               if (ret)
+                       return ret;
+
+               /* Commit UCLK custom range (only max supported) */
+               if (pstate_table->uclk_pstate.custom.max) {
+                       min_clk = pstate_table->uclk_pstate.curr.min;
+                       max_clk = pstate_table->uclk_pstate.custom.max;
+                       ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
+                                                                     SMU_UCLK,
+                                                                     min_clk, 
max_clk,
+                                                                     false);
+                       if (ret)
+                               return ret;
+               }
+
+               break;
+       default:
+               return -ENOSYS;
+       }
+
+       return 0;
+}
+
 static const struct pptable_funcs smu_v15_0_8_ppt_funcs = {
        .init_allowed_features = smu_v15_0_8_init_allowed_features,
        .set_default_dpm_table = smu_v15_0_8_set_default_dpm_table,
@@ -1559,6 +1713,7 @@ static const struct pptable_funcs smu_v15_0_8_ppt_funcs = 
{
        .emit_clk_levels = smu_v15_0_8_emit_clk_levels,
        .populate_umd_state_clk = smu_v15_0_8_populate_umd_state_clk,
        .set_performance_level = smu_v15_0_8_set_performance_level,
+       .od_edit_dpm_table = smu_v15_0_8_od_edit_dpm_table,
 };
 
 static void smu_v15_0_8_init_msg_ctl(struct smu_context *smu,
-- 
2.53.0

Reply via email to