diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2014-11-20 21:48:57 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-12-03 14:26:44 -0500 |
commit | 6d3759fac636028849f3bbec80c4b77e9bfdb1d2 (patch) | |
tree | 616375c5fdc12324a8fab230ccdeafc495fa7525 | |
parent | d5b75dc01fa9c699aee5f82f5dbe508da438ff94 (diff) |
drm/radeon: Re-show the cursor after a modeset
Setting a mode seems to clear the cursor registers, so we need to
re-program them to make sure the cursor is visible.
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cursor.c | 89 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 1 |
4 files changed, 68 insertions, 24 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 30d242b25078..d59ec491dbb9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -2039,6 +2039,7 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
2039 | atombios_crtc_set_base(crtc, x, y, old_fb); | 2039 | atombios_crtc_set_base(crtc, x, y, old_fb); |
2040 | atombios_overscan_setup(crtc, mode, adjusted_mode); | 2040 | atombios_overscan_setup(crtc, mode, adjusted_mode); |
2041 | atombios_scaler_setup(crtc); | 2041 | atombios_scaler_setup(crtc); |
2042 | radeon_cursor_reset(crtc); | ||
2042 | /* update the hw version fpr dpm */ | 2043 | /* update the hw version fpr dpm */ |
2043 | radeon_crtc->hw_mode = *adjusted_mode; | 2044 | radeon_crtc->hw_mode = *adjusted_mode; |
2044 | 2045 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 85f38ee11888..44dcbde6044c 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -227,11 +227,25 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, | |||
227 | return ret; | 227 | return ret; |
228 | } | 228 | } |
229 | 229 | ||
230 | static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | 230 | static int radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, |
231 | uint64_t gpu_addr, int hot_x, int hot_y) | 231 | int hot_x, int hot_y) |
232 | { | 232 | { |
233 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 233 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
234 | struct radeon_device *rdev = crtc->dev->dev_private; | 234 | struct radeon_device *rdev = crtc->dev->dev_private; |
235 | struct radeon_bo *robj = gem_to_radeon_bo(obj); | ||
236 | uint64_t gpu_addr; | ||
237 | int ret; | ||
238 | |||
239 | ret = radeon_bo_reserve(robj, false); | ||
240 | if (unlikely(ret != 0)) | ||
241 | goto fail; | ||
242 | /* Only 27 bit offset for legacy cursor */ | ||
243 | ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, | ||
244 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, | ||
245 | &gpu_addr); | ||
246 | radeon_bo_unreserve(robj); | ||
247 | if (ret) | ||
248 | goto fail; | ||
235 | 249 | ||
236 | if (ASIC_IS_DCE4(rdev)) { | 250 | if (ASIC_IS_DCE4(rdev)) { |
237 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | 251 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, |
@@ -265,6 +279,13 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | |||
265 | radeon_crtc->cursor_hot_x = hot_x; | 279 | radeon_crtc->cursor_hot_x = hot_x; |
266 | radeon_crtc->cursor_hot_y = hot_y; | 280 | radeon_crtc->cursor_hot_y = hot_y; |
267 | } | 281 | } |
282 | |||
283 | return 0; | ||
284 | |||
285 | fail: | ||
286 | drm_gem_object_unreference_unlocked(obj); | ||
287 | |||
288 | return ret; | ||
268 | } | 289 | } |
269 | 290 | ||
270 | int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | 291 | int radeon_crtc_cursor_set2(struct drm_crtc *crtc, |
@@ -276,10 +297,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | |||
276 | int32_t hot_y) | 297 | int32_t hot_y) |
277 | { | 298 | { |
278 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 299 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
279 | struct radeon_device *rdev = crtc->dev->dev_private; | ||
280 | struct drm_gem_object *obj; | 300 | struct drm_gem_object *obj; |
281 | struct radeon_bo *robj; | ||
282 | uint64_t gpu_addr; | ||
283 | int ret; | 301 | int ret; |
284 | 302 | ||
285 | if (!handle) { | 303 | if (!handle) { |
@@ -301,41 +319,64 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | |||
301 | return -ENOENT; | 319 | return -ENOENT; |
302 | } | 320 | } |
303 | 321 | ||
304 | robj = gem_to_radeon_bo(obj); | ||
305 | ret = radeon_bo_reserve(robj, false); | ||
306 | if (unlikely(ret != 0)) | ||
307 | goto fail; | ||
308 | /* Only 27 bit offset for legacy cursor */ | ||
309 | ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, | ||
310 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, | ||
311 | &gpu_addr); | ||
312 | radeon_bo_unreserve(robj); | ||
313 | if (ret) | ||
314 | goto fail; | ||
315 | |||
316 | radeon_crtc->cursor_width = width; | 322 | radeon_crtc->cursor_width = width; |
317 | radeon_crtc->cursor_height = height; | 323 | radeon_crtc->cursor_height = height; |
318 | 324 | ||
319 | radeon_lock_cursor(crtc, true); | 325 | radeon_lock_cursor(crtc, true); |
320 | radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); | 326 | ret = radeon_set_cursor(crtc, obj, hot_x, hot_y); |
321 | radeon_show_cursor(crtc); | 327 | |
328 | if (ret) | ||
329 | DRM_ERROR("radeon_set_cursor returned %d, not changing cursor\n", | ||
330 | ret); | ||
331 | else | ||
332 | radeon_show_cursor(crtc); | ||
333 | |||
322 | radeon_lock_cursor(crtc, false); | 334 | radeon_lock_cursor(crtc, false); |
323 | 335 | ||
324 | unpin: | 336 | unpin: |
325 | if (radeon_crtc->cursor_bo) { | 337 | if (radeon_crtc->cursor_bo) { |
326 | robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); | 338 | struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); |
327 | ret = radeon_bo_reserve(robj, false); | 339 | ret = radeon_bo_reserve(robj, false); |
328 | if (likely(ret == 0)) { | 340 | if (likely(ret == 0)) { |
329 | radeon_bo_unpin(robj); | 341 | radeon_bo_unpin(robj); |
330 | radeon_bo_unreserve(robj); | 342 | radeon_bo_unreserve(robj); |
331 | } | 343 | } |
332 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); | 344 | if (radeon_crtc->cursor_bo != obj) |
345 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); | ||
333 | } | 346 | } |
334 | 347 | ||
335 | radeon_crtc->cursor_bo = obj; | 348 | radeon_crtc->cursor_bo = obj; |
336 | return 0; | 349 | return 0; |
337 | fail: | 350 | } |
338 | drm_gem_object_unreference_unlocked(obj); | ||
339 | 351 | ||
340 | return ret; | 352 | /** |
353 | * radeon_cursor_reset - Re-set the current cursor, if any. | ||
354 | * | ||
355 | * @crtc: drm crtc | ||
356 | * | ||
357 | * If the CRTC passed in currently has a cursor assigned, this function | ||
358 | * makes sure it's visible. | ||
359 | */ | ||
360 | void radeon_cursor_reset(struct drm_crtc *crtc) | ||
361 | { | ||
362 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
363 | int ret; | ||
364 | |||
365 | if (radeon_crtc->cursor_bo) { | ||
366 | radeon_lock_cursor(crtc, true); | ||
367 | |||
368 | radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x, | ||
369 | radeon_crtc->cursor_y); | ||
370 | |||
371 | ret = radeon_set_cursor(crtc, radeon_crtc->cursor_bo, | ||
372 | radeon_crtc->cursor_hot_x, | ||
373 | radeon_crtc->cursor_hot_y); | ||
374 | if (ret) | ||
375 | DRM_ERROR("radeon_set_cursor returned %d, not showing " | ||
376 | "cursor\n", ret); | ||
377 | else | ||
378 | radeon_show_cursor(crtc); | ||
379 | |||
380 | radeon_lock_cursor(crtc, false); | ||
381 | } | ||
341 | } | 382 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index cafb1ccf2ec3..678b4386540d 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -1054,6 +1054,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1054 | DRM_ERROR("Mode need scaling but only first crtc can do that.\n"); | 1054 | DRM_ERROR("Mode need scaling but only first crtc can do that.\n"); |
1055 | } | 1055 | } |
1056 | } | 1056 | } |
1057 | radeon_cursor_reset(crtc); | ||
1057 | return 0; | 1058 | return 0; |
1058 | } | 1059 | } |
1059 | 1060 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f3d87cdd5c9d..390db897f322 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -818,6 +818,7 @@ extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | |||
818 | int32_t hot_y); | 818 | int32_t hot_y); |
819 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, | 819 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, |
820 | int x, int y); | 820 | int x, int y); |
821 | extern void radeon_cursor_reset(struct drm_crtc *crtc); | ||
821 | 822 | ||
822 | extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, | 823 | extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, |
823 | unsigned int flags, | 824 | unsigned int flags, |