aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
diff options
context:
space:
mode:
authorRex Zhu <Rex.Zhu@amd.com>2016-10-14 07:23:34 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-10-25 14:38:53 -0400
commit5e876c62d85a93381140f5e37bfabfb9a5a3345d (patch)
treea86d341979fd3131f8f0d5db9a2243da631dee6b /drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
parent8c8e2c30d2da29f67156e2a3f5087b758552f86d (diff)
drm/amdgpu: refine set power state logic for dpm.
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c80
1 files changed, 15 insertions, 65 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 4656ad697154..274f3309aec9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -986,10 +986,10 @@ restart_search:
986 986
987static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) 987static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)
988{ 988{
989 int i;
990 struct amdgpu_ps *ps; 989 struct amdgpu_ps *ps;
991 enum amd_pm_state_type dpm_state; 990 enum amd_pm_state_type dpm_state;
992 int ret; 991 int ret;
992 bool equal;
993 993
994 /* if dpm init failed */ 994 /* if dpm init failed */
995 if (!adev->pm.dpm_enabled) 995 if (!adev->pm.dpm_enabled)
@@ -1009,46 +1009,6 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)
1009 else 1009 else
1010 return; 1010 return;
1011 1011
1012 /* no need to reprogram if nothing changed unless we are on BTC+ */
1013 if (adev->pm.dpm.current_ps == adev->pm.dpm.requested_ps) {
1014 /* vce just modifies an existing state so force a change */
1015 if (ps->vce_active != adev->pm.dpm.vce_active)
1016 goto force;
1017 if (adev->flags & AMD_IS_APU) {
1018 /* for APUs if the num crtcs changed but state is the same,
1019 * all we need to do is update the display configuration.
1020 */
1021 if (adev->pm.dpm.new_active_crtcs != adev->pm.dpm.current_active_crtcs) {
1022 /* update display watermarks based on new power state */
1023 amdgpu_display_bandwidth_update(adev);
1024 /* update displays */
1025 amdgpu_dpm_display_configuration_changed(adev);
1026 adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
1027 adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
1028 }
1029 return;
1030 } else {
1031 /* for BTC+ if the num crtcs hasn't changed and state is the same,
1032 * nothing to do, if the num crtcs is > 1 and state is the same,
1033 * update display configuration.
1034 */
1035 if (adev->pm.dpm.new_active_crtcs ==
1036 adev->pm.dpm.current_active_crtcs) {
1037 return;
1038 } else if ((adev->pm.dpm.current_active_crtc_count > 1) &&
1039 (adev->pm.dpm.new_active_crtc_count > 1)) {
1040 /* update display watermarks based on new power state */
1041 amdgpu_display_bandwidth_update(adev);
1042 /* update displays */
1043 amdgpu_dpm_display_configuration_changed(adev);
1044 adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
1045 adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
1046 return;
1047 }
1048 }
1049 }
1050
1051force:
1052 if (amdgpu_dpm == 1) { 1012 if (amdgpu_dpm == 1) {
1053 printk("switching from power state:\n"); 1013 printk("switching from power state:\n");
1054 amdgpu_dpm_print_power_state(adev, adev->pm.dpm.current_ps); 1014 amdgpu_dpm_print_power_state(adev, adev->pm.dpm.current_ps);
@@ -1059,31 +1019,21 @@ force:
1059 /* update whether vce is active */ 1019 /* update whether vce is active */
1060 ps->vce_active = adev->pm.dpm.vce_active; 1020 ps->vce_active = adev->pm.dpm.vce_active;
1061 1021
1022 amdgpu_dpm_display_configuration_changed(adev);
1023
1062 ret = amdgpu_dpm_pre_set_power_state(adev); 1024 ret = amdgpu_dpm_pre_set_power_state(adev);
1063 if (ret) 1025 if (ret)
1064 return; 1026 return;
1065 1027
1066 /* update display watermarks based on new power state */ 1028 if ((0 != amgdpu_dpm_check_state_equal(adev, adev->pm.dpm.current_ps, adev->pm.dpm.requested_ps, &equal)))
1067 amdgpu_display_bandwidth_update(adev); 1029 equal = false;
1068 1030
1069 /* wait for the rings to drain */ 1031 if (equal)
1070 for (i = 0; i < AMDGPU_MAX_RINGS; i++) { 1032 return;
1071 struct amdgpu_ring *ring = adev->rings[i];
1072 if (ring && ring->ready)
1073 amdgpu_fence_wait_empty(ring);
1074 }
1075 1033
1076 /* program the new power state */
1077 amdgpu_dpm_set_power_state(adev); 1034 amdgpu_dpm_set_power_state(adev);
1078
1079 /* update current power state */
1080 adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps;
1081
1082 amdgpu_dpm_post_set_power_state(adev); 1035 amdgpu_dpm_post_set_power_state(adev);
1083 1036
1084 /* update displays */
1085 amdgpu_dpm_display_configuration_changed(adev);
1086
1087 adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs; 1037 adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
1088 adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count; 1038 adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
1089 1039
@@ -1276,20 +1226,20 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
1276 struct drm_device *ddev = adev->ddev; 1226 struct drm_device *ddev = adev->ddev;
1277 struct drm_crtc *crtc; 1227 struct drm_crtc *crtc;
1278 struct amdgpu_crtc *amdgpu_crtc; 1228 struct amdgpu_crtc *amdgpu_crtc;
1229 int i = 0;
1279 1230
1280 if (!adev->pm.dpm_enabled) 1231 if (!adev->pm.dpm_enabled)
1281 return; 1232 return;
1282 1233
1283 if (adev->pp_enabled) { 1234 amdgpu_display_bandwidth_update(adev);
1284 int i = 0;
1285 1235
1286 amdgpu_display_bandwidth_update(adev); 1236 for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
1287 for (i = 0; i < AMDGPU_MAX_RINGS; i++) { 1237 struct amdgpu_ring *ring = adev->rings[i];
1288 struct amdgpu_ring *ring = adev->rings[i]; 1238 if (ring && ring->ready)
1289 if (ring && ring->ready) 1239 amdgpu_fence_wait_empty(ring);
1290 amdgpu_fence_wait_empty(ring); 1240 }
1291 }
1292 1241
1242 if (adev->pp_enabled) {
1293 amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL); 1243 amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL);
1294 } else { 1244 } else {
1295 mutex_lock(&adev->pm.mutex); 1245 mutex_lock(&adev->pm.mutex);