diff options
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 33 |
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 | ||
480 | pflip_cleanup2: | ||
481 | drm_vblank_put(dev, radeon_crtc->crtc_id); | ||
482 | |||
483 | pflip_cleanup1: | 462 | pflip_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: | |||
501 | unlock_free: | 480 | unlock_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; |