aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r--drivers/gpu/drm/radeon/r100.c140
1 files changed, 116 insertions, 24 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index b076b96f8b6c..a6b2aca36b47 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -67,41 +67,133 @@ MODULE_FIRMWARE(FIRMWARE_R520);
67 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 67 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
68 */ 68 */
69 69
70void r100_get_power_state(struct radeon_device *rdev,
71 enum radeon_pm_action action)
72{
73 int i;
74 rdev->pm.can_upclock = true;
75 rdev->pm.can_downclock = true;
76
77 switch (action) {
78 case PM_ACTION_MINIMUM:
79 rdev->pm.requested_power_state_index = 0;
80 rdev->pm.can_downclock = false;
81 break;
82 case PM_ACTION_DOWNCLOCK:
83 if (rdev->pm.current_power_state_index == 0) {
84 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
85 rdev->pm.can_downclock = false;
86 } else {
87 if (rdev->pm.active_crtc_count > 1) {
88 for (i = 0; i < rdev->pm.num_power_states; i++) {
89 if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
90 continue;
91 else if (i >= rdev->pm.current_power_state_index) {
92 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
93 break;
94 } else {
95 rdev->pm.requested_power_state_index = i;
96 break;
97 }
98 }
99 } else
100 rdev->pm.requested_power_state_index =
101 rdev->pm.current_power_state_index - 1;
102 }
103 break;
104 case PM_ACTION_UPCLOCK:
105 if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) {
106 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
107 rdev->pm.can_upclock = false;
108 } else {
109 if (rdev->pm.active_crtc_count > 1) {
110 for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) {
111 if (rdev->pm.power_state[i].flags & RADEON_PM_SINGLE_DISPLAY_ONLY)
112 continue;
113 else if (i <= rdev->pm.current_power_state_index) {
114 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
115 break;
116 } else {
117 rdev->pm.requested_power_state_index = i;
118 break;
119 }
120 }
121 } else
122 rdev->pm.requested_power_state_index =
123 rdev->pm.current_power_state_index + 1;
124 }
125 break;
126 case PM_ACTION_NONE:
127 default:
128 DRM_ERROR("Requested mode for not defined action\n");
129 return;
130 }
131 /* only one clock mode per power state */
132 rdev->pm.requested_clock_mode_index = 0;
133
134 DRM_INFO("Requested: e: %d m: %d p: %d\n",
135 rdev->pm.power_state[rdev->pm.requested_power_state_index].
136 clock_info[rdev->pm.requested_clock_mode_index].sclk,
137 rdev->pm.power_state[rdev->pm.requested_power_state_index].
138 clock_info[rdev->pm.requested_clock_mode_index].mclk,
139 rdev->pm.power_state[rdev->pm.requested_power_state_index].
140 non_clock_info.pcie_lanes);
141}
142
70void r100_set_power_state(struct radeon_device *rdev) 143void r100_set_power_state(struct radeon_device *rdev)
71{ 144{
72 /* if *_clock_mode are the same, *_power_state are as well */ 145 u32 sclk, mclk;
73 if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode) 146
147 if (rdev->pm.current_power_state_index == rdev->pm.requested_power_state_index)
74 return; 148 return;
75 149
76 DRM_INFO("Setting: e: %d m: %d p: %d\n", 150 if (radeon_gui_idle(rdev)) {
77 rdev->pm.requested_clock_mode->sclk,
78 rdev->pm.requested_clock_mode->mclk,
79 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
80 151
81 /* set pcie lanes */ 152 sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
82 /* TODO */ 153 clock_info[rdev->pm.requested_clock_mode_index].sclk;
154 if (sclk > rdev->clock.default_sclk)
155 sclk = rdev->clock.default_sclk;
83 156
84 /* set voltage */ 157 mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
85 /* TODO */ 158 clock_info[rdev->pm.requested_clock_mode_index].mclk;
159 if (mclk > rdev->clock.default_mclk)
160 mclk = rdev->clock.default_mclk;
161 /* don't change the mclk with multiple crtcs */
162 if (rdev->pm.active_crtc_count > 1)
163 mclk = rdev->clock.default_mclk;
86 164
87 /* set engine clock */ 165 /* set pcie lanes */
88 radeon_sync_with_vblank(rdev); 166 /* TODO */
89 radeon_pm_debug_check_in_vbl(rdev, false); 167
90 radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); 168 /* set voltage */
91 radeon_pm_debug_check_in_vbl(rdev, true); 169 /* TODO */
170
171 /* set engine clock */
172 if (sclk != rdev->pm.current_sclk) {
173 radeon_sync_with_vblank(rdev);
174 radeon_pm_debug_check_in_vbl(rdev, false);
175 radeon_set_engine_clock(rdev, sclk);
176 radeon_pm_debug_check_in_vbl(rdev, true);
177 rdev->pm.current_sclk = sclk;
178 DRM_INFO("Setting: e: %d\n", sclk);
179 }
92 180
93#if 0 181#if 0
94 /* set memory clock */ 182 /* set memory clock */
95 if (rdev->asic->set_memory_clock) { 183 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
96 radeon_sync_with_vblank(rdev); 184 radeon_sync_with_vblank(rdev);
97 radeon_pm_debug_check_in_vbl(rdev, false); 185 radeon_pm_debug_check_in_vbl(rdev, false);
98 radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); 186 radeon_set_memory_clock(rdev, mclk);
99 radeon_pm_debug_check_in_vbl(rdev, true); 187 radeon_pm_debug_check_in_vbl(rdev, true);
100 } 188 rdev->pm.current_mclk = mclk;
189 DRM_INFO("Setting: m: %d\n", mclk);
190 }
101#endif 191#endif
102 192
103 rdev->pm.current_power_state = rdev->pm.requested_power_state; 193 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
104 rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; 194 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
195 } else
196 DRM_INFO("GUI not idle!!!\n");
105} 197}
106 198
107bool r100_gui_idle(struct radeon_device *rdev) 199bool r100_gui_idle(struct radeon_device *rdev)