|
@@ -2806,13 +2806,34 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
|
|
|
udelay(100);
|
|
|
}
|
|
|
|
|
|
+static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
|
|
|
+{
|
|
|
+ struct drm_device *dev = crtc->dev;
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ unsigned long flags;
|
|
|
+ bool pending;
|
|
|
+
|
|
|
+ if (atomic_read(&dev_priv->mm.wedged))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
+ pending = to_intel_crtc(crtc)->unpin_work != NULL;
|
|
|
+ spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
+
|
|
|
+ return pending;
|
|
|
+}
|
|
|
+
|
|
|
static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
|
|
|
{
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
if (crtc->fb == NULL)
|
|
|
return;
|
|
|
|
|
|
+ wait_event(dev_priv->pending_flip_queue,
|
|
|
+ !intel_crtc_has_pending_flip(crtc));
|
|
|
+
|
|
|
mutex_lock(&dev->struct_mutex);
|
|
|
intel_finish_fb(crtc->fb);
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
@@ -6217,9 +6238,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
|
|
|
|
|
|
atomic_clear_mask(1 << intel_crtc->plane,
|
|
|
&obj->pending_flip.counter);
|
|
|
- if (atomic_read(&obj->pending_flip) == 0)
|
|
|
- wake_up(&dev_priv->pending_flip_queue);
|
|
|
|
|
|
+ wake_up(&dev_priv->pending_flip_queue);
|
|
|
schedule_work(&work->work);
|
|
|
|
|
|
trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
|