提交 83f7fd05 编写于 作者: J Jesse Barnes 提交者: Eric Anholt

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: NJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: NEric Anholt <eric@anholt.net>
上级 be26a10b
...@@ -4680,6 +4680,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -4680,6 +4680,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
unsigned long flags; unsigned long flags;
int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
int ret, pipesrc; int ret, pipesrc;
u32 flip_mask;
work = kzalloc(sizeof *work, GFP_KERNEL); work = kzalloc(sizeof *work, GFP_KERNEL);
if (work == NULL) if (work == NULL)
...@@ -4733,6 +4734,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -4733,6 +4734,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
atomic_inc(&obj_priv->pending_flip); atomic_inc(&obj_priv->pending_flip);
work->pending_flip_obj = obj; 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); BEGIN_LP_RING(4);
OUT_RING(MI_DISPLAY_FLIP | OUT_RING(MI_DISPLAY_FLIP |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册