drm/amd: Restore cached manual clock settings during resume
authorMario Limonciello <mario.limonciello@amd.com>
Fri, 25 Jul 2025 03:12:22 +0000 (22:12 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 4 Aug 2025 19:37:26 +0000 (15:37 -0400)
If the SCLK limits have been set before S3 they will not
be restored. The limits are however cached in the driver and so
they can be restored by running a commit sequence during resume.

Acked-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/r/20250725031222.3015095-3-superm1@kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 4e9526924d09057a9ba854305e17eded900ced82)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c

index 310f51ff05b9e7c8900bbca7325ad8b838b0203d..b47cb4a5f4887d6d9bcf00abe3a08eb9ff792532 100644 (file)
@@ -77,6 +77,9 @@ static void smu_power_profile_mode_get(struct smu_context *smu,
 static void smu_power_profile_mode_put(struct smu_context *smu,
                                       enum PP_SMC_POWER_PROFILE profile_mode);
 static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type);
+static int smu_od_edit_dpm_table(void *handle,
+                                enum PP_OD_DPM_TABLE_COMMAND type,
+                                long *input, uint32_t size);
 
 static int smu_sys_get_pp_feature_mask(void *handle,
                                       char *buf)
@@ -2195,6 +2198,7 @@ static int smu_resume(struct amdgpu_ip_block *ip_block)
        int ret;
        struct amdgpu_device *adev = ip_block->adev;
        struct smu_context *smu = adev->powerplay.pp_handle;
+       struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
 
        if (amdgpu_sriov_multi_vf_mode(adev))
                return 0;
@@ -2232,6 +2236,12 @@ static int smu_resume(struct amdgpu_ip_block *ip_block)
                        return ret;
        }
 
+       if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
+               ret = smu_od_edit_dpm_table(smu, PP_OD_COMMIT_DPM_TABLE, NULL, 0);
+               if (ret)
+                       return ret;
+       }
+
        dev_info(adev->dev, "SMU is resumed successfully!\n");
 
        return 0;