summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2014-04-23 10:27:51 +0200
committerChristian König <christian.koenig@amd.com>2014-04-23 10:56:30 +0200
commit32b164b1046e1fbf78b812960ccf6685ed404ed5 (patch)
tree1ca74f264800eec2392bec4b2b66f5091d42606d
parentc5e08d109980ba3b5cb962196376c1f8775e9adb (diff)
drm/radeon: WIP rework page flip handlingdrm-next-3.16
Signed-off-by: Christian König <christian.koenig@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c73
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
2 files changed, 22 insertions, 52 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index c4b15dfafdf6..8e5ace9da681 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -260,8 +260,29 @@ static void radeon_unpin_work_func(struct work_struct *__work)
{
struct radeon_unpin_work *work =
container_of(__work, struct radeon_unpin_work, work);
+ struct radeon_device *rdev = work->rdev;
+ struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
+ unsigned long flags;
int r;
+ if (radeon_page_flip_pending(rdev, work->crtc_id))
+ return;
+
+ spin_lock_irqsave(&rdev->ddev->event_lock, flags);
+
+ /* Pageflip completed. Clean up. */
+ radeon_crtc->unpin_work = NULL;
+
+ /* wakeup userspace */
+ if (work->event)
+ drm_send_vblank_event(rdev->ddev, work->crtc_id, work->event);
+
+ spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+
+ drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
+ radeon_fence_unref(&work->fence);
+ radeon_post_page_flip(work->rdev, work->crtc_id);
+
/* unpin of the old buffer */
r = radeon_bo_reserve(work->old_rbo, false);
if (likely(r == 0)) {
@@ -282,8 +303,6 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
struct radeon_unpin_work *work;
unsigned long flags;
- u32 update_pending;
- int vpos, hpos;
spin_lock_irqsave(&rdev->ddev->event_lock, flags);
work = radeon_crtc->unpin_work;
@@ -293,59 +312,12 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
return;
}
/* New pageflip, or just completion of a previous one? */
- if (!radeon_crtc->deferred_flip_completion) {
+ if (work->new_crtc_base) {
/* do the flip (mmio) */
radeon_page_flip(rdev, crtc_id, work->new_crtc_base);
- update_pending = radeon_page_flip_pending(rdev, crtc_id);
- trace_radeon_page_flip(update_pending, crtc_id, work->new_crtc_base);
- } else {
- /* This is just a completion of a flip queued in crtc
- * at last invocation. Make sure we go directly to
- * completion routine.
- */
- update_pending = 0;
- radeon_crtc->deferred_flip_completion = 0;
}
-
- /* Has the pageflip already completed in crtc, or is it certain
- * to complete in this vblank?
- */
- if (update_pending &&
- (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0,
- &vpos, &hpos, NULL, NULL)) &&
- ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
- (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
- /* crtc didn't flip in this target vblank interval,
- * but flip is pending in crtc. Based on the current
- * scanout position we know that the current frame is
- * (nearly) complete and the flip will (likely)
- * complete before the start of the next frame.
- */
- update_pending = 0;
- }
- if (update_pending) {
- /* crtc didn't flip in this target vblank interval,
- * but flip is pending in crtc. It will complete it
- * in next vblank interval, so complete the flip at
- * next vblank irq.
- */
- radeon_crtc->deferred_flip_completion = 1;
- spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
- return;
- }
-
- /* Pageflip (will be) certainly completed in this vblank. Clean up. */
- radeon_crtc->unpin_work = NULL;
-
- /* wakeup userspace */
- if (work->event)
- drm_send_vblank_event(rdev->ddev, crtc_id, work->event);
-
spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
- drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
- radeon_fence_unref(&work->fence);
- radeon_post_page_flip(work->rdev, work->crtc_id);
schedule_work(&work->work);
}
@@ -400,7 +372,6 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
goto unlock_free;
}
radeon_crtc->unpin_work = work;
- radeon_crtc->deferred_flip_completion = 0;
spin_unlock_irqrestore(&dev->event_lock, flags);
/* pin the new buffer */
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 6ddf31a2d34e..630b18873db9 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -325,7 +325,6 @@ struct radeon_crtc {
int pll_id;
/* page flipping */
struct radeon_unpin_work *unpin_work;
- int deferred_flip_completion;
/* pll sharing */
struct radeon_atom_ss ss;
bool ss_enabled;