aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-09-17 08:35:02 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-10-03 09:19:15 -0400
commita0e847641cd7239661ff1b39db0afb0e2992026f (patch)
tree052c3ec2e7fcc8107f319f3f83f9a5d500994665
parent38aea07167b6f51a42e09812212a000ce84afb77 (diff)
drm/radeon: cope with foreign fences inside display
Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c30
2 files changed, 20 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 510fe9677e84..06d24b85003e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -712,7 +712,7 @@ struct radeon_flip_work {
712 uint64_t base; 712 uint64_t base;
713 struct drm_pending_vblank_event *event; 713 struct drm_pending_vblank_event *event;
714 struct radeon_bo *old_rbo; 714 struct radeon_bo *old_rbo;
715 struct radeon_fence *fence; 715 struct fence *fence;
716}; 716};
717 717
718struct r500_irq_stat_regs { 718struct r500_irq_stat_regs {
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 4eb37976f879..00ead8c2758a 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -402,14 +402,21 @@ static void radeon_flip_work_func(struct work_struct *__work)
402 402
403 down_read(&rdev->exclusive_lock); 403 down_read(&rdev->exclusive_lock);
404 if (work->fence) { 404 if (work->fence) {
405 r = radeon_fence_wait(work->fence, false); 405 struct radeon_fence *fence;
406 if (r == -EDEADLK) { 406
407 up_read(&rdev->exclusive_lock); 407 fence = to_radeon_fence(work->fence);
408 do { 408 if (fence && fence->rdev == rdev) {
409 r = radeon_gpu_reset(rdev); 409 r = radeon_fence_wait(fence, false);
410 } while (r == -EAGAIN); 410 if (r == -EDEADLK) {
411 down_read(&rdev->exclusive_lock); 411 up_read(&rdev->exclusive_lock);
412 } 412 do {
413 r = radeon_gpu_reset(rdev);
414 } while (r == -EAGAIN);
415 down_read(&rdev->exclusive_lock);
416 }
417 } else
418 r = fence_wait(work->fence, false);
419
413 if (r) 420 if (r)
414 DRM_ERROR("failed to wait on page flip fence (%d)!\n", r); 421 DRM_ERROR("failed to wait on page flip fence (%d)!\n", r);
415 422
@@ -418,7 +425,8 @@ static void radeon_flip_work_func(struct work_struct *__work)
418 * confused about which BO the CRTC is scanning out 425 * confused about which BO the CRTC is scanning out
419 */ 426 */
420 427
421 radeon_fence_unref(&work->fence); 428 fence_put(work->fence);
429 work->fence = NULL;
422 } 430 }
423 431
424 /* We borrow the event spin lock for protecting flip_status */ 432 /* We borrow the event spin lock for protecting flip_status */
@@ -494,7 +502,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
494 DRM_ERROR("failed to pin new rbo buffer before flip\n"); 502 DRM_ERROR("failed to pin new rbo buffer before flip\n");
495 goto cleanup; 503 goto cleanup;
496 } 504 }
497 work->fence = (struct radeon_fence *)fence_get(reservation_object_get_excl(new_rbo->tbo.resv)); 505 work->fence = fence_get(reservation_object_get_excl(new_rbo->tbo.resv));
498 radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL); 506 radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL);
499 radeon_bo_unreserve(new_rbo); 507 radeon_bo_unreserve(new_rbo);
500 508
@@ -576,7 +584,7 @@ pflip_cleanup:
576 584
577cleanup: 585cleanup:
578 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); 586 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
579 radeon_fence_unref(&work->fence); 587 fence_put(work->fence);
580 kfree(work); 588 kfree(work);
581 return r; 589 return r;
582} 590}