diff mbox

[9/9] drm/i915: Add windowing for primary planes on gen2/3 and chv

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

Commit Message

Ville Syrjälä Oct. 11, 2017, 4:04 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Plane B and C (note that we don't actually expose plane C currently)
on gen2/3 have a window generator, as does the primary plane on CHV
pipe B. So let's allow positioning of these planes freely within the
pipe source area.

Plane A on gen2/3 seems to have some kind of partial window generator
which would allow you to cut the plane off midway through the scanout,
but it would still have to start at the top-left corner of the pipe,
and it would have to be full width. That's doesn't sound all that
useful, so for simplicity let's just keep to the idea that plane A
has to be fullscreen.

Gen4 removed the plane A/B windowing support entirely, and it wasn't
reintroduced until SKL (apart from the CHV pipe B special case).

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

Comments

Daniel Vetter Oct. 12, 2017, 7:42 p.m. UTC | #1
On Wed, Oct 11, 2017 at 07:04:55PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Plane B and C (note that we don't actually expose plane C currently)
> on gen2/3 have a window generator, as does the primary plane on CHV
> pipe B. So let's allow positioning of these planes freely within the
> pipe source area.
> 
> Plane A on gen2/3 seems to have some kind of partial window generator
> which would allow you to cut the plane off midway through the scanout,
> but it would still have to start at the top-left corner of the pipe,
> and it would have to be full width. That's doesn't sound all that
> useful, so for simplicity let's just keep to the idea that plane A
> has to be fullscreen.
> 
> Gen4 removed the plane A/B windowing support entirely, and it wasn't
> reintroduced until SKL (apart from the CHV pipe B special case).
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

Hm, not really liking to r-b this since I don't have a metric pile of igts
switching from skip -> pass due to this. Which is because:

- no chv or gen2/3 in our shards
- and I think still no good primary plane position testcases in igt

I'd want both before I rb this (and chv in CI shards would be kinda neat,
so perhaps start working on Jani about this).
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_display.c | 43 ++++++++++++++++++++++--------------
>  1 file changed, 27 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 622b487629d7..595b46255dd2 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3236,6 +3236,10 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  	i915_reg_t reg = DSPCNTR(plane_id);
>  	int x = plane_state->main.x;
>  	int y = plane_state->main.y;
> +	int crtc_x = plane_state->base.dst.x1;
> +	int crtc_y = plane_state->base.dst.y1;
> +	int crtc_w = drm_rect_width(&plane_state->base.dst);
> +	int crtc_h = drm_rect_height(&plane_state->base.dst);
>  	unsigned long irqflags;
>  
>  	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
> @@ -3251,18 +3255,18 @@ static void i9xx_update_plane(struct intel_plane *plane,
>  	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>  
>  	if (INTEL_GEN(dev_priv) < 4) {
> -		/* pipesrc and dspsize control the size that is scaled from,
> -		 * which should always be the user's requested size.
> +		/*
> +		 * PLANE_A doesn't actually have a full window
> +		 * generator but let's assume we still need to
> +		 * program whatever is there.
>  		 */
> +		I915_WRITE_FW(DSPPOS(plane_id), (crtc_y << 16) | crtc_x);
>  		I915_WRITE_FW(DSPSIZE(plane_id),
> -			      ((crtc_state->pipe_src_h - 1) << 16) |
> -			      (crtc_state->pipe_src_w - 1));
> -		I915_WRITE_FW(DSPPOS(plane_id), 0);
> +			      ((crtc_h - 1) << 16) | (crtc_w - 1));
>  	} else if (IS_CHERRYVIEW(dev_priv) && plane_id == PLANE_B) {
> +		I915_WRITE_FW(PRIMPOS(plane_id), (crtc_y << 16) | crtc_x);
>  		I915_WRITE_FW(PRIMSIZE(plane_id),
> -			      ((crtc_state->pipe_src_h - 1) << 16) |
> -			      (crtc_state->pipe_src_w - 1));
> -		I915_WRITE_FW(PRIMPOS(plane_id), 0);
> +			      ((crtc_h - 1) << 16) | (crtc_w - 1));
>  		I915_WRITE_FW(PRIMCNSTALPHA(plane_id), 0);
>  	}
>  
> @@ -12737,6 +12741,15 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state
>  	return max_scale;
>  }
>  
> +static bool intel_primary_plane_has_windowing(struct intel_plane *plane)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +
> +	return INTEL_GEN(dev_priv) >= 9 ||
> +		(IS_CHERRYVIEW(dev_priv) && plane->plane == PLANE_B) ||
> +		(INTEL_GEN(dev_priv) < 4 && plane->plane != PLANE_A);
> +}
> +
>  static int
>  intel_check_primary_plane(struct intel_plane *plane,
>  			  struct intel_crtc_state *crtc_state,
> @@ -12746,16 +12759,14 @@ intel_check_primary_plane(struct intel_plane *plane,
>  	struct drm_crtc *crtc = state->base.crtc;
>  	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> -	bool can_position = false;
> +	bool can_position = intel_primary_plane_has_windowing(plane);
>  	int ret;
>  
> -	if (INTEL_GEN(dev_priv) >= 9) {
> -		/* use scaler when colorkey is not required */
> -		if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
> -			min_scale = 1;
> -			max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
> -		}
> -		can_position = true;
> +	/* use scaler when colorkey is not required */
> +	if (INTEL_GEN(dev_priv) >= 9 &&
> +	    state->ckey.flags == I915_SET_COLORKEY_NONE) {
> +		min_scale = 1;
> +		max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
>  	}
>  
>  	ret = drm_plane_helper_check_state(&state->base,
> -- 
> 2.13.6
> 
> _______________________________________________
> 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 622b487629d7..595b46255dd2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3236,6 +3236,10 @@  static void i9xx_update_plane(struct intel_plane *plane,
 	i915_reg_t reg = DSPCNTR(plane_id);
 	int x = plane_state->main.x;
 	int y = plane_state->main.y;
+	int crtc_x = plane_state->base.dst.x1;
+	int crtc_y = plane_state->base.dst.y1;
+	int crtc_w = drm_rect_width(&plane_state->base.dst);
+	int crtc_h = drm_rect_height(&plane_state->base.dst);
 	unsigned long irqflags;
 
 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
@@ -3251,18 +3255,18 @@  static void i9xx_update_plane(struct intel_plane *plane,
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	if (INTEL_GEN(dev_priv) < 4) {
-		/* pipesrc and dspsize control the size that is scaled from,
-		 * which should always be the user's requested size.
+		/*
+		 * PLANE_A doesn't actually have a full window
+		 * generator but let's assume we still need to
+		 * program whatever is there.
 		 */
+		I915_WRITE_FW(DSPPOS(plane_id), (crtc_y << 16) | crtc_x);
 		I915_WRITE_FW(DSPSIZE(plane_id),
-			      ((crtc_state->pipe_src_h - 1) << 16) |
-			      (crtc_state->pipe_src_w - 1));
-		I915_WRITE_FW(DSPPOS(plane_id), 0);
+			      ((crtc_h - 1) << 16) | (crtc_w - 1));
 	} else if (IS_CHERRYVIEW(dev_priv) && plane_id == PLANE_B) {
+		I915_WRITE_FW(PRIMPOS(plane_id), (crtc_y << 16) | crtc_x);
 		I915_WRITE_FW(PRIMSIZE(plane_id),
-			      ((crtc_state->pipe_src_h - 1) << 16) |
-			      (crtc_state->pipe_src_w - 1));
-		I915_WRITE_FW(PRIMPOS(plane_id), 0);
+			      ((crtc_h - 1) << 16) | (crtc_w - 1));
 		I915_WRITE_FW(PRIMCNSTALPHA(plane_id), 0);
 	}
 
@@ -12737,6 +12741,15 @@  skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state
 	return max_scale;
 }
 
+static bool intel_primary_plane_has_windowing(struct intel_plane *plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+
+	return INTEL_GEN(dev_priv) >= 9 ||
+		(IS_CHERRYVIEW(dev_priv) && plane->plane == PLANE_B) ||
+		(INTEL_GEN(dev_priv) < 4 && plane->plane != PLANE_A);
+}
+
 static int
 intel_check_primary_plane(struct intel_plane *plane,
 			  struct intel_crtc_state *crtc_state,
@@ -12746,16 +12759,14 @@  intel_check_primary_plane(struct intel_plane *plane,
 	struct drm_crtc *crtc = state->base.crtc;
 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
-	bool can_position = false;
+	bool can_position = intel_primary_plane_has_windowing(plane);
 	int ret;
 
-	if (INTEL_GEN(dev_priv) >= 9) {
-		/* use scaler when colorkey is not required */
-		if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
-			min_scale = 1;
-			max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
-		}
-		can_position = true;
+	/* use scaler when colorkey is not required */
+	if (INTEL_GEN(dev_priv) >= 9 &&
+	    state->ckey.flags == I915_SET_COLORKEY_NONE) {
+		min_scale = 1;
+		max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
 	}
 
 	ret = drm_plane_helper_check_state(&state->base,