aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_display.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c33
1 files changed, 6 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 292f73f0ddbd..ffce85a91165 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -282,7 +282,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
282 spin_lock_irqsave(&rdev->ddev->event_lock, flags); 282 spin_lock_irqsave(&rdev->ddev->event_lock, flags);
283 work = radeon_crtc->unpin_work; 283 work = radeon_crtc->unpin_work;
284 if (work == NULL || 284 if (work == NULL ||
285 !radeon_fence_signaled(work->fence)) { 285 (work->fence && !radeon_fence_signaled(work->fence))) {
286 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); 286 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
287 return; 287 return;
288 } 288 }
@@ -348,7 +348,6 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
348 struct radeon_framebuffer *new_radeon_fb; 348 struct radeon_framebuffer *new_radeon_fb;
349 struct drm_gem_object *obj; 349 struct drm_gem_object *obj;
350 struct radeon_bo *rbo; 350 struct radeon_bo *rbo;
351 struct radeon_fence *fence;
352 struct radeon_unpin_work *work; 351 struct radeon_unpin_work *work;
353 unsigned long flags; 352 unsigned long flags;
354 u32 tiling_flags, pitch_pixels; 353 u32 tiling_flags, pitch_pixels;
@@ -359,16 +358,9 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
359 if (work == NULL) 358 if (work == NULL)
360 return -ENOMEM; 359 return -ENOMEM;
361 360
362 r = radeon_fence_create(rdev, &fence);
363 if (unlikely(r != 0)) {
364 kfree(work);
365 DRM_ERROR("flip queue: failed to create fence.\n");
366 return -ENOMEM;
367 }
368 work->event = event; 361 work->event = event;
369 work->rdev = rdev; 362 work->rdev = rdev;
370 work->crtc_id = radeon_crtc->crtc_id; 363 work->crtc_id = radeon_crtc->crtc_id;
371 work->fence = radeon_fence_ref(fence);
372 old_radeon_fb = to_radeon_framebuffer(crtc->fb); 364 old_radeon_fb = to_radeon_framebuffer(crtc->fb);
373 new_radeon_fb = to_radeon_framebuffer(fb); 365 new_radeon_fb = to_radeon_framebuffer(fb);
374 /* schedule unpin of the old buffer */ 366 /* schedule unpin of the old buffer */
@@ -377,6 +369,10 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
377 drm_gem_object_reference(obj); 369 drm_gem_object_reference(obj);
378 rbo = gem_to_radeon_bo(obj); 370 rbo = gem_to_radeon_bo(obj);
379 work->old_rbo = rbo; 371 work->old_rbo = rbo;
372 obj = new_radeon_fb->obj;
373 rbo = gem_to_radeon_bo(obj);
374 if (rbo->tbo.sync_obj)
375 work->fence = radeon_fence_ref(rbo->tbo.sync_obj);
380 INIT_WORK(&work->work, radeon_unpin_work_func); 376 INIT_WORK(&work->work, radeon_unpin_work_func);
381 377
382 /* We borrow the event spin lock for protecting unpin_work */ 378 /* We borrow the event spin lock for protecting unpin_work */
@@ -391,9 +387,6 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
391 spin_unlock_irqrestore(&dev->event_lock, flags); 387 spin_unlock_irqrestore(&dev->event_lock, flags);
392 388
393 /* pin the new buffer */ 389 /* pin the new buffer */
394 obj = new_radeon_fb->obj;
395 rbo = gem_to_radeon_bo(obj);
396
397 DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n", 390 DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n",
398 work->old_rbo, rbo); 391 work->old_rbo, rbo);
399 392
@@ -461,25 +454,11 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
461 goto pflip_cleanup1; 454 goto pflip_cleanup1;
462 } 455 }
463 456
464 /* 32 ought to cover us */
465 r = radeon_ring_lock(rdev, 32);
466 if (r) {
467 DRM_ERROR("failed to lock the ring before flip\n");
468 goto pflip_cleanup2;
469 }
470
471 /* emit the fence */
472 radeon_fence_emit(rdev, fence);
473 /* set the proper interrupt */ 457 /* set the proper interrupt */
474 radeon_pre_page_flip(rdev, radeon_crtc->crtc_id); 458 radeon_pre_page_flip(rdev, radeon_crtc->crtc_id);
475 /* fire the ring */
476 radeon_ring_unlock_commit(rdev);
477 459
478 return 0; 460 return 0;
479 461
480pflip_cleanup2:
481 drm_vblank_put(dev, radeon_crtc->crtc_id);
482
483pflip_cleanup1: 462pflip_cleanup1:
484 r = radeon_bo_reserve(rbo, false); 463 r = radeon_bo_reserve(rbo, false);
485 if (unlikely(r != 0)) { 464 if (unlikely(r != 0)) {
@@ -501,7 +480,7 @@ pflip_cleanup:
501unlock_free: 480unlock_free:
502 drm_gem_object_unreference_unlocked(old_radeon_fb->obj); 481 drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
503 spin_unlock_irqrestore(&dev->event_lock, flags); 482 spin_unlock_irqrestore(&dev->event_lock, flags);
504 radeon_fence_unref(&fence); 483 radeon_fence_unref(&work->fence);
505 kfree(work); 484 kfree(work);
506 485
507 return r; 486 return r;