User-configured SCLK(GPU core clock) frequency are not persisting
across S0ix suspend/resume cycles on smu v14 hardware. The issue
is because of the code updating the clock frequency during resume.

This patch resolves the issue by:
- Preserving user-configured values in driver and sets the clock
  frequency during resume
- Preserved settings are sent to the smu hardware

Signed-off-by: mythilam <[email protected]>
---
 .../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c    |  5 +++
 .../drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c  | 37 ++++++++++++++++---
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
index f9b0938c57ea..f2a16dfee599 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
@@ -1939,6 +1939,11 @@ int smu_v14_0_od_edit_dpm_table(struct smu_context *smu,
                        dev_err(smu->adev->dev, "Set soft max sclk failed!");
                        return ret;
                }
+               if (smu->gfx_actual_hard_min_freq != 
smu->gfx_default_hard_min_freq ||
+                   smu->gfx_actual_soft_max_freq != 
smu->gfx_default_soft_max_freq)
+                       smu->user_dpm_profile.user_od = true;
+               else
+                       smu->user_dpm_profile.user_od = false;
                break;
        default:
                return -ENOSYS;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
index fe00c84b1cc6..8d72a962aef7 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
@@ -1513,9 +1513,10 @@ static int 
smu_v14_0_1_set_fine_grain_gfx_freq_parameters(struct smu_context *sm
 
        smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
        smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
-       smu->gfx_actual_hard_min_freq = 0;
-       smu->gfx_actual_soft_max_freq = 0;
-
+       if (smu->gfx_actual_hard_min_freq == 0)
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+       if (smu->gfx_actual_soft_max_freq == 0)
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
        return 0;
 }
 
@@ -1525,8 +1526,10 @@ static int 
smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *sm
 
        smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
        smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
-       smu->gfx_actual_hard_min_freq = 0;
-       smu->gfx_actual_soft_max_freq = 0;
+       if (smu->gfx_actual_hard_min_freq == 0)
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+       if (smu->gfx_actual_soft_max_freq == 0)
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
 
        return 0;
 }
@@ -1664,6 +1667,29 @@ static int smu_v14_0_common_set_mall_enable(struct 
smu_context *smu)
        return ret;
 }
 
+static int smu_v14_0_0_restore_user_od_settings(struct smu_context *smu)
+{
+       int ret;
+
+       ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
+                                             smu->gfx_actual_hard_min_freq,
+                                             NULL);
+       if (ret) {
+               dev_err(smu->adev->dev, "Failed to restore hard min sclk on 
resume!\n");
+               return ret;
+       }
+
+       ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
+                                             smu->gfx_actual_soft_max_freq,
+                                             NULL);
+       if (ret) {
+               dev_err(smu->adev->dev, "Failed to restore soft max sclk on 
resume!\n");
+               return ret;
+       }
+
+       return 0;
+}
+
 static const struct pptable_funcs smu_v14_0_0_ppt_funcs = {
        .check_fw_status = smu_v14_0_check_fw_status,
        .check_fw_version = smu_v14_0_check_fw_version,
@@ -1687,6 +1713,7 @@ static const struct pptable_funcs smu_v14_0_0_ppt_funcs = 
{
        .mode2_reset = smu_v14_0_0_mode2_reset,
        .get_dpm_ultimate_freq = smu_v14_0_common_get_dpm_ultimate_freq,
        .set_soft_freq_limited_range = smu_v14_0_0_set_soft_freq_limited_range,
+       .restore_user_od_settings = smu_v14_0_0_restore_user_od_settings,
        .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table,
        .print_clk_levels = smu_v14_0_0_print_clk_levels,
        .force_clk_levels = smu_v14_0_0_force_clk_levels,
-- 
2.17.1

Reply via email to