From: Ville Syrj?l? <ville.syrjala at linux.intel.com> Take fb->offset[0] into account when calculating the linear and tile x/y offsets. For non-tiled surfaces fb->offset[0] is simply added to the linear byte offset. For tiled surfaces treat fb->offsets[0] as a byte offset into the linearized view of the surface. So we end up converting fb->offsets[0] into additional x and y offsets. Signed-off-by: Ville Syrj?l? <ville.syrjala at linux.intel.com> --- drivers/gpu/drm/i915/intel_display.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9df15ee..f4338cb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1826,6 +1826,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, unsigned long Start, Offset; u32 dspcntr; u32 reg; + unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0); switch (plane) { case 0: @@ -1885,12 +1886,14 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, I915_WRITE(reg, dspcntr); Start = obj->gtt_offset; - Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); + Offset = fb->offsets[0] + y * fb->pitches[0] + x * cpp; DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", Start, Offset, x, y, fb->pitches[0]); I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); if (INTEL_INFO(dev)->gen >= 4) { + y += fb->offsets[0] / fb->pitches[0]; + x += fb->offsets[0] % fb->pitches[0] / cpp; I915_MODIFY_DISPBASE(DSPSURF(plane), Start); I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); I915_WRITE(DSPADDR(plane), Offset); @@ -1913,6 +1916,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc, unsigned long Start, Offset; u32 dspcntr; u32 reg; + unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0); switch (plane) { case 0: @@ -1970,7 +1974,10 @@ static int ironlake_update_plane(struct drm_crtc *crtc, I915_WRITE(reg, dspcntr); Start = obj->gtt_offset; - Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); + Offset = fb->offsets[0] + y * fb->pitches[0] + x * cpp; + + y += fb->offsets[0] / fb->pitches[0]; + x += fb->offsets[0] % fb->pitches[0] / cpp; DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", Start, Offset, x, y, fb->pitches[0]); @@ -5993,7 +6000,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, goto err; /* Offset into the new buffer for cases of shared fbs between CRTCs */ - offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; + offset = fb->offsets[0] + crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; ret = intel_ring_begin(ring, 6); if (ret) @@ -6039,7 +6046,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev, goto err; /* Offset into the new buffer for cases of shared fbs between CRTCs */ - offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; + offset = fb->offsets[0] + crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; ret = intel_ring_begin(ring, 6); if (ret) -- 1.7.3.4