From: Kenneth Feng <kenneth.feng@xxxxxxx> set the workload type based on MALL status Signed-off-by: Kenneth Feng <kenneth.feng@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 4 ++-- .../drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 12 ++++++++++-- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 2 +- drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 4 ++-- drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 +- .../gpu/drm/amd/pm/powerplay/amd_powerplay.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 17 ++++++++++------- 8 files changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 2e5732dfd425..9b2bdf0273f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -730,7 +730,7 @@ void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle) } amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_COMPUTE, - !idle); + !idle, false); } bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 83faf6e6788a..393eea91ad0e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -423,7 +423,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, AMD_PG_STATE_GATE); r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, - false); + false, false); if (r) dev_warn(adev->dev, "(%d) failed to disable video power profile mode\n", r); } else { @@ -440,7 +440,7 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) if (!cancel_delayed_work_sync(&adev->vcn.idle_work)) { r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO, - true); + true, false); if (r) dev_warn(adev->dev, "(%d) failed to switch to video power profile mode\n", r); } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 8bc73922e3a6..fc6d8bb7cc11 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -34,6 +34,7 @@ #include "amdgpu_dm_plane.h" #include "amdgpu_dm_trace.h" #include "amdgpu_dm_debugfs.h" +#include "amdgpu_smu.h" #define HPD_DETECTION_PERIOD_uS 2000000 #define HPD_DETECTION_TIME_uS 100000 @@ -244,6 +245,9 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) struct vblank_control_work *vblank_work = container_of(work, struct vblank_control_work, work); struct amdgpu_display_manager *dm = vblank_work->dm; + struct amdgpu_device *adev = dm->adev; + struct smu_context *smu = (struct smu_context*)(adev->powerplay.pp_handle); + int profile_mode = smu->power_profile_mode; mutex_lock(&dm->dc_lock); @@ -252,8 +256,10 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) else if (dm->active_vblank_irq_count) dm->active_vblank_irq_count--; - if (dm->active_vblank_irq_count > 0) + if (dm->active_vblank_irq_count > 0) { + amdgpu_dpm_switch_power_profile(adev, profile_mode, true, false); dc_allow_idle_optimizations(dm->dc, false); + } /* * Control PSR based on vblank requirements from OS @@ -271,8 +277,10 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work) vblank_work->acrtc->dm_irq_params.allow_sr_entry); } - if (dm->active_vblank_irq_count == 0) + if (dm->active_vblank_irq_count == 0) { + amdgpu_dpm_switch_power_profile(adev, profile_mode, false, true); dc_allow_idle_optimizations(dm->dc, true); + } mutex_unlock(&dm->dc_lock); diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 9189dcb65188..cd56fa375f19 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -413,7 +413,7 @@ struct amd_pm_funcs { int (*get_pp_table)(void *handle, char **table); int (*set_pp_table)(void *handle, const char *buf, size_t size); void (*debugfs_print_current_performance_level)(void *handle, struct seq_file *m); - int (*switch_power_profile)(void *handle, enum PP_SMC_POWER_PROFILE type, bool en); + int (*switch_power_profile)(void *handle, enum PP_SMC_POWER_PROFILE type, bool en, bool force); /* export to amdgpu */ struct amd_vce_state *(*get_vce_clock_state)(void *handle, u32 idx); int (*dispatch_tasks)(void *handle, enum amd_pp_task task_id, diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 6a9e26905edf..0fd5b520d281 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -331,7 +331,7 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev) int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev, enum PP_SMC_POWER_PROFILE type, - bool en) + bool en, bool force) { const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; int ret = 0; @@ -342,7 +342,7 @@ int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev, if (pp_funcs && pp_funcs->switch_power_profile) { mutex_lock(&adev->pm.mutex); ret = pp_funcs->switch_power_profile( - adev->powerplay.pp_handle, type, en); + adev->powerplay.pp_handle, type, en, force); mutex_unlock(&adev->pm.mutex); } diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index 1f5ac7e0230d..b473c06d0b09 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -408,7 +408,7 @@ int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev, int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev, enum PP_SMC_POWER_PROFILE type, - bool en); + bool en, bool force); int amdgpu_dpm_baco_reset(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c index 686345f75f26..6095776ee0cb 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c @@ -909,7 +909,7 @@ static int pp_dpm_set_mp1_state(void *handle, enum pp_mp1_state mp1_state) } static int pp_dpm_switch_power_profile(void *handle, - enum PP_SMC_POWER_PROFILE type, bool en) + enum PP_SMC_POWER_PROFILE type, bool en, bool force) { struct pp_hwmgr *hwmgr = handle; long workload[1]; diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 8ca793c222ff..c48d3588fbc8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -75,7 +75,7 @@ static int smu_set_mp1_state(void *handle, enum pp_mp1_state mp1_state); static void smu_power_profile_mode_get(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile_mode); static void smu_power_profile_mode_put(struct smu_context *smu, - enum PP_SMC_POWER_PROFILE profile_mode); + enum PP_SMC_POWER_PROFILE profile_mode, bool force); static int smu_sys_get_pp_feature_mask(void *handle, char *buf) @@ -2287,8 +2287,11 @@ 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) + enum PP_SMC_POWER_PROFILE profile_mode, bool force) { + if (force) + smu->workload_refcount[profile_mode] = 0; + if (smu->workload_refcount[profile_mode]) smu->workload_refcount[profile_mode]--; } @@ -2382,7 +2385,7 @@ static int smu_handle_dpm_task(void *handle, static int smu_switch_power_profile(void *handle, enum PP_SMC_POWER_PROFILE type, - bool enable) + bool enable, bool force) { struct smu_context *smu = handle; struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); @@ -2399,11 +2402,11 @@ static int smu_switch_power_profile(void *handle, if (enable) smu_power_profile_mode_get(smu, type); else - smu_power_profile_mode_put(smu, type); + smu_power_profile_mode_put(smu, type, force); ret = smu_bump_power_profile_mode(smu, NULL, 0); if (ret) { if (enable) - smu_power_profile_mode_put(smu, type); + smu_power_profile_mode_put(smu, type, force); else smu_power_profile_mode_get(smu, type); return ret; @@ -3122,14 +3125,14 @@ static int smu_set_power_profile_mode(void *handle, if ((param[param_size] != smu->power_profile_mode) || custom) { /* clear the old user preference */ - smu_power_profile_mode_put(smu, smu->power_profile_mode); + smu_power_profile_mode_put(smu, smu->power_profile_mode, false); /* set the new user preference */ smu_power_profile_mode_get(smu, param[param_size]); ret = smu_bump_power_profile_mode(smu, custom ? param : NULL, custom ? param_size : 0); if (ret) - smu_power_profile_mode_put(smu, param[param_size]); + smu_power_profile_mode_put(smu, param[param_size], false); else /* store the user's preference */ smu->power_profile_mode = param[param_size]; -- 2.39.5