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 | |
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')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/trinity_dpm.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/trinity_dpm.h | 6 |
4 files changed, 61 insertions, 22 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index b0d055a20d5d..c99fae7b6f7a 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -2091,7 +2091,9 @@ static struct radeon_asic trinity_asic = { | |||
2091 | .setup_asic = &trinity_dpm_setup_asic, | 2091 | .setup_asic = &trinity_dpm_setup_asic, |
2092 | .enable = &trinity_dpm_enable, | 2092 | .enable = &trinity_dpm_enable, |
2093 | .disable = &trinity_dpm_disable, | 2093 | .disable = &trinity_dpm_disable, |
2094 | .pre_set_power_state = &trinity_dpm_pre_set_power_state, | ||
2094 | .set_power_state = &trinity_dpm_set_power_state, | 2095 | .set_power_state = &trinity_dpm_set_power_state, |
2096 | .post_set_power_state = &trinity_dpm_post_set_power_state, | ||
2095 | .display_configuration_changed = &trinity_dpm_display_configuration_changed, | 2097 | .display_configuration_changed = &trinity_dpm_display_configuration_changed, |
2096 | .fini = &trinity_dpm_fini, | 2098 | .fini = &trinity_dpm_fini, |
2097 | .get_sclk = &trinity_dpm_get_sclk, | 2099 | .get_sclk = &trinity_dpm_get_sclk, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 57fd4c021727..4870ef97b006 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -604,7 +604,9 @@ void ni_dpm_print_power_state(struct radeon_device *rdev, | |||
604 | int trinity_dpm_init(struct radeon_device *rdev); | 604 | int trinity_dpm_init(struct radeon_device *rdev); |
605 | int trinity_dpm_enable(struct radeon_device *rdev); | 605 | int trinity_dpm_enable(struct radeon_device *rdev); |
606 | void trinity_dpm_disable(struct radeon_device *rdev); | 606 | void trinity_dpm_disable(struct radeon_device *rdev); |
607 | int trinity_dpm_pre_set_power_state(struct radeon_device *rdev); | ||
607 | int trinity_dpm_set_power_state(struct radeon_device *rdev); | 608 | int trinity_dpm_set_power_state(struct radeon_device *rdev); |
609 | void trinity_dpm_post_set_power_state(struct radeon_device *rdev); | ||
608 | void trinity_dpm_setup_asic(struct radeon_device *rdev); | 610 | void trinity_dpm_setup_asic(struct radeon_device *rdev); |
609 | void trinity_dpm_display_configuration_changed(struct radeon_device *rdev); | 611 | void trinity_dpm_display_configuration_changed(struct radeon_device *rdev); |
610 | void trinity_dpm_fini(struct radeon_device *rdev); | 612 | void trinity_dpm_fini(struct radeon_device *rdev); |
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; |
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.h b/drivers/gpu/drm/radeon/trinity_dpm.h index c663aed6aeea..c621b843aab5 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.h +++ b/drivers/gpu/drm/radeon/trinity_dpm.h | |||
@@ -97,7 +97,6 @@ struct trinity_power_info { | |||
97 | u32 thermal_auto_throttling; | 97 | u32 thermal_auto_throttling; |
98 | struct trinity_sys_info sys_info; | 98 | struct trinity_sys_info sys_info; |
99 | struct trinity_pl boot_pl; | 99 | struct trinity_pl boot_pl; |
100 | struct trinity_ps current_ps; | ||
101 | u32 min_sclk_did; | 100 | u32 min_sclk_did; |
102 | bool enable_nbps_policy; | 101 | bool enable_nbps_policy; |
103 | bool voltage_drop_in_dce; | 102 | bool voltage_drop_in_dce; |
@@ -110,7 +109,10 @@ struct trinity_power_info { | |||
110 | bool enable_dpm; | 109 | bool enable_dpm; |
111 | bool enable_sclk_ds; | 110 | bool enable_sclk_ds; |
112 | bool uvd_dpm; | 111 | bool uvd_dpm; |
113 | struct trinity_ps hw_ps; | 112 | struct radeon_ps current_rps; |
113 | struct trinity_ps current_ps; | ||
114 | struct radeon_ps requested_rps; | ||
115 | struct trinity_ps requested_ps; | ||
114 | }; | 116 | }; |
115 | 117 | ||
116 | #define TRINITY_AT_DFLT 30 | 118 | #define TRINITY_AT_DFLT 30 |