]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amdgpu/pm/swsmu: implement pause workload profile
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 26 Mar 2025 14:54:56 +0000 (10:54 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 9 Apr 2025 14:53:11 +0000 (10:53 -0400)
Add the callback for implementation for swsmu.

Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 92e511d1cecc6a8fa7bdfc8657f16ece9ab4d456)

drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h

index 033c3229b555f04e94bc1a1e4d2e170c8b88256b..46cce1d2aaf3578eb395b750bc8f61d5d81555af 100644 (file)
@@ -2398,7 +2398,11 @@ static int smu_switch_power_profile(void *handle,
                        smu_power_profile_mode_get(smu, type);
                else
                        smu_power_profile_mode_put(smu, type);
-               ret = smu_bump_power_profile_mode(smu, NULL, 0);
+               /* don't switch the active workload when paused */
+               if (smu->pause_workload)
+                       ret = 0;
+               else
+                       ret = smu_bump_power_profile_mode(smu, NULL, 0);
                if (ret) {
                        if (enable)
                                smu_power_profile_mode_put(smu, type);
@@ -2411,6 +2415,35 @@ static int smu_switch_power_profile(void *handle,
        return 0;
 }
 
+static int smu_pause_power_profile(void *handle,
+                                  bool pause)
+{
+       struct smu_context *smu = handle;
+       struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+       u32 workload_mask = 1 << PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
+       int ret;
+
+       if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
+               return -EOPNOTSUPP;
+
+       if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
+           smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
+               smu->pause_workload = pause;
+
+               /* force to bootup default profile */
+               if (smu->pause_workload && smu->ppt_funcs->set_power_profile_mode)
+                       ret = smu->ppt_funcs->set_power_profile_mode(smu,
+                                                                    workload_mask,
+                                                                    NULL,
+                                                                    0);
+               else
+                       ret = smu_bump_power_profile_mode(smu, NULL, 0);
+               return ret;
+       }
+
+       return 0;
+}
+
 static enum amd_dpm_forced_level smu_get_performance_level(void *handle)
 {
        struct smu_context *smu = handle;
@@ -3733,6 +3766,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = {
        .get_pp_table            = smu_sys_get_pp_table,
        .set_pp_table            = smu_sys_set_pp_table,
        .switch_power_profile    = smu_switch_power_profile,
+       .pause_power_profile     = smu_pause_power_profile,
        /* export to amdgpu */
        .dispatch_tasks          = smu_handle_dpm_task,
        .load_firmware           = smu_load_microcode,
index 3ba169639f546061d0a5f13e3f91c531bc9ea3af..dd6d0e7aa2425dd0f339d39db5a1148ab0d40e79 100644 (file)
@@ -558,6 +558,7 @@ struct smu_context {
 
        /* asic agnostic workload mask */
        uint32_t workload_mask;
+       bool pause_workload;
        /* default/user workload preference */
        uint32_t power_profile_mode;
        uint32_t workload_refcount[PP_SMC_POWER_PROFILE_COUNT];