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

Reply via email to