diff mbox

[13/15] drm/i915: Handle fb offset and src coordinates for cursors

Message ID 20170327185546.2977-14-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ville Syrjälä March 27, 2017, 6:55 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The cursor plane doesn't have any kind of source offset register, so
the only form of panning possible is via a the base address register.
The alignment required by CURBASE ranges from 32B to 16KiB depending
on the platform. Let's make sure the user didn't ask for something
we can't do.

Obviously this is impossible to hit via the legacy cursor ioctl since
the src offsets are always 0, but via the plane/atomic ioctls the user
can ask for pretty much anything so we have to deal with this.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

Comments

Imre Deak May 5, 2017, 8:53 p.m. UTC | #1
On Mon, Mar 27, 2017 at 09:55:44PM +0300, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> The cursor plane doesn't have any kind of source offset register, so
> the only form of panning possible is via a the base address register.
> The alignment required by CURBASE ranges from 32B to 16KiB depending
> on the platform. Let's make sure the user didn't ask for something
> we can't do.
> 
> Obviously this is impossible to hit via the legacy cursor ioctl since
> the src offsets are always 0, but via the plane/atomic ioctls the user
> can ask for pretty much anything so we have to deal with this.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_display.c | 27 +++++++++++++++++++++++++--
>  1 file changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 3a1d7d6530ec..420d306e31c9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2396,11 +2396,17 @@ u32 intel_compute_tile_offset(int *x, int *y,
>  			      const struct intel_plane_state *state,
>  			      int plane)
>  {
> -	const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
> +	struct intel_plane *intel_plane = to_intel_plane(state->base.plane);
> +	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
>  	const struct drm_framebuffer *fb = state->base.fb;
>  	unsigned int rotation = state->base.rotation;
>  	int pitch = intel_fb_pitch(fb, plane, rotation);
> -	u32 alignment = intel_surf_alignment(fb, plane);
> +	u32 alignment;
> +
> +	if (intel_plane->id == PLANE_CURSOR)
> +		alignment = intel_cursor_alignment(dev_priv);
> +	else
> +		alignment = intel_surf_alignment(fb, plane);
>  
>  	return _intel_compute_tile_offset(dev_priv, x, y, fb, plane, pitch,
>  					  rotation, alignment);
> @@ -9149,6 +9155,8 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
>  	else
>  		base = intel_plane_ggtt_offset(plane_state);
>  
> +	base += plane_state->main.offset;
> +
>  	/* ILK+ do this automagically */
>  	if (HAS_GMCH_DISPLAY(dev_priv) &&
>  	    plane_state->base.rotation & DRM_ROTATE_180)
> @@ -9194,6 +9202,8 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
>  			      struct intel_plane_state *plane_state)
>  {
>  	const struct drm_framebuffer *fb = plane_state->base.fb;
> +	int src_x, src_y;
> +	u32 offset;
>  	int ret;
>  
>  	ret = drm_plane_helper_check_state(&plane_state->base,
> @@ -9212,6 +9222,19 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
>  		return -EINVAL;
>  	}
>  
> +	src_x = plane_state->base.src_x >> 16;
> +	src_y = plane_state->base.src_y >> 16;
> +
> +	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
> +	offset = intel_compute_tile_offset(&src_x, &src_y, plane_state, 0);
> +
> +	if (src_x != 0 || src_y != 0) {
> +		DRM_DEBUG_KMS("Arbitrary cursor panning not supported\n");
> +		return -EINVAL;
> +	}
> +
> +	plane_state->main.offset = offset;
> +
>  	return 0;
>  }
>  
> -- 
> 2.10.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3a1d7d6530ec..420d306e31c9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2396,11 +2396,17 @@  u32 intel_compute_tile_offset(int *x, int *y,
 			      const struct intel_plane_state *state,
 			      int plane)
 {
-	const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
+	struct intel_plane *intel_plane = to_intel_plane(state->base.plane);
+	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
 	const struct drm_framebuffer *fb = state->base.fb;
 	unsigned int rotation = state->base.rotation;
 	int pitch = intel_fb_pitch(fb, plane, rotation);
-	u32 alignment = intel_surf_alignment(fb, plane);
+	u32 alignment;
+
+	if (intel_plane->id == PLANE_CURSOR)
+		alignment = intel_cursor_alignment(dev_priv);
+	else
+		alignment = intel_surf_alignment(fb, plane);
 
 	return _intel_compute_tile_offset(dev_priv, x, y, fb, plane, pitch,
 					  rotation, alignment);
@@ -9149,6 +9155,8 @@  static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
 	else
 		base = intel_plane_ggtt_offset(plane_state);
 
+	base += plane_state->main.offset;
+
 	/* ILK+ do this automagically */
 	if (HAS_GMCH_DISPLAY(dev_priv) &&
 	    plane_state->base.rotation & DRM_ROTATE_180)
@@ -9194,6 +9202,8 @@  static int intel_check_cursor(struct intel_crtc_state *crtc_state,
 			      struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
+	int src_x, src_y;
+	u32 offset;
 	int ret;
 
 	ret = drm_plane_helper_check_state(&plane_state->base,
@@ -9212,6 +9222,19 @@  static int intel_check_cursor(struct intel_crtc_state *crtc_state,
 		return -EINVAL;
 	}
 
+	src_x = plane_state->base.src_x >> 16;
+	src_y = plane_state->base.src_y >> 16;
+
+	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
+	offset = intel_compute_tile_offset(&src_x, &src_y, plane_state, 0);
+
+	if (src_x != 0 || src_y != 0) {
+		DRM_DEBUG_KMS("Arbitrary cursor panning not supported\n");
+		return -EINVAL;
+	}
+
+	plane_state->main.offset = offset;
+
 	return 0;
 }