On 31-Aug-26 10:05 AM, Kevin Wang wrote:
[Some people who received this message don't often get email from
[email protected]. Learn why this is important at
https://aka.ms/LearnAboutSenderIdentification ]
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;
+ }
+}
The default values shouldn't be put as custom min/max limits. The custom
limits will keep non-zero values to indicate any custom limit is set or
not. It's not used to keep the default limits.
+
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;
This is intentional to always enforce the min limit, there is no custom
min limit allowed for FCLK.
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 ?:
Same here, there is no custom min allowed for UCLK.
Thanks,
Lijo
+ 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