<div dir="ltr"><div dir="ltr">On Tue, Nov 12, 2024 at 1:18 AM Lazar, Lijo <<a href="mailto:lijo.lazar@amd.com">lijo.lazar@amd.com</a>> wrote:</div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
On 11/9/2024 11:01 AM, Alex Deucher wrote:<br>
> smu->workload_mask is IP specific and should not be messed with in<br>
> the common code. The mask bits vary across SMU versions.<br>
> <br>
> Move all handling of smu->workload_mask in to the backends and<br>
> simplify the code. Store the user's preference in smu->power_profile_mode<br>
> which will be reflected in sysfs. For internal driver profile<br>
> switches for KFD or VCN, just update the workload mask so that the<br>
> user's preference is retained. Remove all of the extra now unused<br>
> workload related elements in the smu structure.<br>
> <br>
> Fixes: 8cc438be5d49 ("drm/amd/pm: correct the workload setting")<br>
> Signed-off-by: Alex Deucher <<a href="mailto:alexander.deucher@amd.com" target="_blank">alexander.deucher@amd.com</a>><br>
> Cc: Kenneth Feng <<a href="mailto:kenneth.feng@amd.com" target="_blank">kenneth.feng@amd.com</a>><br>
> Cc: Lijo Lazar <<a href="mailto:lijo.lazar@amd.com" target="_blank">lijo.lazar@amd.com</a>><br>
> ---<br>
> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 108 ++++++------------<br>
> drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 11 +-<br>
> .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 20 ++--<br>
> .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 20 ++--<br>
> .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 21 ++--<br>
> .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 17 +--<br>
> .../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 17 +--<br>
> .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 33 +++---<br>
> .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 21 ++--<br>
> .../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 24 ++--<br>
> drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 8 --<br>
> drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 2 -<br>
> 12 files changed, 132 insertions(+), 170 deletions(-)<br>
> <br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c<br>
> index c3a6b6f20455..162a3289855c 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c<br>
> @@ -1268,9 +1268,6 @@ static int smu_sw_init(struct amdgpu_ip_block *ip_block)<br>
> INIT_WORK(&smu->interrupt_work, smu_interrupt_work_fn);<br>
> atomic64_set(&smu->throttle_int_counter, 0);<br>
> smu->watermarks_bitmap = 0;<br>
> - smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;<br>
> - smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;<br>
> - smu->user_dpm_profile.user_workload_mask = 0;<br>
> <br>
> for (i = 0; i < adev->vcn.num_vcn_inst; i++)<br>
> atomic_set(&smu->smu_power.power_gate.vcn_gated[i], 1);<br>
> @@ -1278,33 +1275,12 @@ static int smu_sw_init(struct amdgpu_ip_block *ip_block)<br>
> atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);<br>
> atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1);<br>
> <br>
> - smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;<br>
> - smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;<br>
> - smu->workload_priority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;<br>
> - smu->workload_priority[PP_SMC_POWER_PROFILE_VIDEO] = 3;<br>
> - smu->workload_priority[PP_SMC_POWER_PROFILE_VR] = 4;<br>
> - smu->workload_priority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;<br>
> - smu->workload_priority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;<br>
> -<br>
> if (smu->is_apu ||<br>
> - !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D)) {<br>
> - smu->driver_workload_mask =<br>
> - 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];<br>
> - } else {<br>
> - smu->driver_workload_mask =<br>
> - 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];<br>
> - smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;<br>
> - }<br>
> -<br>
> - smu->workload_mask = smu->driver_workload_mask |<br>
> - smu->user_dpm_profile.user_workload_mask;<br>
> - smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;<br>
> - smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;<br>
> - smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;<br>
> - smu->workload_setting[3] = PP_SMC_POWER_PROFILE_VIDEO;<br>
> - smu->workload_setting[4] = PP_SMC_POWER_PROFILE_VR;<br>
> - smu->workload_setting[5] = PP_SMC_POWER_PROFILE_COMPUTE;<br>
> - smu->workload_setting[6] = PP_SMC_POWER_PROFILE_CUSTOM;<br>
> + !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D))<br>
> + smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;<br>
> + else<br>
> + smu->power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D;<br>
> +<br>
> smu->display_config = &adev->pm.pm_display_cfg;<br>
> <br>
> smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;<br>
> @@ -2252,24 +2228,23 @@ static int smu_enable_umd_pstate(void *handle,<br>
> }<br>
> <br>
> static int smu_bump_power_profile_mode(struct smu_context *smu,<br>
> - long *param,<br>
> - uint32_t param_size)<br>
> + long *param,<br>
> + uint32_t param_size,<br>
> + bool enable)<br>
> {<br>
> int ret = 0;<br>
> <br>
> if (smu->ppt_funcs->set_power_profile_mode)<br>
> - ret = smu->ppt_funcs->set_power_profile_mode(smu, param, param_size);<br>
> + ret = smu->ppt_funcs->set_power_profile_mode(smu, param, param_size, enable);<br>
> <br>
> return ret;<br>
> }<br>
> <br>
> static int smu_adjust_power_state_dynamic(struct smu_context *smu,<br>
> enum amd_dpm_forced_level level,<br>
> - bool skip_display_settings,<br>
> - bool init)<br>
> + bool skip_display_settings)<br>
> {<br>
> int ret = 0;<br>
> - int index = 0;<br>
> long workload[1];<br>
> struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);<br>
> <br>
> @@ -2307,13 +2282,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,<br>
> }<br>
> <br>
> if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&<br>
> - smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {<br>
> - index = fls(smu->workload_mask);<br>
> - index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;<br>
> - workload[0] = smu->workload_setting[index];<br>
> + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {<br>
> + workload[0] = smu->power_profile_mode;<br>
> <br>
> - if (init || smu->power_profile_mode != workload[0])<br>
> - smu_bump_power_profile_mode(smu, workload, 0);<br>
> + smu_bump_power_profile_mode(smu, workload, 0, true);<br>
> }<br>
> <br>
> return ret;<br>
> @@ -2333,13 +2305,13 @@ static int smu_handle_task(struct smu_context *smu,<br>
> ret = smu_pre_display_config_changed(smu);<br>
> if (ret)<br>
> return ret;<br>
> - ret = smu_adjust_power_state_dynamic(smu, level, false, false);<br>
> + ret = smu_adjust_power_state_dynamic(smu, level, false);<br>
> break;<br>
> case AMD_PP_TASK_COMPLETE_INIT:<br>
> - ret = smu_adjust_power_state_dynamic(smu, level, true, true);<br>
> + ret = smu_adjust_power_state_dynamic(smu, level, true);<br>
> break;<br>
> case AMD_PP_TASK_READJUST_POWER_STATE:<br>
> - ret = smu_adjust_power_state_dynamic(smu, level, true, false);<br>
> + ret = smu_adjust_power_state_dynamic(smu, level, true);<br>
> break;<br>
> default:<br>
> break;<br>
> @@ -2361,12 +2333,11 @@ static int smu_handle_dpm_task(void *handle,<br>
> <br>
> static int smu_switch_power_profile(void *handle,<br>
> enum PP_SMC_POWER_PROFILE type,<br>
> - bool en)<br>
> + bool enable)<br>
> {<br>
> struct smu_context *smu = handle;<br>
> struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);<br>
> long workload[1];<br>
> - uint32_t index;<br>
> <br>
> if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)<br>
> return -EOPNOTSUPP;<br>
> @@ -2374,24 +2345,15 @@ static int smu_switch_power_profile(void *handle,<br>
> if (!(type < PP_SMC_POWER_PROFILE_CUSTOM))<br>
> return -EINVAL;<br>
> <br>
> - if (!en) {<br>
> - smu->driver_workload_mask &= ~(1 << smu->workload_priority[type]);<br>
> - index = fls(smu->workload_mask);<br>
> - index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;<br>
> - workload[0] = smu->workload_setting[index];<br>
> - } else {<br>
> - smu->driver_workload_mask |= (1 << smu->workload_priority[type]);<br>
> - index = fls(smu->workload_mask);<br>
> - index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;<br>
> - workload[0] = smu->workload_setting[index];<br>
> - }<br>
> + /* don't disable the user's preference */<br>
> + if (!enable && type == smu->power_profile_mode)<br>
> + return 0;<br>
> <br>
> - smu->workload_mask = smu->driver_workload_mask |<br>
> - smu->user_dpm_profile.user_workload_mask;<br>
> + workload[0] = type;<br>
> <br>
> if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&<br>
> - smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)<br>
> - smu_bump_power_profile_mode(smu, workload, 0);<br>
> + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)<br>
> + smu_bump_power_profile_mode(smu, workload, 0, enable);<br>
> <br>
> return 0;<br>
> }<br>
> @@ -3090,21 +3052,25 @@ static int smu_set_power_profile_mode(void *handle,<br>
> uint32_t param_size)<br>
> {<br>
> struct smu_context *smu = handle;<br>
> - int ret;<br>
> + long workload[1];<br>
> + int ret = 0;<br>
> <br>
> if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||<br>
> !smu->ppt_funcs->set_power_profile_mode)<br>
> return -EOPNOTSUPP;<br>
> <br>
> - if (smu->user_dpm_profile.user_workload_mask &<br>
> - (1 << smu->workload_priority[param[param_size]]))<br>
> - return 0;<br>
> -<br>
> - smu->user_dpm_profile.user_workload_mask =<br>
> - (1 << smu->workload_priority[param[param_size]]);<br>
> - smu->workload_mask = smu->user_dpm_profile.user_workload_mask |<br>
> - smu->driver_workload_mask;<br>
> - ret = smu_bump_power_profile_mode(smu, param, param_size);<br>
> + if (param[param_size] != smu->power_profile_mode) {<br>
> + /* clear the old user preference */<br>
> + workload[0] = smu->power_profile_mode;<br>
> + ret = smu_bump_power_profile_mode(smu, workload, 0, false);<br>
<br>
What if internal driver call has set the same profile preference? Once<br>
this is done, that setting is lost. There is a check to make sure that<br>
user setting is not lost, but the same is not done here and cannot be<br>
done with a single profile mode value.<br></blockquote><div><br></div><div>Yeah, I think we need to ref count the workload hints so we keep the mask up to date.</div><div><br></div><div>Alex<br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Thanks,<br>
Lijo<br>
<br>
> + if (ret)<br>
> + return ret;<br>
> + /* set the new user preference */<br>
> + ret = smu_bump_power_profile_mode(smu, param, param_size, true);<br>
> + if (!ret)<br>
> + /* store the user's preference */<br>
> + smu->power_profile_mode = param[param_size];<br>
> + }<br>
> <br>
> return ret;<br>
> }<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h<br>
> index fa93a8879113..cd2db06d752b 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h<br>
> @@ -240,7 +240,6 @@ struct smu_user_dpm_profile {<br>
> /* user clock state information */<br>
> uint32_t clk_mask[SMU_CLK_COUNT];<br>
> uint32_t clk_dependency;<br>
> - uint32_t user_workload_mask;<br>
> };<br>
> <br>
> #define SMU_TABLE_INIT(tables, table_id, s, a, d) \<br>
> @@ -557,12 +556,10 @@ struct smu_context {<br>
> uint32_t hard_min_uclk_req_from_dal;<br>
> bool disable_uclk_switch;<br>
> <br>
> + /* backend specific workload mask */<br>
> uint32_t workload_mask;<br>
> - uint32_t driver_workload_mask;<br>
> - uint32_t workload_priority[WORKLOAD_POLICY_MAX];<br>
> - uint32_t workload_setting[WORKLOAD_POLICY_MAX];<br>
> + /* default/user workload preference */<br>
> uint32_t power_profile_mode;<br>
> - uint32_t default_power_profile_mode;<br>
> bool pm_enabled;<br>
> bool is_apu;<br>
> <br>
> @@ -734,8 +731,10 @@ struct pptable_funcs {<br>
> * create/set custom power profile modes.<br>
> * &input: Power profile mode parameters.<br>
> * &size: Size of &input.<br>
> + * &enable: enable/disable the profile<br>
> */<br>
> - int (*set_power_profile_mode)(struct smu_context *smu, long *input, uint32_t size);<br>
> + int (*set_power_profile_mode)(struct smu_context *smu, long *input,<br>
> + uint32_t size, bool enable);<br>
> <br>
> /**<br>
> * @dpm_set_vcn_enable: Enable/disable VCN engine dynamic power<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c<br>
> index 4b36c230e43a..1e44cf6fec4b 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c<br>
> @@ -1443,7 +1443,8 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu,<br>
> <br>
> static int arcturus_set_power_profile_mode(struct smu_context *smu,<br>
> long *input,<br>
> - uint32_t size)<br>
> + uint32_t size,<br>
> + bool enable)<br>
> {<br>
> DpmActivityMonitorCoeffInt_t activity_monitor;<br>
> int workload_type = 0;<br>
> @@ -1455,8 +1456,9 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu,<br>
> return -EINVAL;<br>
> }<br>
> <br>
> - if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&<br>
> - (smu->smc_fw_version >= 0x360d00)) {<br>
> + if (enable &&<br>
> + (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&<br>
> + (smu->smc_fw_version >= 0x360d00)) {<br>
> if (size != 10)<br>
> return -EINVAL;<br>
> <br>
> @@ -1520,18 +1522,18 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu,<br>
> return -EINVAL;<br>
> }<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= (1 << workload_type);<br>
> + else<br>
> + smu->workload_mask &= ~(1 << workload_type);<br>
> ret = smu_cmn_send_smc_msg_with_param(smu,<br>
> SMU_MSG_SetWorkloadMask,<br>
> smu->workload_mask,<br>
> NULL);<br>
> - if (ret) {<br>
> + if (ret)<br>
> dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type);<br>
> - return ret;<br>
> - }<br>
> -<br>
> - smu_cmn_assign_power_profile(smu);<br>
> <br>
> - return 0;<br>
> + return ret;<br>
> }<br>
> <br>
> static int arcturus_set_performance_level(struct smu_context *smu,<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c<br>
> index 211635dabed8..d944a9f954d0 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c<br>
> @@ -2006,19 +2006,19 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf)<br>
> return size;<br>
> }<br>
> <br>
> -static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)<br>
> +static int navi10_set_power_profile_mode(struct smu_context *smu, long *input,<br>
> + uint32_t size, bool enable)<br>
> {<br>
> DpmActivityMonitorCoeffInt_t activity_monitor;<br>
> int workload_type, ret = 0;<br>
> + uint32_t profile_mode = input[size];<br>
> <br>
> - smu->power_profile_mode = input[size];<br>
> -<br>
> - if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);<br>
> + if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> + dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);<br>
> return -EINVAL;<br>
> }<br>
> <br>
> - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> + if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> if (size != 10)<br>
> return -EINVAL;<br>
> <br>
> @@ -2080,16 +2080,18 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u<br>
> /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */<br>
> workload_type = smu_cmn_to_asic_specific_index(smu,<br>
> CMN2ASIC_MAPPING_WORKLOAD,<br>
> - smu->power_profile_mode);<br>
> + profile_mode);<br>
> if (workload_type < 0)<br>
> return -EINVAL;<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= (1 << workload_type);<br>
> + else<br>
> + smu->workload_mask &= ~(1 << workload_type);<br>
> ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,<br>
> smu->workload_mask, NULL);<br>
> if (ret)<br>
> dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);<br>
> - else<br>
> - smu_cmn_assign_power_profile(smu);<br>
> <br>
> return ret;<br>
> }<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c<br>
> index 844532a9b641..4967e087088b 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c<br>
> @@ -1704,22 +1704,23 @@ static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char *<br>
> return size;<br>
> }<br>
> <br>
> -static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)<br>
> +static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu,<br>
> + long *input, uint32_t size,<br>
> + bool enable)<br>
> {<br>
> <br>
> DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;<br>
> DpmActivityMonitorCoeffInt_t *activity_monitor =<br>
> &(activity_monitor_external.DpmActivityMonitorCoeffInt);<br>
> + uint32_t profile_mode = input[size];<br>
> int workload_type, ret = 0;<br>
> <br>
> - smu->power_profile_mode = input[size];<br>
> -<br>
> - if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);<br>
> + if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> + dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);<br>
> return -EINVAL;<br>
> }<br>
> <br>
> - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> + if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> if (size != 10)<br>
> return -EINVAL;<br>
> <br>
> @@ -1781,16 +1782,18 @@ static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *<br>
> /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */<br>
> workload_type = smu_cmn_to_asic_specific_index(smu,<br>
> CMN2ASIC_MAPPING_WORKLOAD,<br>
> - smu->power_profile_mode);<br>
> + profile_mode);<br>
> if (workload_type < 0)<br>
> return -EINVAL;<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= (1 << workload_type);<br>
> + else<br>
> + smu->workload_mask &= ~(1 << workload_type);<br>
> ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,<br>
> smu->workload_mask, NULL);<br>
> if (ret)<br>
> dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);<br>
> - else<br>
> - smu_cmn_assign_power_profile(smu);<br>
> <br>
> return ret;<br>
> }<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c<br>
> index f89c487dce72..b5dba4826f81 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c<br>
> @@ -1056,7 +1056,8 @@ static int vangogh_get_power_profile_mode(struct smu_context *smu,<br>
> return size;<br>
> }<br>
> <br>
> -static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)<br>
> +static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,<br>
> + uint32_t size, bool enable)<br>
> {<br>
> int workload_type, ret;<br>
> uint32_t profile_mode = input[size];<br>
> @@ -1067,7 +1068,7 @@ static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,<br>
> }<br>
> <br>
> if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||<br>
> - profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)<br>
> + profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)<br>
> return 0;<br>
> <br>
> /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */<br>
> @@ -1080,18 +1081,18 @@ static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input,<br>
> return -EINVAL;<br>
> }<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= (1 << workload_type);<br>
> + else<br>
> + smu->workload_mask &= ~(1 << workload_type);<br>
> ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,<br>
> smu->workload_mask,<br>
> NULL);<br>
> - if (ret) {<br>
> + if (ret)<br>
> dev_err_once(smu->adev->dev, "Fail to set workload type %d\n",<br>
> workload_type);<br>
> - return ret;<br>
> - }<br>
> -<br>
> - smu_cmn_assign_power_profile(smu);<br>
> <br>
> - return 0;<br>
> + return ret;<br>
> }<br>
> <br>
> static int vangogh_set_soft_freq_limited_range(struct smu_context *smu,<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c<br>
> index 75a9ea87f419..2d1eae79ab9d 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c<br>
> @@ -864,7 +864,8 @@ static int renoir_force_clk_levels(struct smu_context *smu,<br>
> return ret;<br>
> }<br>
> <br>
> -static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)<br>
> +static int renoir_set_power_profile_mode(struct smu_context *smu, long *input,<br>
> + uint32_t size, bool enable)<br>
> {<br>
> int workload_type, ret;<br>
> uint32_t profile_mode = input[size];<br>
> @@ -875,7 +876,7 @@ static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, u<br>
> }<br>
> <br>
> if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT ||<br>
> - profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)<br>
> + profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING)<br>
> return 0;<br>
> <br>
> /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */<br>
> @@ -891,17 +892,17 @@ static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, u<br>
> return -EINVAL;<br>
> }<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= (1 << workload_type);<br>
> + else<br>
> + smu->workload_mask &= ~(1 << workload_type);<br>
> ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,<br>
> smu->workload_mask,<br>
> NULL);<br>
> - if (ret) {<br>
> + if (ret)<br>
> dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type);<br>
> - return ret;<br>
> - }<br>
> <br>
> - smu_cmn_assign_power_profile(smu);<br>
> -<br>
> - return 0;<br>
> + return ret;<br>
> }<br>
> <br>
> static int renoir_set_peak_clock_by_device(struct smu_context *smu)<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c<br>
> index 80c6b1e523aa..3cc734331891 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c<br>
> @@ -2573,22 +2573,22 @@ static int smu_v13_0_0_get_power_profile_mode(struct smu_context *smu,<br>
> <br>
> static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,<br>
> long *input,<br>
> - uint32_t size)<br>
> + uint32_t size,<br>
> + bool enable)<br>
> {<br>
> DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;<br>
> DpmActivityMonitorCoeffInt_t *activity_monitor =<br>
> &(activity_monitor_external.DpmActivityMonitorCoeffInt);<br>
> + uint32_t profile_mode = input[size];<br>
> int workload_type, ret = 0;<br>
> u32 workload_mask;<br>
> <br>
> - smu->power_profile_mode = input[size];<br>
> -<br>
> - if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {<br>
> - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);<br>
> + if (profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {<br>
> + dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);<br>
> return -EINVAL;<br>
> }<br>
> <br>
> - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> + if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> if (size != 9)<br>
> return -EINVAL;<br>
> <br>
> @@ -2641,13 +2641,18 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,<br>
> /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */<br>
> workload_type = smu_cmn_to_asic_specific_index(smu,<br>
> CMN2ASIC_MAPPING_WORKLOAD,<br>
> - smu->power_profile_mode);<br>
> + profile_mode);<br>
> <br>
> if (workload_type < 0)<br>
> return -EINVAL;<br>
> <br>
> workload_mask = 1 << workload_type;<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= workload_mask;<br>
> + else<br>
> + smu->workload_mask &= ~workload_mask;<br>
> +<br>
> /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */<br>
> if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&<br>
> ((smu->adev->pm.fw_version == 0x004e6601) ||<br>
> @@ -2658,25 +2663,13 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,<br>
> CMN2ASIC_MAPPING_WORKLOAD,<br>
> PP_SMC_POWER_PROFILE_POWERSAVING);<br>
> if (workload_type >= 0)<br>
> - workload_mask |= 1 << workload_type;<br>
> + smu->workload_mask |= 1 << workload_type;<br>
> }<br>
> <br>
> - smu->workload_mask |= workload_mask;<br>
> ret = smu_cmn_send_smc_msg_with_param(smu,<br>
> SMU_MSG_SetWorkloadMask,<br>
> smu->workload_mask,<br>
> NULL);<br>
> - if (!ret) {<br>
> - smu_cmn_assign_power_profile(smu);<br>
> - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING) {<br>
> - workload_type = smu_cmn_to_asic_specific_index(smu,<br>
> - CMN2ASIC_MAPPING_WORKLOAD,<br>
> - PP_SMC_POWER_PROFILE_FULLSCREEN3D);<br>
> - smu->power_profile_mode = smu->workload_mask & (1 << workload_type)<br>
> - ? PP_SMC_POWER_PROFILE_FULLSCREEN3D<br>
> - : PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;<br>
> - }<br>
> - }<br>
> <br>
> return ret;<br>
> }<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c<br>
> index c5d3e25cc967..1aafd23857f0 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c<br>
> @@ -2528,22 +2528,23 @@ do { \<br>
> return result;<br>
> }<br>
> <br>
> -static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)<br>
> +static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu,<br>
> + long *input, uint32_t size,<br>
> + bool enable)<br>
> {<br>
> <br>
> DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;<br>
> DpmActivityMonitorCoeffInt_t *activity_monitor =<br>
> &(activity_monitor_external.DpmActivityMonitorCoeffInt);<br>
> + uint32_t profile_mode = input[size];<br>
> int workload_type, ret = 0;<br>
> <br>
> - smu->power_profile_mode = input[size];<br>
> -<br>
> - if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) {<br>
> - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);<br>
> + if (profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) {<br>
> + dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);<br>
> return -EINVAL;<br>
> }<br>
> <br>
> - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> + if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> if (size != 8)<br>
> return -EINVAL;<br>
> <br>
> @@ -2590,17 +2591,19 @@ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *inp<br>
> /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */<br>
> workload_type = smu_cmn_to_asic_specific_index(smu,<br>
> CMN2ASIC_MAPPING_WORKLOAD,<br>
> - smu->power_profile_mode);<br>
> + profile_mode);<br>
> if (workload_type < 0)<br>
> return -EINVAL;<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= (1 << workload_type);<br>
> + else<br>
> + smu->workload_mask &= ~(1 << workload_type);<br>
> ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,<br>
> smu->workload_mask, NULL);<br>
> <br>
> if (ret)<br>
> dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__);<br>
> - else<br>
> - smu_cmn_assign_power_profile(smu);<br>
> <br>
> return ret;<br>
> }<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c<br>
> index 59b369eff30f..695480833603 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c<br>
> @@ -1719,21 +1719,22 @@ static int smu_v14_0_2_get_power_profile_mode(struct smu_context *smu,<br>
> <br>
> static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,<br>
> long *input,<br>
> - uint32_t size)<br>
> + uint32_t size,<br>
> + bool enable)<br>
> {<br>
> DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;<br>
> DpmActivityMonitorCoeffInt_t *activity_monitor =<br>
> &(activity_monitor_external.DpmActivityMonitorCoeffInt);<br>
> + uint32_t profile_mode = input[size];<br>
> int workload_type, ret = 0;<br>
> uint32_t current_profile_mode = smu->power_profile_mode;<br>
> - smu->power_profile_mode = input[size];<br>
> <br>
> - if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {<br>
> - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);<br>
> + if (profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {<br>
> + dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);<br>
> return -EINVAL;<br>
> }<br>
> <br>
> - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> + if (enable && profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {<br>
> if (size != 9)<br>
> return -EINVAL;<br>
> <br>
> @@ -1783,7 +1784,7 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,<br>
> }<br>
> }<br>
> <br>
> - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)<br>
> + if (profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)<br>
> smu_v14_0_deep_sleep_control(smu, false);<br>
> else if (current_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)<br>
> smu_v14_0_deep_sleep_control(smu, true);<br>
> @@ -1791,15 +1792,16 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,<br>
> /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */<br>
> workload_type = smu_cmn_to_asic_specific_index(smu,<br>
> CMN2ASIC_MAPPING_WORKLOAD,<br>
> - smu->power_profile_mode);<br>
> + profile_mode);<br>
> if (workload_type < 0)<br>
> return -EINVAL;<br>
> <br>
> + if (enable)<br>
> + smu->workload_mask |= (1 << workload_type);<br>
> + else<br>
> + smu->workload_mask &= ~(1 << workload_type);<br>
> ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,<br>
> - smu->workload_mask, NULL);<br>
> -<br>
> - if (!ret)<br>
> - smu_cmn_assign_power_profile(smu);<br>
> + smu->workload_mask, NULL);<br>
> <br>
> return ret;<br>
> }<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c<br>
> index fd2aa949538e..63c4f75fa118 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c<br>
> @@ -1141,14 +1141,6 @@ int smu_cmn_set_mp1_state(struct smu_context *smu,<br>
> return ret;<br>
> }<br>
> <br>
> -void smu_cmn_assign_power_profile(struct smu_context *smu)<br>
> -{<br>
> - uint32_t index;<br>
> - index = fls(smu->workload_mask);<br>
> - index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;<br>
> - smu->power_profile_mode = smu->workload_setting[index];<br>
> -}<br>
> -<br>
> bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)<br>
> {<br>
> struct pci_dev *p = NULL;<br>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h<br>
> index 8a801e389659..1de685defe85 100644<br>
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h<br>
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h<br>
> @@ -130,8 +130,6 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev);<br>
> int smu_cmn_set_mp1_state(struct smu_context *smu,<br>
> enum pp_mp1_state mp1_state);<br>
> <br>
> -void smu_cmn_assign_power_profile(struct smu_context *smu);<br>
> -<br>
> /*<br>
> * Helper function to make sysfs_emit_at() happy. Align buf to<br>
> * the current page boundary and record the offset.<br>
</blockquote></div></div>