diff options
| -rw-r--r-- | drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 61 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/pm/amdgpu_pm.c | 50 | 
2 files changed, 59 insertions, 52 deletions
| diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 68d2e80a673b..728b6e10f302 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -692,16 +692,25 @@ void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,  		amdgpu_dpm_compute_clocks(adev);  } -enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev) +static enum amd_dpm_forced_level amdgpu_dpm_get_performance_level_locked(struct amdgpu_device *adev)  {  	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;  	enum amd_dpm_forced_level level; -	mutex_lock(&adev->pm.mutex);  	if (pp_funcs->get_performance_level)  		level = pp_funcs->get_performance_level(adev->powerplay.pp_handle);  	else  		level = adev->pm.dpm.forced_level; + +	return level; +} + +enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev) +{ +	enum amd_dpm_forced_level level; + +	mutex_lock(&adev->pm.mutex); +	level = amdgpu_dpm_get_performance_level_locked(adev);  	mutex_unlock(&adev->pm.mutex);  	return level; @@ -711,6 +720,11 @@ int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,  				       enum amd_dpm_forced_level level)  {  	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; +	enum amd_dpm_forced_level current_level; +	uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | +					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | +					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK | +					AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;  	int ret = 0;  	if (!pp_funcs->force_performance_level) @@ -723,6 +737,49 @@ int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,  		goto out;  	} +	current_level = amdgpu_dpm_get_performance_level_locked(adev); +	if (current_level == level) { +		ret = 0; +		goto out; +	} + +	if (adev->asic_type == CHIP_RAVEN) { +		if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) { +			if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL && +			    level == AMD_DPM_FORCED_LEVEL_MANUAL) +				amdgpu_gfx_off_ctrl(adev, false); +			else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL && +				 level != AMD_DPM_FORCED_LEVEL_MANUAL) +				amdgpu_gfx_off_ctrl(adev, true); +		} +	} + +	if (!(current_level & profile_mode_mask) && +	    (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)) { +		ret = -EINVAL; +		goto out; +	} + +	if (!(current_level & profile_mode_mask) && +	      (level & profile_mode_mask)) { +		/* enter UMD Pstate */ +		amdgpu_device_ip_set_powergating_state(adev, +						       AMD_IP_BLOCK_TYPE_GFX, +						       AMD_PG_STATE_UNGATE); +		amdgpu_device_ip_set_clockgating_state(adev, +						       AMD_IP_BLOCK_TYPE_GFX, +						       AMD_CG_STATE_UNGATE); +	} else if ((current_level & profile_mode_mask) && +		    !(level & profile_mode_mask)) { +		/* exit UMD Pstate */ +		amdgpu_device_ip_set_clockgating_state(adev, +						       AMD_IP_BLOCK_TYPE_GFX, +						       AMD_CG_STATE_GATE); +		amdgpu_device_ip_set_powergating_state(adev, +						       AMD_IP_BLOCK_TYPE_GFX, +						       AMD_PG_STATE_GATE); +	} +  	if (pp_funcs->force_performance_level(adev->powerplay.pp_handle,  					      level))  		ret = -EINVAL; diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index d3eab245e0fe..d2823aaeca09 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -299,11 +299,6 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = drm_to_adev(ddev);  	enum amd_dpm_forced_level level; -	enum amd_dpm_forced_level current_level; -	uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | -					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | -					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK | -					AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;  	int ret = 0;  	if (amdgpu_in_reset(adev)) @@ -341,51 +336,6 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev,  		return ret;  	} -	current_level = amdgpu_dpm_get_performance_level(adev); -	if (current_level == level) { -		pm_runtime_mark_last_busy(ddev->dev); -		pm_runtime_put_autosuspend(ddev->dev); -		return count; -	} - -	if (adev->asic_type == CHIP_RAVEN) { -		if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) { -			if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL && level == AMD_DPM_FORCED_LEVEL_MANUAL) -				amdgpu_gfx_off_ctrl(adev, false); -			else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL && level != AMD_DPM_FORCED_LEVEL_MANUAL) -				amdgpu_gfx_off_ctrl(adev, true); -		} -	} - -	/* profile_exit setting is valid only when current mode is in profile mode */ -	if (!(current_level & profile_mode_mask) && -	    (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)) { -		pr_err("Currently not in any profile mode!\n"); -		pm_runtime_mark_last_busy(ddev->dev); -		pm_runtime_put_autosuspend(ddev->dev); -		return -EINVAL; -	} - -	if (!(current_level & profile_mode_mask) && -	      (level & profile_mode_mask)) { -		/* enter UMD Pstate */ -		amdgpu_device_ip_set_powergating_state(adev, -						       AMD_IP_BLOCK_TYPE_GFX, -						       AMD_PG_STATE_UNGATE); -		amdgpu_device_ip_set_clockgating_state(adev, -						       AMD_IP_BLOCK_TYPE_GFX, -						       AMD_CG_STATE_UNGATE); -	} else if ((current_level & profile_mode_mask) && -		    !(level & profile_mode_mask)) { -		/* exit UMD Pstate */ -		amdgpu_device_ip_set_clockgating_state(adev, -						       AMD_IP_BLOCK_TYPE_GFX, -						       AMD_CG_STATE_GATE); -		amdgpu_device_ip_set_powergating_state(adev, -						       AMD_IP_BLOCK_TYPE_GFX, -						       AMD_PG_STATE_GATE); -	} -  	if (amdgpu_dpm_force_performance_level(adev, level)) {  		pm_runtime_mark_last_busy(ddev->dev);  		pm_runtime_put_autosuspend(ddev->dev); | 
