diff options
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c')
| -rw-r--r-- | drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 60 | 
1 files changed, 45 insertions, 15 deletions
| diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 9ad9cf7a9c98..ee1bcfaae3e3 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1234,6 +1234,14 @@ static void smu_init_xgmi_plpd_mode(struct smu_context *smu)  	}  } +static bool smu_is_workload_profile_available(struct smu_context *smu, +					      u32 profile) +{ +	if (profile >= PP_SMC_POWER_PROFILE_COUNT) +		return false; +	return smu->workload_map && smu->workload_map[profile].valid_mapping; +} +  static int smu_sw_init(void *handle)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -1251,25 +1259,33 @@ static int smu_sw_init(void *handle)  	smu->watermarks_bitmap = 0;  	smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;  	smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; +	smu->user_dpm_profile.user_workload_mask = 0;  	atomic_set(&smu->smu_power.power_gate.vcn_gated, 1);  	atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1);  	atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);  	atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1); -	smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0; -	smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1; -	smu->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2; -	smu->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3; -	smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4; -	smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5; -	smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6; - -	if (smu->is_apu) -		smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; -	else -		smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D]; +	smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0; +	smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1; +	smu->workload_priority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2; +	smu->workload_priority[PP_SMC_POWER_PROFILE_VIDEO] = 3; +	smu->workload_priority[PP_SMC_POWER_PROFILE_VR] = 4; +	smu->workload_priority[PP_SMC_POWER_PROFILE_COMPUTE] = 5; +	smu->workload_priority[PP_SMC_POWER_PROFILE_CUSTOM] = 6; + +	if (smu->is_apu || +	    !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D)) { +		smu->driver_workload_mask = +			1 << smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; +	} else { +		smu->driver_workload_mask = +			1 << smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D]; +		smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; +	} +	smu->workload_mask = smu->driver_workload_mask | +							smu->user_dpm_profile.user_workload_mask;  	smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;  	smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;  	smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING; @@ -2339,17 +2355,20 @@ static int smu_switch_power_profile(void *handle,  		return -EINVAL;  	if (!en) { -		smu->workload_mask &= ~(1 << smu->workload_prority[type]); +		smu->driver_workload_mask &= ~(1 << smu->workload_priority[type]);  		index = fls(smu->workload_mask);  		index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;  		workload[0] = smu->workload_setting[index];  	} else { -		smu->workload_mask |= (1 << smu->workload_prority[type]); +		smu->driver_workload_mask |= (1 << smu->workload_priority[type]);  		index = fls(smu->workload_mask);  		index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;  		workload[0] = smu->workload_setting[index];  	} +	smu->workload_mask = smu->driver_workload_mask | +						 smu->user_dpm_profile.user_workload_mask; +  	if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&  		smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)  		smu_bump_power_profile_mode(smu, workload, 0); @@ -3040,12 +3059,23 @@ static int smu_set_power_profile_mode(void *handle,  				      uint32_t param_size)  {  	struct smu_context *smu = handle; +	int ret;  	if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled ||  	    !smu->ppt_funcs->set_power_profile_mode)  		return -EOPNOTSUPP; -	return smu_bump_power_profile_mode(smu, param, param_size); +	if (smu->user_dpm_profile.user_workload_mask & +	   (1 << smu->workload_priority[param[param_size]])) +	   return 0; + +	smu->user_dpm_profile.user_workload_mask = +		(1 << smu->workload_priority[param[param_size]]); +	smu->workload_mask = smu->user_dpm_profile.user_workload_mask | +		smu->driver_workload_mask; +	ret = smu_bump_power_profile_mode(smu, param, param_size); + +	return ret;  }  static int smu_get_fan_control_mode(void *handle, u32 *fan_mode) | 
