diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-16 13:53:40 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-06-27 19:16:18 -0400 |
commit | a284c48ae7217fc362b851c68f74d7b414061704 (patch) | |
tree | d26e64601b9fbd29ed7e144c957b3e97b8404813 /drivers/gpu/drm/radeon/trinity_dpm.c | |
parent | 422a56bc8a5aaa6d48b244a1ba0484ef4d62a7ac (diff) |
drm/radeon/dpm: add pre/post_set_power_state callback (TN)
This properly implemented dynamic state adjustment by
using a working copy of the requested and current
power states.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/trinity_dpm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/trinity_dpm.c | 73 |
1 files changed, 53 insertions, 20 deletions
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 103efbc5a99b..1699e93805b4 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c | |||
@@ -832,15 +832,6 @@ static void trinity_unforce_levels(struct radeon_device *rdev) | |||
832 | trinity_dpm_no_forced_level(rdev); | 832 | trinity_dpm_no_forced_level(rdev); |
833 | } | 833 | } |
834 | 834 | ||
835 | static void trinity_update_current_power_levels(struct radeon_device *rdev, | ||
836 | struct radeon_ps *rps) | ||
837 | { | ||
838 | struct trinity_ps *new_ps = trinity_get_ps(rps); | ||
839 | struct trinity_power_info *pi = trinity_get_pi(rdev); | ||
840 | |||
841 | pi->current_ps = *new_ps; | ||
842 | } | ||
843 | |||
844 | static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev, | 835 | static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev, |
845 | struct radeon_ps *new_rps, | 836 | struct radeon_ps *new_rps, |
846 | struct radeon_ps *old_rps) | 837 | struct radeon_ps *old_rps) |
@@ -1046,6 +1037,28 @@ static int trinity_set_thermal_temperature_range(struct radeon_device *rdev, | |||
1046 | return 0; | 1037 | return 0; |
1047 | } | 1038 | } |
1048 | 1039 | ||
1040 | static void trinity_update_current_ps(struct radeon_device *rdev, | ||
1041 | struct radeon_ps *rps) | ||
1042 | { | ||
1043 | struct trinity_ps *new_ps = trinity_get_ps(rps); | ||
1044 | struct trinity_power_info *pi = trinity_get_pi(rdev); | ||
1045 | |||
1046 | pi->current_rps = *rps; | ||
1047 | pi->current_ps = *new_ps; | ||
1048 | pi->current_rps.ps_priv = &pi->current_ps; | ||
1049 | } | ||
1050 | |||
1051 | static void trinity_update_requested_ps(struct radeon_device *rdev, | ||
1052 | struct radeon_ps *rps) | ||
1053 | { | ||
1054 | struct trinity_ps *new_ps = trinity_get_ps(rps); | ||
1055 | struct trinity_power_info *pi = trinity_get_pi(rdev); | ||
1056 | |||
1057 | pi->requested_rps = *rps; | ||
1058 | pi->requested_ps = *new_ps; | ||
1059 | pi->requested_rps.ps_priv = &pi->requested_ps; | ||
1060 | } | ||
1061 | |||
1049 | int trinity_dpm_enable(struct radeon_device *rdev) | 1062 | int trinity_dpm_enable(struct radeon_device *rdev) |
1050 | { | 1063 | { |
1051 | struct trinity_power_info *pi = trinity_get_pi(rdev); | 1064 | struct trinity_power_info *pi = trinity_get_pi(rdev); |
@@ -1077,6 +1090,8 @@ int trinity_dpm_enable(struct radeon_device *rdev) | |||
1077 | radeon_irq_set(rdev); | 1090 | radeon_irq_set(rdev); |
1078 | } | 1091 | } |
1079 | 1092 | ||
1093 | trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps); | ||
1094 | |||
1080 | return 0; | 1095 | return 0; |
1081 | } | 1096 | } |
1082 | 1097 | ||
@@ -1099,6 +1114,8 @@ void trinity_dpm_disable(struct radeon_device *rdev) | |||
1099 | rdev->irq.dpm_thermal = false; | 1114 | rdev->irq.dpm_thermal = false; |
1100 | radeon_irq_set(rdev); | 1115 | radeon_irq_set(rdev); |
1101 | } | 1116 | } |
1117 | |||
1118 | trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps); | ||
1102 | } | 1119 | } |
1103 | 1120 | ||
1104 | static void trinity_get_min_sclk_divider(struct radeon_device *rdev) | 1121 | static void trinity_get_min_sclk_divider(struct radeon_device *rdev) |
@@ -1127,14 +1144,26 @@ static void trinity_setup_nbp_sim(struct radeon_device *rdev, | |||
1127 | } | 1144 | } |
1128 | } | 1145 | } |
1129 | 1146 | ||
1130 | int trinity_dpm_set_power_state(struct radeon_device *rdev) | 1147 | int trinity_dpm_pre_set_power_state(struct radeon_device *rdev) |
1131 | { | 1148 | { |
1132 | struct trinity_power_info *pi = trinity_get_pi(rdev); | 1149 | struct trinity_power_info *pi = trinity_get_pi(rdev); |
1133 | struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps; | 1150 | struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps; |
1134 | struct radeon_ps *old_ps = rdev->pm.dpm.current_ps; | 1151 | struct radeon_ps *new_ps = &requested_ps; |
1152 | |||
1153 | trinity_update_requested_ps(rdev, new_ps); | ||
1135 | 1154 | ||
1136 | trinity_apply_state_adjust_rules(rdev, new_ps, old_ps); | 1155 | trinity_apply_state_adjust_rules(rdev, |
1137 | trinity_update_current_power_levels(rdev, new_ps); | 1156 | &pi->requested_rps, |
1157 | &pi->current_rps); | ||
1158 | |||
1159 | return 0; | ||
1160 | } | ||
1161 | |||
1162 | int trinity_dpm_set_power_state(struct radeon_device *rdev) | ||
1163 | { | ||
1164 | struct trinity_power_info *pi = trinity_get_pi(rdev); | ||
1165 | struct radeon_ps *new_ps = &pi->requested_rps; | ||
1166 | struct radeon_ps *old_ps = &pi->current_rps; | ||
1138 | 1167 | ||
1139 | trinity_acquire_mutex(rdev); | 1168 | trinity_acquire_mutex(rdev); |
1140 | if (pi->enable_dpm) { | 1169 | if (pi->enable_dpm) { |
@@ -1153,6 +1182,14 @@ int trinity_dpm_set_power_state(struct radeon_device *rdev) | |||
1153 | return 0; | 1182 | return 0; |
1154 | } | 1183 | } |
1155 | 1184 | ||
1185 | void trinity_dpm_post_set_power_state(struct radeon_device *rdev) | ||
1186 | { | ||
1187 | struct trinity_power_info *pi = trinity_get_pi(rdev); | ||
1188 | struct radeon_ps *new_ps = &pi->requested_rps; | ||
1189 | |||
1190 | trinity_update_current_ps(rdev, new_ps); | ||
1191 | } | ||
1192 | |||
1156 | void trinity_dpm_setup_asic(struct radeon_device *rdev) | 1193 | void trinity_dpm_setup_asic(struct radeon_device *rdev) |
1157 | { | 1194 | { |
1158 | trinity_acquire_mutex(rdev); | 1195 | trinity_acquire_mutex(rdev); |
@@ -1390,11 +1427,6 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, | |||
1390 | bool force_high; | 1427 | bool force_high; |
1391 | u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count; | 1428 | u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count; |
1392 | 1429 | ||
1393 | /* point to the hw copy since this function will modify the ps */ | ||
1394 | pi->hw_ps = *ps; | ||
1395 | rdev->pm.dpm.hw_ps.ps_priv = &pi->hw_ps; | ||
1396 | ps = &pi->hw_ps; | ||
1397 | |||
1398 | if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL) | 1430 | if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL) |
1399 | return trinity_patch_thermal_state(rdev, ps, current_ps); | 1431 | return trinity_patch_thermal_state(rdev, ps, current_ps); |
1400 | 1432 | ||
@@ -1833,7 +1865,8 @@ void trinity_dpm_fini(struct radeon_device *rdev) | |||
1833 | 1865 | ||
1834 | u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low) | 1866 | u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low) |
1835 | { | 1867 | { |
1836 | struct trinity_ps *requested_state = trinity_get_ps(rdev->pm.dpm.requested_ps); | 1868 | struct trinity_power_info *pi = trinity_get_pi(rdev); |
1869 | struct trinity_ps *requested_state = trinity_get_ps(&pi->requested_rps); | ||
1837 | 1870 | ||
1838 | if (low) | 1871 | if (low) |
1839 | return requested_state->levels[0].sclk; | 1872 | return requested_state->levels[0].sclk; |