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

Daniel Vetter daniel at ffwll.ch
Thu Oct 12 19:42:45 UTC 2017


On Wed, Oct 11, 2017 at 07:04:55PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala at 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 at 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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the Intel-gfx mailing list