diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-05-27 17:01:41 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-06-02 23:13:30 -0400 |
commit | 92645879d07a48897fe8888c2e37607aa1189cc9 (patch) | |
tree | 6f1ac44afc865f12004040b958640b1dc7a30e56 /drivers/gpu | |
parent | c5e8ce61d64995f4076c6a9b2f8b4b71e0be2e37 (diff) |
drm/radeon/kms/pm: radeon_set_power_state fixes
- wait for vbl for both profile and dynpm
- unify profile and dynpm code paths more
- call pm_misc before of after clocks to make
sure voltage is changed in the proper order.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 75 |
1 files changed, 34 insertions, 41 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index a8d162c6f829..02281269a881 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -151,6 +151,7 @@ static void radeon_sync_with_vblank(struct radeon_device *rdev) | |||
151 | static void radeon_set_power_state(struct radeon_device *rdev) | 151 | static void radeon_set_power_state(struct radeon_device *rdev) |
152 | { | 152 | { |
153 | u32 sclk, mclk; | 153 | u32 sclk, mclk; |
154 | bool misc_after = false; | ||
154 | 155 | ||
155 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && | 156 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && |
156 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) | 157 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) |
@@ -167,55 +168,47 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
167 | if (mclk > rdev->clock.default_mclk) | 168 | if (mclk > rdev->clock.default_mclk) |
168 | mclk = rdev->clock.default_mclk; | 169 | mclk = rdev->clock.default_mclk; |
169 | 170 | ||
170 | /* voltage, pcie lanes, etc.*/ | 171 | /* upvolt before raising clocks, downvolt after lowering clocks */ |
171 | radeon_pm_misc(rdev); | 172 | if (sclk < rdev->pm.current_sclk) |
173 | misc_after = true; | ||
172 | 174 | ||
173 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | 175 | radeon_sync_with_vblank(rdev); |
174 | radeon_sync_with_vblank(rdev); | ||
175 | 176 | ||
177 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | ||
176 | if (!radeon_pm_in_vbl(rdev)) | 178 | if (!radeon_pm_in_vbl(rdev)) |
177 | return; | 179 | return; |
180 | } | ||
178 | 181 | ||
179 | radeon_pm_prepare(rdev); | 182 | radeon_pm_prepare(rdev); |
180 | /* set engine clock */ | ||
181 | if (sclk != rdev->pm.current_sclk) { | ||
182 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
183 | radeon_set_engine_clock(rdev, sclk); | ||
184 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
185 | rdev->pm.current_sclk = sclk; | ||
186 | DRM_DEBUG("Setting: e: %d\n", sclk); | ||
187 | } | ||
188 | 183 | ||
189 | /* set memory clock */ | 184 | if (!misc_after) |
190 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { | 185 | /* voltage, pcie lanes, etc.*/ |
191 | radeon_pm_debug_check_in_vbl(rdev, false); | 186 | radeon_pm_misc(rdev); |
192 | radeon_set_memory_clock(rdev, mclk); | 187 | |
193 | radeon_pm_debug_check_in_vbl(rdev, true); | 188 | /* set engine clock */ |
194 | rdev->pm.current_mclk = mclk; | 189 | if (sclk != rdev->pm.current_sclk) { |
195 | DRM_DEBUG("Setting: m: %d\n", mclk); | 190 | radeon_pm_debug_check_in_vbl(rdev, false); |
196 | } | 191 | radeon_set_engine_clock(rdev, sclk); |
197 | radeon_pm_finish(rdev); | 192 | radeon_pm_debug_check_in_vbl(rdev, true); |
198 | } else { | 193 | rdev->pm.current_sclk = sclk; |
199 | /* set engine clock */ | 194 | DRM_DEBUG("Setting: e: %d\n", sclk); |
200 | if (sclk != rdev->pm.current_sclk) { | 195 | } |
201 | radeon_sync_with_vblank(rdev); | 196 | |
202 | radeon_pm_prepare(rdev); | 197 | /* set memory clock */ |
203 | radeon_set_engine_clock(rdev, sclk); | 198 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { |
204 | radeon_pm_finish(rdev); | 199 | radeon_pm_debug_check_in_vbl(rdev, false); |
205 | rdev->pm.current_sclk = sclk; | 200 | radeon_set_memory_clock(rdev, mclk); |
206 | DRM_DEBUG("Setting: e: %d\n", sclk); | 201 | radeon_pm_debug_check_in_vbl(rdev, true); |
207 | } | 202 | rdev->pm.current_mclk = mclk; |
208 | /* set memory clock */ | 203 | DRM_DEBUG("Setting: m: %d\n", mclk); |
209 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { | ||
210 | radeon_sync_with_vblank(rdev); | ||
211 | radeon_pm_prepare(rdev); | ||
212 | radeon_set_memory_clock(rdev, mclk); | ||
213 | radeon_pm_finish(rdev); | ||
214 | rdev->pm.current_mclk = mclk; | ||
215 | DRM_DEBUG("Setting: m: %d\n", mclk); | ||
216 | } | ||
217 | } | 204 | } |
218 | 205 | ||
206 | if (misc_after) | ||
207 | /* voltage, pcie lanes, etc.*/ | ||
208 | radeon_pm_misc(rdev); | ||
209 | |||
210 | radeon_pm_finish(rdev); | ||
211 | |||
219 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; | 212 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; |
220 | rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; | 213 | rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; |
221 | } else | 214 | } else |