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

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

drm/i915: handle shared framebuffers when flipping

If a framebuffer is shared across CRTCs, the x,y position of one of them
is likely to be something other than the origin (e.g. for extended
desktop configs).  So calculate the offset at flip time so such
configurations can work.

Fixes https://bugs.freedesktop.org/show_bug.cgi?id=28518

.

Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Tested-by: default avatarThomas M. <tmezzadra@gmail.com>
Tested-by: default avatarfangxun <xunx.fang@intel.com>
Cc: stable@kernel.org
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 6f772d7e
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -4695,7 +4695,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
	struct drm_gem_object *obj;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	struct intel_unpin_work *work;
	unsigned long flags;
	unsigned long flags, offset;
	int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
	int ret, pipesrc;
	u32 flip_mask;
@@ -4762,19 +4762,23 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
		while (I915_READ(ISR) & flip_mask)
			;

	/* Offset into the new buffer for cases of shared fbs between CRTCs */
	offset = obj_priv->gtt_offset;
	offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8);

	BEGIN_LP_RING(4);
	if (IS_I965G(dev)) {
		OUT_RING(MI_DISPLAY_FLIP |
			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
		OUT_RING(fb->pitch);
		OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
		OUT_RING(offset | obj_priv->tiling_mode);
		pipesrc = I915_READ(pipesrc_reg); 
		OUT_RING(pipesrc & 0x0fff0fff);
	} else {
		OUT_RING(MI_DISPLAY_FLIP_I915 |
			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
		OUT_RING(fb->pitch);
		OUT_RING(obj_priv->gtt_offset);
		OUT_RING(offset);
		OUT_RING(MI_NOOP);
	}
	ADVANCE_LP_RING();