Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83f7fd05 authored by Jesse Barnes's avatar Jesse Barnes Committed by Eric Anholt
Browse files

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.

Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent be26a10b
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -4680,6 +4680,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;

	work = kzalloc(sizeof *work, GFP_KERNEL);
	if (work == NULL)
@@ -4733,6 +4734,16 @@ 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 */
	if (IS_GEN3(dev))
		while (I915_READ(ISR) & flip_mask)
			;

	BEGIN_LP_RING(4);
	OUT_RING(MI_DISPLAY_FLIP |
		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));