All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915: Handle untiled planes when computing their offsets
@ 2013-02-21 14:45 Chris Wilson
  2013-02-21 16:55 ` [Intel-gfx] " Ville Syrjälä
  0 siblings, 1 reply; 8+ messages in thread
From: Chris Wilson @ 2013-02-21 14:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: Chris Wilson, Daniel Vetter, stable

We trim the fb to fit the CRTC by computing the offset of that CRTC to
its nearest tile_row origin. This allows us to use framebuffers that are
larger than the CRTC limits without additional work.

However, we failed to compute the offset for a linear framebuffer
correctly as we treated its x-advance in whole tiles (instead of the
linear increment expected), leaving the CRTC misaligned with its
contents.

Fixes regression from commit c2c75131244507c93f812862fdbd4f3a37139401
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Thu Jul 5 12:17:30 2012 +0200

    drm/i915: adjust framebuffer base address on gen4+

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61152
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
---
 drivers/gpu/drm/i915/intel_display.c |   14 +++++++++-----
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++-
 drivers/gpu/drm/i915/intel_sprite.c  |    6 ++++--
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a3ca9a8..2a46f08 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1906,18 +1906,20 @@ void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
 
 /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
  * is assumed to be a power-of-two. */
-unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
+unsigned long intel_gen4_compute_planar_offset(int *x, int *y,
+					       unsigned int tiling_mode,
 					       unsigned int bpp,
 					       unsigned int pitch)
 {
-	int tile_rows, tiles;
+	int tile_rows, tiles, tile_size;
 
 	tile_rows = *y / 8;
 	*y %= 8;
 	tiles = *x / (512/bpp);
 	*x %= 512/bpp;
 
-	return tile_rows * pitch * 8 + tiles * 4096;
+	tile_size = tiling_mode != I915_TILING_NONE ? 4096 : 512;
+	return (tile_rows * pitch * 8 + tiles * tile_size) & -4096;
 }
 
 static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
@@ -1993,7 +1995,8 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 
 	if (INTEL_INFO(dev)->gen >= 4) {
 		intel_crtc->dspaddr_offset =
-			intel_gen4_compute_offset_xtiled(&x, &y,
+			intel_gen4_compute_planar_offset(&x, &y,
+							 obj->tiling_mode,
 							 fb->bits_per_pixel / 8,
 							 fb->pitches[0]);
 		linear_offset -= intel_crtc->dspaddr_offset;
@@ -2085,7 +2088,8 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
 
 	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
 	intel_crtc->dspaddr_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
+		intel_gen4_compute_planar_offset(&x, &y,
+						 obj->tiling_mode,
 						 fb->bits_per_pixel / 8,
 						 fb->pitches[0]);
 	linear_offset -= intel_crtc->dspaddr_offset;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3a671d5..f5ad87b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -671,7 +671,8 @@ extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
 extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe,
 			 struct drm_display_mode *mode);
 
-extern unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
+extern unsigned long intel_gen4_compute_planar_offset(int *x, int *y,
+						      unsigned int tiling_mode,
 						      unsigned int bpp,
 						      unsigned int pitch);
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 03cfd62..ea90077 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -119,7 +119,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
 
 	linear_offset = y * fb->pitches[0] + x * pixel_size;
 	sprsurf_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
+		intel_gen4_compute_planar_offset(&x, &y,
+						 obj->tiling_mode,
 						 pixel_size, fb->pitches[0]);
 	linear_offset -= sprsurf_offset;
 
@@ -292,7 +293,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
 
 	linear_offset = y * fb->pitches[0] + x * pixel_size;
 	dvssurf_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
+		intel_gen4_compute_planar_offset(&x, &y,
+						 obj->tiling_mode,
 						 pixel_size, fb->pitches[0]);
 	linear_offset -= dvssurf_offset;
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915: Handle untiled planes when computing their offsets
  2013-02-21 14:45 [PATCH] drm/i915: Handle untiled planes when computing their offsets Chris Wilson
@ 2013-02-21 16:55 ` Ville Syrjälä
  2013-02-21 19:05   ` Chris Wilson
  0 siblings, 1 reply; 8+ messages in thread
From: Ville Syrjälä @ 2013-02-21 16:55 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx, Daniel Vetter, stable

On Thu, Feb 21, 2013 at 02:45:26PM +0000, Chris Wilson wrote:
> We trim the fb to fit the CRTC by computing the offset of that CRTC to
> its nearest tile_row origin. This allows us to use framebuffers that are
> larger than the CRTC limits without additional work.
> 
> However, we failed to compute the offset for a linear framebuffer
> correctly as we treated its x-advance in whole tiles (instead of the
> linear increment expected), leaving the CRTC misaligned with its
> contents.
> 
> Fixes regression from commit c2c75131244507c93f812862fdbd4f3a37139401
> Author: Daniel Vetter <daniel.vetter@ffwll.ch>
> Date:   Thu Jul 5 12:17:30 2012 +0200
> 
>     drm/i915: adjust framebuffer base address on gen4+
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61152
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: stable@vger.kernel.org
> ---
>  drivers/gpu/drm/i915/intel_display.c |   14 +++++++++-----
>  drivers/gpu/drm/i915/intel_drv.h     |    3 ++-
>  drivers/gpu/drm/i915/intel_sprite.c  |    6 ++++--
>  3 files changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index a3ca9a8..2a46f08 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1906,18 +1906,20 @@ void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
>  
>  /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
>   * is assumed to be a power-of-two. */
> -unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
> +unsigned long intel_gen4_compute_planar_offset(int *x, int *y,
> +					       unsigned int tiling_mode,
>  					       unsigned int bpp,
>  					       unsigned int pitch)
>  {
> -	int tile_rows, tiles;
> +	int tile_rows, tiles, tile_size;
>  
>  	tile_rows = *y / 8;
>  	*y %= 8;
>  	tiles = *x / (512/bpp);
>  	*x %= 512/bpp;
>  
> -	return tile_rows * pitch * 8 + tiles * 4096;
> +	tile_size = tiling_mode != I915_TILING_NONE ? 4096 : 512;
> +	return (tile_rows * pitch * 8 + tiles * tile_size) & -4096;

This doesn't seem to work as intended. Eg. plug in
x=128, y=0, bpp=4, pitch=1024 and you get x=0,y=0,off=0 out.

Well I suppose it works when we actually have the LINOFF register since
we compute the value using the original x/y values, and the subtract the
result from this computation. But that sort of behaviour seems a bit
fragile. And in any case, this won't work on HSW where we use the
adjusted x/y offsets even w/ linear surfaces.

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] drm/i915: Handle untiled planes when computing their offsets
  2013-02-21 16:55 ` [Intel-gfx] " Ville Syrjälä
@ 2013-02-21 19:05   ` Chris Wilson
  2013-02-21 19:54     ` [Intel-gfx] " Ville Syrjälä
  0 siblings, 1 reply; 8+ messages in thread
From: Chris Wilson @ 2013-02-21 19:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Chris Wilson, Daniel Vetter, stable

We trim the fb to fit the CRTC by computing the offset of that CRTC to
its nearest tile_row origin. This allows us to use framebuffers that are
larger than the CRTC limits without additional work.

However, we failed to compute the offset for a linear framebuffer
correctly as we treated its x-advance in whole tiles (instead of the
linear increment expected), leaving the CRTC misaligned with its
contents.

Fixes regression from commit c2c75131244507c93f812862fdbd4f3a37139401
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Thu Jul 5 12:17:30 2012 +0200

    drm/i915: adjust framebuffer base address on gen4+

v2: Adjust relative x-coordinate after linear alignment (vsyrjala)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61152
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
---
 drivers/gpu/drm/i915/intel_display.c |   33 +++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++-
 drivers/gpu/drm/i915/intel_sprite.c  |    6 ++++--
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a3ca9a8..c32c0dc 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1906,18 +1906,29 @@ void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
 
 /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
  * is assumed to be a power-of-two. */
-unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
-					       unsigned int bpp,
+unsigned long intel_gen4_compute_planar_offset(int *x, int *y,
+					       unsigned int tiling_mode,
+					       unsigned int cpp,
 					       unsigned int pitch)
 {
-	int tile_rows, tiles;
+	if (tiling_mode != I915_TILING_NONE) {
+		int tile_rows, tiles;
 
-	tile_rows = *y / 8;
-	*y %= 8;
-	tiles = *x / (512/bpp);
-	*x %= 512/bpp;
+		tile_rows = *y / 8;
+		*y %= 8;
 
-	return tile_rows * pitch * 8 + tiles * 4096;
+		tiles = *x / (512/cpp);
+		*x %= 512/cpp;
+
+		return tile_rows * pitch * 8 + tiles * 4096;
+	} else {
+		int offset;
+
+		offset = *y * pitch + *x * cpp;
+		*y = 0;
+		*x = (offset & 4095) / cpp;
+		return offset & -4096;
+	}
 }
 
 static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
@@ -1993,7 +2004,8 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 
 	if (INTEL_INFO(dev)->gen >= 4) {
 		intel_crtc->dspaddr_offset =
-			intel_gen4_compute_offset_xtiled(&x, &y,
+			intel_gen4_compute_planar_offset(&x, &y,
+							 obj->tiling_mode,
 							 fb->bits_per_pixel / 8,
 							 fb->pitches[0]);
 		linear_offset -= intel_crtc->dspaddr_offset;
@@ -2085,7 +2097,8 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
 
 	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
 	intel_crtc->dspaddr_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
+		intel_gen4_compute_planar_offset(&x, &y,
+						 obj->tiling_mode,
 						 fb->bits_per_pixel / 8,
 						 fb->pitches[0]);
 	linear_offset -= intel_crtc->dspaddr_offset;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3a671d5..f5ad87b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -671,7 +671,8 @@ extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
 extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe,
 			 struct drm_display_mode *mode);
 
-extern unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
+extern unsigned long intel_gen4_compute_planar_offset(int *x, int *y,
+						      unsigned int tiling_mode,
 						      unsigned int bpp,
 						      unsigned int pitch);
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 03cfd62..ea90077 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -119,7 +119,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
 
 	linear_offset = y * fb->pitches[0] + x * pixel_size;
 	sprsurf_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
+		intel_gen4_compute_planar_offset(&x, &y,
+						 obj->tiling_mode,
 						 pixel_size, fb->pitches[0]);
 	linear_offset -= sprsurf_offset;
 
@@ -292,7 +293,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
 
 	linear_offset = y * fb->pitches[0] + x * pixel_size;
 	dvssurf_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
+		intel_gen4_compute_planar_offset(&x, &y,
+						 obj->tiling_mode,
 						 pixel_size, fb->pitches[0]);
 	linear_offset -= dvssurf_offset;
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915: Handle untiled planes when computing their offsets
  2013-02-21 19:05   ` Chris Wilson
@ 2013-02-21 19:54     ` Ville Syrjälä
  2013-02-21 20:03       ` Chris Wilson
  2013-02-21 20:04       ` Chris Wilson
  0 siblings, 2 replies; 8+ messages in thread
From: Ville Syrjälä @ 2013-02-21 19:54 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx, Daniel Vetter, stable

On Thu, Feb 21, 2013 at 07:05:51PM +0000, Chris Wilson wrote:
> We trim the fb to fit the CRTC by computing the offset of that CRTC to
> its nearest tile_row origin. This allows us to use framebuffers that are
> larger than the CRTC limits without additional work.
> 
> However, we failed to compute the offset for a linear framebuffer
> correctly as we treated its x-advance in whole tiles (instead of the
> linear increment expected), leaving the CRTC misaligned with its
> contents.
> 
> Fixes regression from commit c2c75131244507c93f812862fdbd4f3a37139401
> Author: Daniel Vetter <daniel.vetter@ffwll.ch>
> Date:   Thu Jul 5 12:17:30 2012 +0200
> 
>     drm/i915: adjust framebuffer base address on gen4+
> 
> v2: Adjust relative x-coordinate after linear alignment (vsyrjala)
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61152
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: stable@vger.kernel.org
> ---
>  drivers/gpu/drm/i915/intel_display.c |   33 +++++++++++++++++++++++----------
>  drivers/gpu/drm/i915/intel_drv.h     |    3 ++-
>  drivers/gpu/drm/i915/intel_sprite.c  |    6 ++++--
>  3 files changed, 29 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index a3ca9a8..c32c0dc 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1906,18 +1906,29 @@ void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
>  
>  /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
>   * is assumed to be a power-of-two. */
> -unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
> -					       unsigned int bpp,
> +unsigned long intel_gen4_compute_planar_offset(int *x, int *y,
> +					       unsigned int tiling_mode,
> +					       unsigned int cpp,
>  					       unsigned int pitch)
>  {
> -	int tile_rows, tiles;
> +	if (tiling_mode != I915_TILING_NONE) {
> +		int tile_rows, tiles;
>  
> -	tile_rows = *y / 8;
> -	*y %= 8;
> -	tiles = *x / (512/bpp);
> -	*x %= 512/bpp;
> +		tile_rows = *y / 8;
> +		*y %= 8;
>  
> -	return tile_rows * pitch * 8 + tiles * 4096;
> +		tiles = *x / (512/cpp);
> +		*x %= 512/cpp;
> +
> +		return tile_rows * pitch * 8 + tiles * 4096;
> +	} else {
> +		int offset;

nit: unsigned

> +
> +		offset = *y * pitch + *x * cpp;
> +		*y = 0;
> +		*x = (offset & 4095) / cpp;
> +		return offset & -4096;

That should do it.

There is one small concern though. HSW BSpec tells us that the
offset + size mustn't exceed the maximum allowed sprite size.
That's a bit weird, but perhaps it just means that whaever
internal register that tracks the current x/y source positions
is the same size as the sprite size register.

Hmm, actually it seems I'm complaining about a non-issue. The
max horizontal size seems to be 13 bits, which means 8k, and the
max x offset from this functions is 2k. Given that displays are
probably limited to 4k, that would still leave us 2k to spare.
So I suppose we can just ignore this.

I do have one other small bikeshed though. Why does the function
name have planar in it? Maybe call it intel_gen4_compute_page_offset()
or something?

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915: Handle untiled planes when computing their offsets
  2013-02-21 19:54     ` [Intel-gfx] " Ville Syrjälä
@ 2013-02-21 20:03       ` Chris Wilson
  2013-02-21 20:04       ` Chris Wilson
  1 sibling, 0 replies; 8+ messages in thread
From: Chris Wilson @ 2013-02-21 20:03 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Daniel Vetter, stable

On Thu, Feb 21, 2013 at 09:54:41PM +0200, Ville Syrjälä wrote:
> Hmm, actually it seems I'm complaining about a non-issue. The
> max horizontal size seems to be 13 bits, which means 8k, and the
> max x offset from this functions is 2k. Given that displays are
> probably limited to 4k, that would still leave us 2k to spare.
> So I suppose we can just ignore this.

Yes, that same restriction crossed my mind. For the foresable future, it
will not be problem - and using a LinearFramebuffer is just masochism in
the first place. Or rather a deliberate attempt to make us look bad.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] drm/i915: Handle untiled planes when computing their offsets
  2013-02-21 19:54     ` [Intel-gfx] " Ville Syrjälä
  2013-02-21 20:03       ` Chris Wilson
@ 2013-02-21 20:04       ` Chris Wilson
  2013-02-21 20:17         ` [Intel-gfx] " Ville Syrjälä
  1 sibling, 1 reply; 8+ messages in thread
From: Chris Wilson @ 2013-02-21 20:04 UTC (permalink / raw)
  To: intel-gfx; +Cc: Chris Wilson, Daniel Vetter, stable

We trim the fb to fit the CRTC by computing the offset of that CRTC to
its nearest tile_row origin. This allows us to use framebuffers that are
larger than the CRTC limits without additional work.

However, we failed to compute the offset for a linear framebuffer
correctly as we treated its x-advance in whole tiles (instead of the
linear increment expected), leaving the CRTC misaligned with its
contents.

Fixes regression from commit c2c75131244507c93f812862fdbd4f3a37139401
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Thu Jul 5 12:17:30 2012 +0200

    drm/i915: adjust framebuffer base address on gen4+

v2: Adjust relative x-coordinate after linear alignment (vsyrjala)
v3: Repaint with pokadots (vsyrjala)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61152
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
---
 drivers/gpu/drm/i915/intel_display.c |   41 +++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_drv.h     |    7 +++---
 drivers/gpu/drm/i915/intel_sprite.c  |    8 +++----
 3 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a3ca9a8..5b6e8b7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1906,18 +1906,29 @@ void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
 
 /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
  * is assumed to be a power-of-two. */
-unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
-					       unsigned int bpp,
-					       unsigned int pitch)
+unsigned long intel_gen4_compute_page_offset(int *x, int *y,
+					     unsigned int tiling_mode,
+					     unsigned int cpp,
+					     unsigned int pitch)
 {
-	int tile_rows, tiles;
+	if (tiling_mode != I915_TILING_NONE) {
+		unsigned int tile_rows, tiles;
 
-	tile_rows = *y / 8;
-	*y %= 8;
-	tiles = *x / (512/bpp);
-	*x %= 512/bpp;
+		tile_rows = *y / 8;
+		*y %= 8;
 
-	return tile_rows * pitch * 8 + tiles * 4096;
+		tiles = *x / (512/cpp);
+		*x %= 512/cpp;
+
+		return tile_rows * pitch * 8 + tiles * 4096;
+	} else {
+		unsigned int offset;
+
+		offset = *y * pitch + *x * cpp;
+		*y = 0;
+		*x = (offset & 4095) / cpp;
+		return offset & -4096;
+	}
 }
 
 static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
@@ -1993,9 +2004,9 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 
 	if (INTEL_INFO(dev)->gen >= 4) {
 		intel_crtc->dspaddr_offset =
-			intel_gen4_compute_offset_xtiled(&x, &y,
-							 fb->bits_per_pixel / 8,
-							 fb->pitches[0]);
+			intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
+						       fb->bits_per_pixel / 8,
+						       fb->pitches[0]);
 		linear_offset -= intel_crtc->dspaddr_offset;
 	} else {
 		intel_crtc->dspaddr_offset = linear_offset;
@@ -2085,9 +2096,9 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
 
 	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
 	intel_crtc->dspaddr_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
-						 fb->bits_per_pixel / 8,
-						 fb->pitches[0]);
+		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
+					       fb->bits_per_pixel / 8,
+					       fb->pitches[0]);
 	linear_offset -= intel_crtc->dspaddr_offset;
 
 	DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3a671d5..06f1320 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -671,9 +671,10 @@ extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
 extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe,
 			 struct drm_display_mode *mode);
 
-extern unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
-						      unsigned int bpp,
-						      unsigned int pitch);
+extern unsigned long intel_gen4_compute_page_offset(int *x, int *y,
+						    unsigned int tiling_mode,
+						    unsigned int bpp,
+						    unsigned int pitch);
 
 extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 				     struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 03cfd62..70dc5e3 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -119,8 +119,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
 
 	linear_offset = y * fb->pitches[0] + x * pixel_size;
 	sprsurf_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
-						 pixel_size, fb->pitches[0]);
+		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
+					       pixel_size, fb->pitches[0]);
 	linear_offset -= sprsurf_offset;
 
 	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
@@ -292,8 +292,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
 
 	linear_offset = y * fb->pitches[0] + x * pixel_size;
 	dvssurf_offset =
-		intel_gen4_compute_offset_xtiled(&x, &y,
-						 pixel_size, fb->pitches[0]);
+		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
+					       pixel_size, fb->pitches[0]);
 	linear_offset -= dvssurf_offset;
 
 	if (obj->tiling_mode != I915_TILING_NONE)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915: Handle untiled planes when computing their offsets
  2013-02-21 20:04       ` Chris Wilson
@ 2013-02-21 20:17         ` Ville Syrjälä
  2013-02-21 20:52           ` Daniel Vetter
  0 siblings, 1 reply; 8+ messages in thread
From: Ville Syrjälä @ 2013-02-21 20:17 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx, Daniel Vetter, stable

On Thu, Feb 21, 2013 at 08:04:31PM +0000, Chris Wilson wrote:
> We trim the fb to fit the CRTC by computing the offset of that CRTC to
> its nearest tile_row origin. This allows us to use framebuffers that are
> larger than the CRTC limits without additional work.
> 
> However, we failed to compute the offset for a linear framebuffer
> correctly as we treated its x-advance in whole tiles (instead of the
> linear increment expected), leaving the CRTC misaligned with its
> contents.
> 
> Fixes regression from commit c2c75131244507c93f812862fdbd4f3a37139401
> Author: Daniel Vetter <daniel.vetter@ffwll.ch>
> Date:   Thu Jul 5 12:17:30 2012 +0200
> 
>     drm/i915: adjust framebuffer base address on gen4+
> 
> v2: Adjust relative x-coordinate after linear alignment (vsyrjala)
> v3: Repaint with pokadots (vsyrjala)
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61152
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: stable@vger.kernel.org

Looking good.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915: Handle untiled planes when computing their offsets
  2013-02-21 20:17         ` [Intel-gfx] " Ville Syrjälä
@ 2013-02-21 20:52           ` Daniel Vetter
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Vetter @ 2013-02-21 20:52 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Chris Wilson, intel-gfx, Daniel Vetter, stable

On Thu, Feb 21, 2013 at 10:17:37PM +0200, Ville Syrjälä wrote:
> On Thu, Feb 21, 2013 at 08:04:31PM +0000, Chris Wilson wrote:
> > We trim the fb to fit the CRTC by computing the offset of that CRTC to
> > its nearest tile_row origin. This allows us to use framebuffers that are
> > larger than the CRTC limits without additional work.
> > 
> > However, we failed to compute the offset for a linear framebuffer
> > correctly as we treated its x-advance in whole tiles (instead of the
> > linear increment expected), leaving the CRTC misaligned with its
> > contents.
> > 
> > Fixes regression from commit c2c75131244507c93f812862fdbd4f3a37139401
> > Author: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Date:   Thu Jul 5 12:17:30 2012 +0200
> > 
> >     drm/i915: adjust framebuffer base address on gen4+
> > 
> > v2: Adjust relative x-coordinate after linear alignment (vsyrjala)
> > v3: Repaint with pokadots (vsyrjala)
> > 
> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61152
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Cc: stable@vger.kernel.org
> 
> Looking good.
> 
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Picked up for -fixes, thanks for the patch.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-02-21 20:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-21 14:45 [PATCH] drm/i915: Handle untiled planes when computing their offsets Chris Wilson
2013-02-21 16:55 ` [Intel-gfx] " Ville Syrjälä
2013-02-21 19:05   ` Chris Wilson
2013-02-21 19:54     ` [Intel-gfx] " Ville Syrjälä
2013-02-21 20:03       ` Chris Wilson
2013-02-21 20:04       ` Chris Wilson
2013-02-21 20:17         ` [Intel-gfx] " Ville Syrjälä
2013-02-21 20:52           ` Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.