diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/kv_dpm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/kv_dpm.c | 66 | 
1 files changed, 44 insertions, 22 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index 7a1e77c93bf1..cb79a93c2eb7 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -65,8 +65,6 @@ static int kv_set_thermal_temperature_range(struct amdgpu_device *adev,  					    int min_temp, int max_temp);  static int kv_init_fps_limits(struct amdgpu_device *adev); -static void kv_dpm_powergate_uvd(void *handle, bool gate); -static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate);  static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate);  static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate); @@ -1354,8 +1352,6 @@ static int kv_dpm_enable(struct amdgpu_device *adev)  		return ret;  	} -	kv_update_current_ps(adev, adev->pm.dpm.boot_ps); -  	if (adev->irq.installed &&  	    amdgpu_is_internal_thermal_sensor(adev->pm.int_thermal_type)) {  		ret = kv_set_thermal_temperature_range(adev, KV_TEMP_RANGE_MIN, KV_TEMP_RANGE_MAX); @@ -1374,6 +1370,8 @@ static int kv_dpm_enable(struct amdgpu_device *adev)  static void kv_dpm_disable(struct amdgpu_device *adev)  { +	struct kv_power_info *pi = kv_get_pi(adev); +  	amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,  		       AMDGPU_THERMAL_IRQ_LOW_TO_HIGH);  	amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq, @@ -1387,8 +1385,10 @@ static void kv_dpm_disable(struct amdgpu_device *adev)  	/* powerup blocks */  	kv_dpm_powergate_acp(adev, false);  	kv_dpm_powergate_samu(adev, false); -	kv_dpm_powergate_vce(adev, false); -	kv_dpm_powergate_uvd(adev, false); +	if (pi->caps_vce_pg) /* power on the VCE block */ +		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); +	if (pi->caps_uvd_pg) /* power on the UVD block */ +		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_UVDPowerON);  	kv_enable_smc_cac(adev, false);  	kv_enable_didt(adev, false); @@ -1551,7 +1551,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,  	int ret;  	if (amdgpu_new_state->evclk > 0 && amdgpu_current_state->evclk == 0) { -		kv_dpm_powergate_vce(adev, false);  		if (pi->caps_stable_p_state)  			pi->vce_boot_level = table->count - 1;  		else @@ -1573,7 +1572,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,  		kv_enable_vce_dpm(adev, true);  	} else if (amdgpu_new_state->evclk == 0 && amdgpu_current_state->evclk > 0) {  		kv_enable_vce_dpm(adev, false); -		kv_dpm_powergate_vce(adev, true);  	}  	return 0; @@ -1702,24 +1700,32 @@ static void kv_dpm_powergate_uvd(void *handle, bool gate)  	}  } -static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate) +static void kv_dpm_powergate_vce(void *handle, bool gate)  { +	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	struct kv_power_info *pi = kv_get_pi(adev); - -	if (pi->vce_power_gated == gate) -		return; +	int ret;  	pi->vce_power_gated = gate; -	if (!pi->caps_vce_pg) -		return; - -	if (gate) -		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF); -	else -		amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); +	if (gate) { +		/* stop the VCE block */ +		ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, +							     AMD_PG_STATE_GATE); +		kv_enable_vce_dpm(adev, false); +		if (pi->caps_vce_pg) /* power off the VCE block */ +			amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF); +	} else { +		if (pi->caps_vce_pg) /* power on the VCE block */ +			amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON); +		kv_enable_vce_dpm(adev, true); +		/* re-init the VCE block */ +		ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, +							     AMD_PG_STATE_UNGATE); +	}  } +  static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate)  {  	struct kv_power_info *pi = kv_get_pi(adev); @@ -1921,7 +1927,7 @@ static int kv_dpm_set_power_state(void *handle)  	int ret;  	if (pi->bapm_enable) { -		ret = amdgpu_kv_smc_bapm_enable(adev, adev->pm.dpm.ac_power); +		ret = amdgpu_kv_smc_bapm_enable(adev, adev->pm.ac_power);  		if (ret) {  			DRM_ERROR("amdgpu_kv_smc_bapm_enable failed\n");  			return ret; @@ -3061,7 +3067,7 @@ static int kv_dpm_hw_init(void *handle)  	else  		adev->pm.dpm_enabled = true;  	mutex_unlock(&adev->pm.mutex); - +	amdgpu_pm_compute_clocks(adev);  	return ret;  } @@ -3306,6 +3312,22 @@ static int kv_dpm_read_sensor(void *handle, int idx,  	}  } +static int kv_set_powergating_by_smu(void *handle, +				uint32_t block_type, bool gate) +{ +	switch (block_type) { +	case AMD_IP_BLOCK_TYPE_UVD: +		kv_dpm_powergate_uvd(handle, gate); +		break; +	case AMD_IP_BLOCK_TYPE_VCE: +		kv_dpm_powergate_vce(handle, gate); +		break; +	default: +		break; +	} +	return 0; +} +  static const struct amd_ip_funcs kv_dpm_ip_funcs = {  	.name = "kv_dpm",  	.early_init = kv_dpm_early_init, @@ -3342,7 +3364,7 @@ static const struct amd_pm_funcs kv_dpm_funcs = {  	.print_power_state = &kv_dpm_print_power_state,  	.debugfs_print_current_performance_level = &kv_dpm_debugfs_print_current_performance_level,  	.force_performance_level = &kv_dpm_force_performance_level, -	.powergate_uvd = &kv_dpm_powergate_uvd, +	.set_powergating_by_smu = kv_set_powergating_by_smu,  	.enable_bapm = &kv_dpm_enable_bapm,  	.get_vce_clock_state = amdgpu_get_vce_clock_state,  	.check_state_equal = kv_check_state_equal, | 
