On 16-Jan-26 1:32 PM, Yang Wang wrote:
Use PPTable to initialize the dpm table to avoid loss of frequency precision
when using SMU message PPSMC_MSG_GetDpmFreqByIndex.
e.g: uclk dpm on smu 14.0.2
- by SMU MSG: 96, 456, 772, 875, 1124, 1258
- by PPTable: 97, 457, 773, 875, 1125, 1259
Signed-off-by: Yang Wang <[email protected]>
---
.../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 112 ++++++++++++++----
1 file changed, 91 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
index faae1da81bd4..03246455d727 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
@@ -497,6 +497,76 @@ static int smu_v14_0_2_init_smc_tables(struct smu_context
*smu)
return smu_v14_0_init_smc_tables(smu);
}
+static int smu_v14_0_2_set_dpm_table(struct smu_context *smu,
+ enum smu_clk_type clk_type,
+ struct smu_dpm_table *dpm_table,
+ DpmDescriptor_t *dpm_desc, uint16_t
*freqtable)
+{
+ int i;
+
+ for (i = 0; i < dpm_desc->NumDiscreteLevels; i++) {
+ dpm_table->dpm_levels[i].enabled = true;
+ dpm_table->dpm_levels[i].value = freqtable[i];
+ }
+
+ dpm_table->count = dpm_desc->NumDiscreteLevels;
+ dpm_table->clk_type = clk_type;
+ if (!dpm_desc->SnapToDiscrete)
+ dpm_table->flags |= SMU_DPM_TABLE_FINE_GRAINED;
+
+ return 0;
No real error returns, can be made a void function.
+}
+
+static int smu_v14_0_2_set_dpm_table_by_pptable(struct smu_context *smu,
+ enum smu_clk_type clk_type,
+ struct smu_dpm_table *dpm_table)
+{
+ struct smu_table_context *table_context = &smu->smu_table;
+ PPTable_t *pptable = table_context->driver_pptable;
+ SkuTable_t *skutable = &pptable->SkuTable;
+ DpmDescriptor_t *dpm_desc;
+ uint16_t *freqtable;
+
+ switch (clk_type) {
+ case SMU_SCLK:
+ case SMU_GFXCLK:
+ dpm_desc = &skutable->DpmDescriptor[PPCLK_GFXCLK];
+ freqtable = skutable->FreqTableGfx;
+ break;
+ case SMU_SOCCLK:
+ dpm_desc = &skutable->DpmDescriptor[PPCLK_SOCCLK];
+ freqtable = skutable->FreqTableSocclk;
+ break;
+ case SMU_UCLK:
+ case SMU_MCLK:
+ dpm_desc = &skutable->DpmDescriptor[PPCLK_UCLK];
+ freqtable = skutable->FreqTableUclk;
+ break;
+ case SMU_FCLK:
+ dpm_desc = &skutable->DpmDescriptor[PPCLK_FCLK];
+ freqtable = skutable->FreqTableFclk;
+ break;
+ case SMU_VCLK:
+ dpm_desc = &skutable->DpmDescriptor[PPCLK_VCLK_0];
+ freqtable = skutable->FreqTableVclk;
+ break;
+ case SMU_DCLK:
+ dpm_desc = &skutable->DpmDescriptor[PPCLK_DCLK_0];
+ freqtable = skutable->FreqTableDclk;
+ break;
+ case SMU_DCEFCLK:
+ dpm_desc = &skutable->DpmDescriptor[PPCLK_DCFCLK];
+ freqtable = skutable->FreqTableDcfclk;
+ break;
+ default:
+ dev_dbg(smu->adev->dev, "[%s] Unsupported smu clock type: %d!",
+ __func__, clk_type);
+ return -EINVAL;
+ }
+
If this is only internal usage (only known clock types are passed),
probably this also can be made void and avoid the return checks at
caller site.
Thanks,
Lijo
+ return smu_v14_0_2_set_dpm_table(smu, clk_type, dpm_table, dpm_desc,
freqtable);
+}
+
static int smu_v14_0_2_set_default_dpm_table(struct smu_context *smu)
{
struct smu_14_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
@@ -510,9 +580,9 @@ static int smu_v14_0_2_set_default_dpm_table(struct
smu_context *smu)
dpm_table = &dpm_context->dpm_tables.soc_table;
dpm_table->clk_type = SMU_SOCCLK;
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
- ret = smu_v14_0_set_single_dpm_table(smu,
- SMU_SOCCLK,
- dpm_table);
+ ret = smu_v14_0_2_set_dpm_table_by_pptable(smu,
+ SMU_SOCCLK,
+ dpm_table);
if (ret)
return ret;
} else {
@@ -525,9 +595,9 @@ static int smu_v14_0_2_set_default_dpm_table(struct
smu_context *smu)
dpm_table = &dpm_context->dpm_tables.gfx_table;
dpm_table->clk_type = SMU_GFXCLK;
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
- ret = smu_v14_0_set_single_dpm_table(smu,
- SMU_GFXCLK,
- dpm_table);
+ ret = smu_v14_0_2_set_dpm_table_by_pptable(smu,
+ SMU_GFXCLK,
+ dpm_table);
if (ret)
return ret;
@@ -556,9 +626,9 @@ static int smu_v14_0_2_set_default_dpm_table(struct smu_context *smu)
dpm_table = &dpm_context->dpm_tables.uclk_table;
dpm_table->clk_type = SMU_UCLK;
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
- ret = smu_v14_0_set_single_dpm_table(smu,
- SMU_UCLK,
- dpm_table);
+ ret = smu_v14_0_2_set_dpm_table_by_pptable(smu,
+ SMU_UCLK,
+ dpm_table);
if (ret)
return ret;
} else {
@@ -571,9 +641,9 @@ static int smu_v14_0_2_set_default_dpm_table(struct
smu_context *smu)
dpm_table = &dpm_context->dpm_tables.fclk_table;
dpm_table->clk_type = SMU_FCLK;
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
- ret = smu_v14_0_set_single_dpm_table(smu,
- SMU_FCLK,
- dpm_table);
+ ret = smu_v14_0_2_set_dpm_table_by_pptable(smu,
+ SMU_FCLK,
+ dpm_table);
if (ret)
return ret;
} else {
@@ -586,9 +656,9 @@ static int smu_v14_0_2_set_default_dpm_table(struct
smu_context *smu)
dpm_table = &dpm_context->dpm_tables.vclk_table;
dpm_table->clk_type = SMU_VCLK;
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_VCLK_BIT)) {
- ret = smu_v14_0_set_single_dpm_table(smu,
- SMU_VCLK,
- dpm_table);
+ ret = smu_v14_0_2_set_dpm_table_by_pptable(smu,
+ SMU_VCLK,
+ dpm_table);
if (ret)
return ret;
} else {
@@ -601,9 +671,9 @@ static int smu_v14_0_2_set_default_dpm_table(struct
smu_context *smu)
dpm_table = &dpm_context->dpm_tables.dclk_table;
dpm_table->clk_type = SMU_DCLK;
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCLK_BIT)) {
- ret = smu_v14_0_set_single_dpm_table(smu,
- SMU_DCLK,
- dpm_table);
+ ret = smu_v14_0_2_set_dpm_table_by_pptable(smu,
+ SMU_DCLK,
+ dpm_table);
if (ret)
return ret;
} else {
@@ -616,9 +686,9 @@ static int smu_v14_0_2_set_default_dpm_table(struct
smu_context *smu)
dpm_table = &dpm_context->dpm_tables.dcef_table;
dpm_table->clk_type = SMU_DCEFCLK;
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCN_BIT)) {
- ret = smu_v14_0_set_single_dpm_table(smu,
- SMU_DCEFCLK,
- dpm_table);
+ ret = smu_v14_0_2_set_dpm_table_by_pptable(smu,
+ SMU_DCEFCLK,
+ dpm_table);
if (ret)
return ret;
} else {