diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2016-10-14 07:23:34 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-10-25 14:38:53 -0400 |
commit | 5e876c62d85a93381140f5e37bfabfb9a5a3345d (patch) | |
tree | a86d341979fd3131f8f0d5db9a2243da631dee6b /drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |
parent | 8c8e2c30d2da29f67156e2a3f5087b758552f86d (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.c | 80 |
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 | ||
987 | static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) | 987 | static 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 | |||
1051 | force: | ||
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); |