aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-01-14 16:18:02 -0500
committerEric Anholt <eric@anholt.net>2010-01-26 01:01:12 -0500
commitde3f440f8c9922afe8770dd16c84f1c87d779b59 (patch)
tree3f5eafaeb3e90a92b3ca503592d99277fe60816b /drivers/gpu/drm
parent8a6c77d645d9111f7bc01f908464301f5c3e0a05 (diff)
drm/i915: handle non-flip pending case when unpinning the scanout buffer
The first page flip queued will replace the current front buffer, which should have a 0 pending flip count. So at finish time we need to handle that case (i.e. if the flip count is 0 *or* dec_and_test is 0 we need to wake the waiters). Also fix up an error path in the queue function and add some debug output (only enabled with driver debugging). Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2cc489b6629e..5f14dfbf715c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3985,6 +3985,12 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
3985 spin_lock_irqsave(&dev->event_lock, flags); 3985 spin_lock_irqsave(&dev->event_lock, flags);
3986 work = intel_crtc->unpin_work; 3986 work = intel_crtc->unpin_work;
3987 if (work == NULL || !work->pending) { 3987 if (work == NULL || !work->pending) {
3988 if (work && !work->pending) {
3989 obj_priv = work->obj->driver_private;
3990 DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
3991 obj_priv,
3992 atomic_read(&obj_priv->pending_flip));
3993 }
3988 spin_unlock_irqrestore(&dev->event_lock, flags); 3994 spin_unlock_irqrestore(&dev->event_lock, flags);
3989 return; 3995 return;
3990 } 3996 }
@@ -4006,7 +4012,10 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
4006 spin_unlock_irqrestore(&dev->event_lock, flags); 4012 spin_unlock_irqrestore(&dev->event_lock, flags);
4007 4013
4008 obj_priv = work->obj->driver_private; 4014 obj_priv = work->obj->driver_private;
4009 if (atomic_dec_and_test(&obj_priv->pending_flip)) 4015
4016 /* Initial scanout buffer will have a 0 pending flip count */
4017 if ((atomic_read(&obj_priv->pending_flip) == 0) ||
4018 atomic_dec_and_test(&obj_priv->pending_flip))
4010 DRM_WAKEUP(&dev_priv->pending_flip_queue); 4019 DRM_WAKEUP(&dev_priv->pending_flip_queue);
4011 schedule_work(&work->work); 4020 schedule_work(&work->work);
4012} 4021}
@@ -4019,8 +4028,11 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
4019 unsigned long flags; 4028 unsigned long flags;
4020 4029
4021 spin_lock_irqsave(&dev->event_lock, flags); 4030 spin_lock_irqsave(&dev->event_lock, flags);
4022 if (intel_crtc->unpin_work) 4031 if (intel_crtc->unpin_work) {
4023 intel_crtc->unpin_work->pending = 1; 4032 intel_crtc->unpin_work->pending = 1;
4033 } else {
4034 DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
4035 }
4024 spin_unlock_irqrestore(&dev->event_lock, flags); 4036 spin_unlock_irqrestore(&dev->event_lock, flags);
4025} 4037}
4026 4038
@@ -4054,6 +4066,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4054 /* We borrow the event spin lock for protecting unpin_work */ 4066 /* We borrow the event spin lock for protecting unpin_work */
4055 spin_lock_irqsave(&dev->event_lock, flags); 4067 spin_lock_irqsave(&dev->event_lock, flags);
4056 if (intel_crtc->unpin_work) { 4068 if (intel_crtc->unpin_work) {
4069 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
4057 spin_unlock_irqrestore(&dev->event_lock, flags); 4070 spin_unlock_irqrestore(&dev->event_lock, flags);
4058 kfree(work); 4071 kfree(work);
4059 mutex_unlock(&dev->struct_mutex); 4072 mutex_unlock(&dev->struct_mutex);
@@ -4067,7 +4080,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4067 4080
4068 ret = intel_pin_and_fence_fb_obj(dev, obj); 4081 ret = intel_pin_and_fence_fb_obj(dev, obj);
4069 if (ret != 0) { 4082 if (ret != 0) {
4083 DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
4084 obj->driver_private);
4070 kfree(work); 4085 kfree(work);
4086 intel_crtc->unpin_work = NULL;
4071 mutex_unlock(&dev->struct_mutex); 4087 mutex_unlock(&dev->struct_mutex);
4072 return ret; 4088 return ret;
4073 } 4089 }