aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-07-23 15:03:37 -0400
committerEric Anholt <eric@anholt.net>2010-07-26 13:45:55 -0400
commitbe9a3dbf65a69933b06011f049b1e2fdfa6bc8b9 (patch)
treeb6f127f19fc374bbdf8932b945c65f2a86d00703
parent6f772d7e2f4105470b9f3d0f0b26f06f61b1278d (diff)
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: Jesse Barnes <jbarnes@virtuousgeek.org> Tested-by: Thomas M. <tmezzadra@gmail.com> Tested-by: fangxun <xunx.fang@intel.com> Cc: stable@kernel.org Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 68dcf36e2793..ab8162afb4a7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4695,7 +4695,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4695 struct drm_gem_object *obj; 4695 struct drm_gem_object *obj;
4696 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4696 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4697 struct intel_unpin_work *work; 4697 struct intel_unpin_work *work;
4698 unsigned long flags; 4698 unsigned long flags, offset;
4699 int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; 4699 int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
4700 int ret, pipesrc; 4700 int ret, pipesrc;
4701 u32 flip_mask; 4701 u32 flip_mask;
@@ -4762,19 +4762,23 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4762 while (I915_READ(ISR) & flip_mask) 4762 while (I915_READ(ISR) & flip_mask)
4763 ; 4763 ;
4764 4764
4765 /* Offset into the new buffer for cases of shared fbs between CRTCs */
4766 offset = obj_priv->gtt_offset;
4767 offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8);
4768
4765 BEGIN_LP_RING(4); 4769 BEGIN_LP_RING(4);
4766 if (IS_I965G(dev)) { 4770 if (IS_I965G(dev)) {
4767 OUT_RING(MI_DISPLAY_FLIP | 4771 OUT_RING(MI_DISPLAY_FLIP |
4768 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); 4772 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4769 OUT_RING(fb->pitch); 4773 OUT_RING(fb->pitch);
4770 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); 4774 OUT_RING(offset | obj_priv->tiling_mode);
4771 pipesrc = I915_READ(pipesrc_reg); 4775 pipesrc = I915_READ(pipesrc_reg);
4772 OUT_RING(pipesrc & 0x0fff0fff); 4776 OUT_RING(pipesrc & 0x0fff0fff);
4773 } else { 4777 } else {
4774 OUT_RING(MI_DISPLAY_FLIP_I915 | 4778 OUT_RING(MI_DISPLAY_FLIP_I915 |
4775 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); 4779 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4776 OUT_RING(fb->pitch); 4780 OUT_RING(fb->pitch);
4777 OUT_RING(obj_priv->gtt_offset); 4781 OUT_RING(offset);
4778 OUT_RING(MI_NOOP); 4782 OUT_RING(MI_NOOP);
4779 } 4783 }
4780 ADVANCE_LP_RING(); 4784 ADVANCE_LP_RING();