Commit a71a4f50 authored by Alex Jivin's avatar Alex Jivin Committed by Alex Deucher
Browse files

drm/amdgpu: SI support for UVD and VCE power managment



Port functionality from the Radeon driver to support
UVD and VCE power management.

Signed-off-by: default avatarAlex Jivin <alex.jivin@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fb40bceb
Loading
Loading
Loading
Loading
+49 −18
Original line number Diff line number Diff line
@@ -3558,6 +3558,20 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
{
	int ret = 0;

	if (adev->family == AMDGPU_FAMILY_SI) {
		if (enable) {
			mutex_lock(&adev->pm.mutex);
			adev->pm.dpm.uvd_active = true;
			adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
			mutex_unlock(&adev->pm.mutex);
		} else {
			mutex_lock(&adev->pm.mutex);
			adev->pm.dpm.uvd_active = false;
			mutex_unlock(&adev->pm.mutex);
		}

		amdgpu_pm_compute_clocks(adev);
	} else {
		ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
		if (ret)
			DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
@@ -3575,16 +3589,33 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
								       true);
		}
	}
}

void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
{
	int ret = 0;

	if (adev->family == AMDGPU_FAMILY_SI) {
		if (enable) {
			mutex_lock(&adev->pm.mutex);
			adev->pm.dpm.vce_active = true;
			/* XXX select vce level based on ring/task */
			adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL;
			mutex_unlock(&adev->pm.mutex);
		} else {
			mutex_lock(&adev->pm.mutex);
			adev->pm.dpm.vce_active = false;
			mutex_unlock(&adev->pm.mutex);
		}

		amdgpu_pm_compute_clocks(adev);
	} else {
		ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
		if (ret)
			DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
				  enable ? "enable" : "disable", ret);
	}
}

void amdgpu_pm_print_power_states(struct amdgpu_device *adev)
{
+19 −0
Original line number Diff line number Diff line
@@ -6953,6 +6953,24 @@ static int si_power_control_set_level(struct amdgpu_device *adev)
	return 0;
}

static void si_set_vce_clock(struct amdgpu_device *adev,
			     struct amdgpu_ps *new_rps,
			     struct amdgpu_ps *old_rps)
{
	if ((old_rps->evclk != new_rps->evclk) ||
	    (old_rps->ecclk != new_rps->ecclk)) {
		/* Turn the clocks on when encoding, off otherwise */
		if (new_rps->evclk || new_rps->ecclk) {
			/* Place holder for future VCE1.0 porting to amdgpu
			vce_v1_0_enable_mgcg(adev, false, false);*/
		} else {
			/* Place holder for future VCE1.0 porting to amdgpu
			vce_v1_0_enable_mgcg(adev, true, false);
			amdgpu_asic_set_vce_clocks(adev, new_rps->evclk, new_rps->ecclk);*/
		}
	}
}

static int si_dpm_set_power_state(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -7029,6 +7047,7 @@ static int si_dpm_set_power_state(void *handle)
		return ret;
	}
	ni_set_uvd_clock_after_set_eng_clock(adev, new_ps, old_ps);
	si_set_vce_clock(adev, new_ps, old_ps);
	if (eg_pi->pcie_performance_request)
		si_notify_link_speed_change_after_state_change(adev, new_ps, old_ps);
	ret = si_set_power_state_conditionally_enable_ulv(adev, new_ps);