Add a timer to poll the SMT state periodically, if the SMT state is changed, invoke the interface to notify the PMFW. Signed-off-by: Wenyou Yang <WenYou.Yang@xxxxxxx> --- drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 8 ++++ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 44 +++++++++++++++++++ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 5 +++ 3 files changed, 57 insertions(+) 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 09469c750a96..fc571c122e87 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -566,6 +566,9 @@ struct smu_context struct firmware pptable_firmware; + bool last_smt_active; + struct timer_list smt_timer; + u32 param_reg; u32 msg_reg; u32 resp_reg; @@ -1354,6 +1357,11 @@ struct pptable_funcs { * @init_pptable_microcode: Prepare the pptable microcode to upload via PSP */ int (*init_pptable_microcode)(struct smu_context *smu); + + /** + * @set_cpu_smt_enable: Set the CPU SMT status. + */ + int (*set_cpu_smt_enable)(struct smu_context *smu, bool smt_enable); }; typedef enum { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index 3ecb900e6ecd..81c547a03f97 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -26,6 +26,7 @@ #include "amdgpu_smu.h" #include "smu_cmn.h" #include "soc15_common.h" +#include <linux/sched/smt.h> /* * DO NOT use these for err/warn/info/debug messages. @@ -1058,3 +1059,46 @@ bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev) return snd_driver_loaded; } + +#define TIME_INTERVAL 200 + +static int smu_set_cpu_smt_enable(struct smu_context *smu, bool enable) +{ + int ret = -EINVAL; + + if (smu->ppt_funcs && smu->ppt_funcs->set_cpu_smt_enable) + ret = smu->ppt_funcs->set_cpu_smt_enable(smu, enable); + + return ret; +} + +static void smu_smt_timer_callback(struct timer_list *timer) +{ + struct smu_context *smu = container_of(timer, + struct smu_context, smt_timer); + bool smt_active; + + smt_active = sched_smt_active(); + if (smt_active != smu->last_smt_active) { + if (!smu_set_cpu_smt_enable(smu, smt_active)) + smu->last_smt_active = smt_active; + } + + mod_timer(timer, jiffies + msecs_to_jiffies(TIME_INTERVAL)); +} + +void smu_smt_timer_init(struct smu_context *smu) +{ + struct timer_list *timer = &smu->smt_timer; + + smu->last_smt_active = sched_smt_active(); + + timer_setup(timer, smu_smt_timer_callback, 0); + + mod_timer(timer, jiffies + msecs_to_jiffies(TIME_INTERVAL)); +} + +void smu_smt_timer_fini(struct smu_context *smu) +{ + del_timer(&smu->smt_timer); +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index d7cd358a53bd..928dd9e30d83 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -127,5 +127,10 @@ static inline void smu_cmn_get_sysfs_buf(char **buf, int *offset) bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev); +void smu_smt_timer_init(struct smu_context *smu); + #endif + +void smu_smt_timer_fini(struct smu_context *smu); + #endif -- 2.39.2