SMU 13.0.6 applies default GFXCLK, UCLK, and FCLK ranges directly from
PP_OD_RESTORE_DEFAULT_TABLE. This bypasses the staged OD transaction.

Stage defaults through one helper and let c submit them. Gate UCLK and
FCLK staging and commit on their DPM features, and require the UCLK
firmware capability before staging or submitting its limit.

Signed-off-by: Kevin Wang <[email protected]>
---
 .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c  | 85 ++++++++++---------
 1 file changed, 44 insertions(+), 41 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 4dec3a93cb3d..169e38db629d 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
@@ -2130,14 +2130,45 @@ static int 
smu_v13_0_6_set_soft_freq_limited_range(struct smu_context *smu,
        return ret;
 }
 
+static void smu_v13_0_6_stage_default_dpm_limits(struct smu_context *smu)
+{
+       struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
+       struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
+       struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
+
+       pstate_table->gfxclk_pstate.custom.min =
+               SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table);
+       pstate_table->gfxclk_pstate.custom.max =
+               SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table);
+
+       if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
+           smu_v13_0_6_cap_supported(smu, SMU_CAP(SET_UCLK_MAX))) {
+               pstate_table->uclk_pstate.custom.min =
+                       SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.uclk_table);
+               pstate_table->uclk_pstate.custom.max =
+                       SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table);
+       } else {
+               pstate_table->uclk_pstate.custom.min = 0;
+               pstate_table->uclk_pstate.custom.max = 0;
+       }
+
+       if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
+               pstate_table->fclk_pstate.custom.min =
+                       SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.fclk_table);
+               pstate_table->fclk_pstate.custom.max =
+                       SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.fclk_table);
+       } else {
+               pstate_table->fclk_pstate.custom.min = 0;
+               pstate_table->fclk_pstate.custom.max = 0;
+       }
+}
+
 static int smu_v13_0_6_usr_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_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
-       struct smu_dpm_table *uclk_table = &dpm_context->dpm_tables.uclk_table;
-       struct smu_dpm_table *fclk_table = &dpm_context->dpm_tables.fclk_table;
        struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
        uint32_t min_clk;
        uint32_t max_clk;
@@ -2258,42 +2289,8 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct 
smu_context *smu,
                        dev_err(smu->adev->dev,
                                "Input parameter number not correct\n");
                        return -EINVAL;
-               } else {
-                       /* Use the default frequencies for manual and 
determinism 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_v13_0_6_set_soft_freq_limited_range(
-                               smu, SMU_GFXCLK, min_clk, max_clk, false);
-
-                       if (ret)
-                               return ret;
-
-                       if (SMU_DPM_TABLE_MAX(uclk_table) !=
-                           pstate_table->uclk_pstate.curr.max) {
-                               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_v13_0_6_set_soft_freq_limited_range(smu,
-                                                                             
SMU_UCLK, min_clk,
-                                                                             
max_clk, false);
-                               if (ret)
-                                       return ret;
-                       }
-
-                       if (SMU_DPM_TABLE_MAX(fclk_table) !=
-                           pstate_table->fclk_pstate.curr.max) {
-                               max_clk = 
SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.fclk_table);
-                               min_clk = 
SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.fclk_table);
-                               ret = 
smu_v13_0_6_set_soft_freq_limited_range(smu,
-                                                                             
SMU_FCLK, min_clk,
-                                                                             
max_clk, false);
-                               if (ret)
-                                       return ret;
-                       }
-                       smu_v13_0_reset_custom_level(smu);
                }
+               smu_v13_0_6_stage_default_dpm_limits(smu);
                break;
        case PP_OD_COMMIT_DPM_TABLE:
                if (size != 0) {
@@ -2318,8 +2315,10 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct 
smu_context *smu,
                        if (ret)
                                return ret;
 
-                       if (pstate_table->fclk_pstate.custom.max) {
-                               min_clk = pstate_table->fclk_pstate.curr.min;
+                       if (pstate_table->fclk_pstate.custom.max &&
+                           smu_cmn_feature_is_enabled(smu, 
SMU_FEATURE_DPM_FCLK_BIT)) {
+                               min_clk = pstate_table->fclk_pstate.custom.min 
?:
+                                       pstate_table->fclk_pstate.curr.min;
                                max_clk = pstate_table->fclk_pstate.custom.max;
                                ret = 
smu_v13_0_6_set_soft_freq_limited_range(smu,
                                                                              
SMU_FCLK, min_clk,
@@ -2328,10 +2327,14 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct 
smu_context *smu,
                                        return ret;
                        }
 
-                       if (!pstate_table->uclk_pstate.custom.max)
+                       if (!pstate_table->uclk_pstate.custom.max ||
+                           !smu_cmn_feature_is_enabled(smu, 
SMU_FEATURE_DPM_UCLK_BIT) ||
+                           !smu_v13_0_6_cap_supported(smu,
+                                                            
SMU_CAP(SET_UCLK_MAX)))
                                return 0;
 
-                       min_clk = pstate_table->uclk_pstate.curr.min;
+                       min_clk = pstate_table->uclk_pstate.custom.min ?:
+                               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, false);
-- 
2.55.0

Reply via email to