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; +} + +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; + } + + 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 { -- 2.34.1
