diff mbox

[ANNOUNCE] xf86-video-intel 2.11.901

Message ID 20100617133217.5babef34@virtuousgeek.org
State Accepted
Headers show

Commit Message

Jesse Barnes June 17, 2010, 8:32 p.m. UTC
None
diff mbox

Patch

From a8ddc8b3743abb72b6c7e26ce75ae98d93d92133 Mon Sep 17 00:00:00 2001
From: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Mon, 5 Apr 2010 14:03:51 -0700
Subject: [PATCH 3/3] drm/i915: don't queue flips during a flip pending event

Hardware will set the flip pending ISR bit as soon as it receives the
flip instruction, and (supposedly) clear it once the flip completes
(e.g. at the next vblank).  If we try to send down a flip instruction
while the ISR bit is set, the hardware can become very confused, and we
may never receive the corresponding flip pending interrupt, effectively
hanging the chip.

Fixes fdo bug #27040.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6f5e7f5..24853e1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4235,6 +4235,7 @@  static int intel_crtc_page_flip(struct drm_crtc *crtc,
 	unsigned long flags;
 	int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
 	int ret, pipesrc;
+	u32 flip_mask;
 	RING_LOCALS;
 
 	work = kzalloc(sizeof *work, GFP_KERNEL);
@@ -4285,6 +4286,15 @@  static int intel_crtc_page_flip(struct drm_crtc *crtc,
 	atomic_inc(&obj_priv->pending_flip);
 	work->pending_flip_obj = obj;
 
+	if (intel_crtc->plane)
+		flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+	else
+		flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
+
+	/* Wait for any previous flip to finish */
+	while (I915_READ(ISR) & flip_mask)
+		;
+
 	BEGIN_LP_RING(4);
 	if (IS_I965G(dev)) {
 		OUT_RING(MI_DISPLAY_FLIP |
-- 
1.6.6.1