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>
This commit is contained in:
parent
38aea07167
commit
a0e847641c
|
@ -712,7 +712,7 @@ struct radeon_flip_work {
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
struct drm_pending_vblank_event *event;
|
struct drm_pending_vblank_event *event;
|
||||||
struct radeon_bo *old_rbo;
|
struct radeon_bo *old_rbo;
|
||||||
struct radeon_fence *fence;
|
struct fence *fence;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct r500_irq_stat_regs {
|
struct r500_irq_stat_regs {
|
||||||
|
|
|
@ -402,14 +402,21 @@ static void radeon_flip_work_func(struct work_struct *__work)
|
||||||
|
|
||||||
down_read(&rdev->exclusive_lock);
|
down_read(&rdev->exclusive_lock);
|
||||||
if (work->fence) {
|
if (work->fence) {
|
||||||
r = radeon_fence_wait(work->fence, false);
|
struct radeon_fence *fence;
|
||||||
if (r == -EDEADLK) {
|
|
||||||
up_read(&rdev->exclusive_lock);
|
fence = to_radeon_fence(work->fence);
|
||||||
do {
|
if (fence && fence->rdev == rdev) {
|
||||||
r = radeon_gpu_reset(rdev);
|
r = radeon_fence_wait(fence, false);
|
||||||
} while (r == -EAGAIN);
|
if (r == -EDEADLK) {
|
||||||
down_read(&rdev->exclusive_lock);
|
up_read(&rdev->exclusive_lock);
|
||||||
}
|
do {
|
||||||
|
r = radeon_gpu_reset(rdev);
|
||||||
|
} while (r == -EAGAIN);
|
||||||
|
down_read(&rdev->exclusive_lock);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
r = fence_wait(work->fence, false);
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
DRM_ERROR("failed to wait on page flip fence (%d)!\n", r);
|
DRM_ERROR("failed to wait on page flip fence (%d)!\n", r);
|
||||||
|
|
||||||
|
@ -418,7 +425,8 @@ static void radeon_flip_work_func(struct work_struct *__work)
|
||||||
* confused about which BO the CRTC is scanning out
|
* confused about which BO the CRTC is scanning out
|
||||||
*/
|
*/
|
||||||
|
|
||||||
radeon_fence_unref(&work->fence);
|
fence_put(work->fence);
|
||||||
|
work->fence = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We borrow the event spin lock for protecting flip_status */
|
/* We borrow the event spin lock for protecting flip_status */
|
||||||
|
@ -494,7 +502,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
|
||||||
DRM_ERROR("failed to pin new rbo buffer before flip\n");
|
DRM_ERROR("failed to pin new rbo buffer before flip\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
work->fence = (struct radeon_fence *)fence_get(reservation_object_get_excl(new_rbo->tbo.resv));
|
work->fence = fence_get(reservation_object_get_excl(new_rbo->tbo.resv));
|
||||||
radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL);
|
radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL);
|
||||||
radeon_bo_unreserve(new_rbo);
|
radeon_bo_unreserve(new_rbo);
|
||||||
|
|
||||||
|
@ -576,7 +584,7 @@ pflip_cleanup:
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
|
drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
|
||||||
radeon_fence_unref(&work->fence);
|
fence_put(work->fence);
|
||||||
kfree(work);
|
kfree(work);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue