Add the callback for implementation for swsmu.

Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
---
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c     | 36 ++++++++++++++++++-
 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  1 +
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index a01b6244d99cd..d23cfd5ba8dc7 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -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;
@@ -3759,6 +3792,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,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 27cecf9688ccb..a855ae249c739 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -560,6 +560,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];
-- 
2.49.0

Reply via email to