diff options
author | Christian König <christian.koenig@amd.com> | 2014-04-23 10:27:51 +0200 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2014-04-23 10:56:30 +0200 |
commit | 32b164b1046e1fbf78b812960ccf6685ed404ed5 (patch) | |
tree | 1ca74f264800eec2392bec4b2b66f5091d42606d | |
parent | c5e08d109980ba3b5cb962196376c1f8775e9adb (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.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 1 |
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; |