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

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
...@@ -3558,21 +3558,36 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) ...@@ -3558,21 +3558,36 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
{ {
int ret = 0; int ret = 0;
ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); if (adev->family == AMDGPU_FAMILY_SI) {
if (ret) if (enable) {
DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", mutex_lock(&adev->pm.mutex);
enable ? "enable" : "disable", ret); adev->pm.dpm.uvd_active = true;
adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
/* enable/disable Low Memory PState for UVD (4k videos) */ mutex_unlock(&adev->pm.mutex);
if (adev->asic_type == CHIP_STONEY && } else {
adev->uvd.decode_image_width >= WIDTH_4K) { mutex_lock(&adev->pm.mutex);
struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; adev->pm.dpm.uvd_active = false;
mutex_unlock(&adev->pm.mutex);
}
if (hwmgr && hwmgr->hwmgr_func && amdgpu_pm_compute_clocks(adev);
hwmgr->hwmgr_func->update_nbdpm_pstate) } else {
hwmgr->hwmgr_func->update_nbdpm_pstate(hwmgr, ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
!enable, if (ret)
true); DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
enable ? "enable" : "disable", ret);
/* enable/disable Low Memory PState for UVD (4k videos) */
if (adev->asic_type == CHIP_STONEY &&
adev->uvd.decode_image_width >= WIDTH_4K) {
struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
if (hwmgr && hwmgr->hwmgr_func &&
hwmgr->hwmgr_func->update_nbdpm_pstate)
hwmgr->hwmgr_func->update_nbdpm_pstate(hwmgr,
!enable,
true);
}
} }
} }
...@@ -3580,10 +3595,26 @@ void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) ...@@ -3580,10 +3595,26 @@ void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
{ {
int ret = 0; int ret = 0;
ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); if (adev->family == AMDGPU_FAMILY_SI) {
if (ret) if (enable) {
DRM_ERROR("Dpm %s vce failed, ret = %d. \n", mutex_lock(&adev->pm.mutex);
enable ? "enable" : "disable", ret); 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) void amdgpu_pm_print_power_states(struct amdgpu_device *adev)
......
...@@ -6953,6 +6953,24 @@ static int si_power_control_set_level(struct amdgpu_device *adev) ...@@ -6953,6 +6953,24 @@ static int si_power_control_set_level(struct amdgpu_device *adev)
return 0; 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) static int si_dpm_set_power_state(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
...@@ -7029,6 +7047,7 @@ static int si_dpm_set_power_state(void *handle) ...@@ -7029,6 +7047,7 @@ static int si_dpm_set_power_state(void *handle)
return ret; return ret;
} }
ni_set_uvd_clock_after_set_eng_clock(adev, new_ps, old_ps); 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) if (eg_pi->pcie_performance_request)
si_notify_link_speed_change_after_state_change(adev, new_ps, old_ps); si_notify_link_speed_change_after_state_change(adev, new_ps, old_ps);
ret = si_set_power_state_conditionally_enable_ulv(adev, new_ps); ret = si_set_power_state_conditionally_enable_ulv(adev, new_ps);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment