Re: [PATCH 09/12] drm/i915: Make intel_adjust_tile_offset() work for linear buffers

Sivakumar Thulasimani
2016-05-09T09:19:55Z

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On Tuesday 03 May 2016 09:09 PM, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> To make life less surprising we can make intel_adjust_tile_offset()
> deal with linear buffers as well. Currently it doesn't seem like there's
> a real need for this since only X tiling and NV12 (which would always
> be tiled currently) should need it. But I've used it for some debug
> hacks already so seems like a reasonable thing to have.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 73 ++++++++++++++++++++++++++++--------
> 1 file changed, 57 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 17f9f014e808..ad7c48757ba6 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2347,19 +2347,16 @@ void intel_add_fb_offsets(int *x, int *y,
> }
>
> /*
> - * Adjust the tile offset by moving the difference into
> - * the x/y offsets.
> - *
> * Input tile dimensions and pitch must already be
> * rotated to match x and y, and in pixel units.
> */
> -static u32 intel_adjust_tile_offset(int *x, int *y,
> - unsigned int tile_width,
> - unsigned int tile_height,
> - unsigned int tile_size,
> - unsigned int pitch_tiles,
> - u32 old_offset,
> - u32 new_offset)
> +static u32 _intel_adjust_tile_offset(int *x, int *y,
> + unsigned int tile_width,
> + unsigned int tile_height,
> + unsigned int tile_size,
> + unsigned int pitch_tiles,
> + u32 old_offset,
> + u32 new_offset)
> {
> unsigned int pitch_pixels = pitch_tiles * tile_width;
> unsigned int tiles;
> @@ -2381,6 +2378,50 @@ static u32 intel_adjust_tile_offset(int *x, int *y,
> }
>
> /*
> + * Adjust the tile offset by moving the difference into
> + * the x/y offsets.
> + */
> +static u32 intel_adjust_tile_offset(int *x, int *y,
> + const struct intel_plane_state *state, int plane,
> + u32 old_offset, u32 new_offset)
> +{
> + const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
> + const struct drm_framebuffer *fb = state->base.fb;
> + unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
> + unsigned int rotation = state->base.rotation;
> + unsigned int pitch = intel_fb_pitch(fb, plane, rotation);
> +
> + WARN_ON(new_offset > old_offset);
> +
> + if (fb->modifier[plane] != DRM_FORMAT_MOD_NONE) {
> + unsigned int tile_size, tile_width, tile_height;
> + unsigned int pitch_tiles;
> +
> + tile_size = intel_tile_size(dev_priv);
> + intel_tile_dims(dev_priv, &tile_width, &tile_height,
> + fb->modifier[plane], cpp);
> +
> + if (intel_rotation_90_or_270(rotation)) {
> + pitch_tiles = pitch / tile_height;
> + swap(tile_width, tile_height);
> + } else {
> + pitch_tiles = pitch / (tile_width * cpp);
> + }
> +
> + _intel_adjust_tile_offset(x, y, tile_width, tile_height,
> + tile_size, pitch_tiles,
> + old_offset, new_offset);
> + } else {
> + old_offset += *y * pitch + *x * cpp;
> +
> + *y = (old_offset - new_offset) / pitch;
> + *x = ((old_offset - new_offset) - *y * pitch) / cpp;
> + }
> +
> + return new_offset;
> +}
> +
> +/*
> * Computes the linear offset to the base tile and adjusts
> * x, y. bytes per pixel is assumed to be a power-of-two.
> *
> @@ -2432,9 +2473,9 @@ static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv,
> offset = (tile_rows * pitch_tiles + tiles) * tile_size;
> offset_aligned = offset & ~alignment;
>
> - intel_adjust_tile_offset(x, y, tile_width, tile_height,
> - tile_size, pitch_tiles,
> - offset, offset_aligned);
> + _intel_adjust_tile_offset(x, y, tile_width, tile_height,
> + tile_size, pitch_tiles,
> + offset, offset_aligned);
> } else {
> offset = *y * pitch + *x * cpp;
> offset_aligned = offset & ~alignment;
> @@ -2581,9 +2622,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
> * We only keep the x/y offsets, so push all of the
> * gtt offset into the x/y offsets.
> */
> - intel_adjust_tile_offset(&x, &y, tile_size,
> - tile_width, tile_height, pitch_tiles,
> - gtt_offset_rotated * tile_size, 0);
> + _intel_adjust_tile_offset(&x, &y, tile_size,
> + tile_width, tile_height, pitch_tiles,
> + gtt_offset_rotated * tile_size, 0);
>
> gtt_offset_rotated += rot_info->plane[i].width * rot_info->plane[i].height;
>

--
regards,
Sivakumar Thulasimani