aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom St Denis <tom.stdenis@amd.com>2016-07-28 09:40:07 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-08-08 11:32:36 -0400
commite95a14a9094a8e6396fba22cbdea9201824d6fd1 (patch)
treefff4770630ed0bf8802b4bc8f4c3d23099ff3537
parent70bb246154229550e5c9095d484b39fb82047907 (diff)
drm/amd/amdgpu: add mutex locking for both DPM and PP based powergating for UVD/VCE
This adds a mutex lock for both DPM/PP around the changes in power gating state so that userspace can poll registers without a race condition on power state. Signed-off-by: Tom St Denis <tom.stdenis@amd.com> Reviewed-by: Rex Zhu <Rex.Zhu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index ff63b88b0ffa..411965f12c01 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1106,54 +1106,46 @@ force:
1106 1106
1107void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) 1107void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
1108{ 1108{
1109 if (adev->pp_enabled) 1109 if (adev->pp_enabled || adev->pm.funcs->powergate_uvd) {
1110 /* enable/disable UVD */
1111 mutex_lock(&adev->pm.mutex);
1110 amdgpu_dpm_powergate_uvd(adev, !enable); 1112 amdgpu_dpm_powergate_uvd(adev, !enable);
1111 else { 1113 mutex_unlock(&adev->pm.mutex);
1112 if (adev->pm.funcs->powergate_uvd) { 1114 } else {
1115 if (enable) {
1113 mutex_lock(&adev->pm.mutex); 1116 mutex_lock(&adev->pm.mutex);
1114 /* enable/disable UVD */ 1117 adev->pm.dpm.uvd_active = true;
1115 amdgpu_dpm_powergate_uvd(adev, !enable); 1118 adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
1116 mutex_unlock(&adev->pm.mutex); 1119 mutex_unlock(&adev->pm.mutex);
1117 } else { 1120 } else {
1118 if (enable) { 1121 mutex_lock(&adev->pm.mutex);
1119 mutex_lock(&adev->pm.mutex); 1122 adev->pm.dpm.uvd_active = false;
1120 adev->pm.dpm.uvd_active = true; 1123 mutex_unlock(&adev->pm.mutex);
1121 adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
1122 mutex_unlock(&adev->pm.mutex);
1123 } else {
1124 mutex_lock(&adev->pm.mutex);
1125 adev->pm.dpm.uvd_active = false;
1126 mutex_unlock(&adev->pm.mutex);
1127 }
1128 amdgpu_pm_compute_clocks(adev);
1129 } 1124 }
1130 1125 amdgpu_pm_compute_clocks(adev);
1131 } 1126 }
1132} 1127}
1133 1128
1134void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) 1129void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
1135{ 1130{
1136 if (adev->pp_enabled) 1131 if (adev->pp_enabled || adev->pm.funcs->powergate_vce) {
1132 /* enable/disable VCE */
1133 mutex_lock(&adev->pm.mutex);
1137 amdgpu_dpm_powergate_vce(adev, !enable); 1134 amdgpu_dpm_powergate_vce(adev, !enable);
1138 else { 1135 mutex_unlock(&adev->pm.mutex);
1139 if (adev->pm.funcs->powergate_vce) { 1136 } else {
1137 if (enable) {
1140 mutex_lock(&adev->pm.mutex); 1138 mutex_lock(&adev->pm.mutex);
1141 amdgpu_dpm_powergate_vce(adev, !enable); 1139 adev->pm.dpm.vce_active = true;
1140 /* XXX select vce level based on ring/task */
1141 adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
1142 mutex_unlock(&adev->pm.mutex); 1142 mutex_unlock(&adev->pm.mutex);
1143 } else { 1143 } else {
1144 if (enable) { 1144 mutex_lock(&adev->pm.mutex);
1145 mutex_lock(&adev->pm.mutex); 1145 adev->pm.dpm.vce_active = false;
1146 adev->pm.dpm.vce_active = true; 1146 mutex_unlock(&adev->pm.mutex);
1147 /* XXX select vce level based on ring/task */
1148 adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL;
1149 mutex_unlock(&adev->pm.mutex);
1150 } else {
1151 mutex_lock(&adev->pm.mutex);
1152 adev->pm.dpm.vce_active = false;
1153 mutex_unlock(&adev->pm.mutex);
1154 }
1155 amdgpu_pm_compute_clocks(adev);
1156 } 1147 }
1148 amdgpu_pm_compute_clocks(adev);
1157 } 1149 }
1158} 1150}
1159 1151