[Intel-gfx] [PATCH] drm/i915: Clean up intel_plane->plane usage

Ville Syrjälä ville.syrjala at linux.intel.com
Fri Sep 18 01:48:30 PDT 2015


On Thu, Sep 17, 2015 at 06:55:21PM -0700, Matt Roper wrote:
> intel_plane->plane has inconsistent meanings across the driver:
>  * For primary planes, intel_plane->plane is usually the pipe number
>    (except for old platforms where it had to be swapped for FBC
>    reasons).
>  * For sprite planes, intel_plane->plane represents the sprite index for
>    the specific CRTC the sprite belongs to (0, 1, 2, ...)
>  * For cursor planes, intel_plane->plane is again the pipe number,
>    but without the FBC swapping on old platforms.
> 
> This overloading of the field can be quite confusing and easily leads to
> bugs due to differences in how the hardware actually gets programmed
> (e.g., SKL code needs to use p->plane + 1 because the hardware expects
> universal plane ID's that include the primary, whereas VLV code needs to
> use just p->plane because hardware expects a sprite index that does not
> include the primary).
> 
> Let's try to clean up this situation by giving intel_plane->plane a
> consistent meaning across all plane types, and then update all uses
> across driver code to use macros to interpret it properly.  The
> following macros should be used in the code where we previously accessed
> p->plane and will do additional plane type checking to help prevent
> misuse:
>  * I915_UNIVERSAL_NUM(p) --- Universal plane ID (primary = 0, sprites
>    start from 1); intended for use in gen9+ code.
>  * I915_I915_PRIMARY_NUM(p) --- Primary plane ID for pre-gen9 platforms;
>    determines whether FBC-related swapping is needed or not.
>  * I915_SPRITE_NUM(p) --- Sprite plane ID (first sprite = 0); intended
>    for use in pre-gen9 code.
> 
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      | 24 ++++++++++++++++++------
>  drivers/gpu/drm/i915/intel_display.c | 12 ++++--------
>  drivers/gpu/drm/i915/intel_pm.c      | 10 +++++-----
>  drivers/gpu/drm/i915/intel_sprite.c  | 13 +++++++------
>  4 files changed, 34 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 3bf8a9b..132fe53 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -131,22 +131,34 @@ enum transcoder {
>  #define transcoder_name(t) ((t) + 'A')
>  
>  /*
> - * This is the maximum (across all platforms) number of planes (primary +
> - * sprites) that can be active at the same time on one pipe.
> - *
> - * This value doesn't count the cursor plane.
> + * I915_MAX_PLANES in the enum below is the maximum (across all platforms)
> + * number of planes per CRTC.  Not all platforms really have this many planes,
> + * which means some arrays of size I915_MAX_PLANES may have unused entries
> + * between the topmost sprite plane and the cursor plane.
>   */
> -#define I915_MAX_PLANES	4
> -
>  enum plane {
>  	PLANE_A = 0,
> +	PLANE_PRIMARY = PLANE_A,
>  	PLANE_B,
>  	PLANE_C,
> +	PLANE_CURSOR,
> +	I915_MAX_PLANES,
>  };

If we're really going to redefine this as a per-pipe thing, then I
think we'd need to rename it. A,B,C have a definite meaning on most of
our hardware, so using it for something else is confusing.

I know that looking for enum plane in the code probably won't give you
a lot of hits, but that's just because we suck and usually use int or
something. I have a patch series in a branch somewhere to clean that
stuff up, but I don't think I posted it to the list so far.

I think it would be better to have a separate per-pipe plane enum.
enum plane_id or something? And maybe store it as plane->id.

>  #define plane_name(p) ((p) + 'A')
>  
>  #define sprite_name(p, s) ((p) * INTEL_INFO(dev)->num_sprites[(p)] + (s) + 'A')
>  
> +#define I915_UNIVERSAL_NUM(p) ( \
> +	WARN_ON(p->base.type == DRM_PLANE_TYPE_CURSOR), \

I don't think that'll fly with SKL. The cursor is just another universal
plane, or well, will be. I think the patch to do that change got stuck
in review or something.

I guess that should be easily fixable by tossing in a !IS_SKL&& once
that patch lands.

> +	p->plane)
> +#define I915_PRIMARY_NUM(p) ( \
> +	WARN_ON(p->base.type != DRM_PLANE_TYPE_PRIMARY), \
> +	(HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) ? \
> +			      !p->pipe : p->pipe)

I'm not sure we want to do this swapping here.

Maybe we'll just want a some kind of
enum plane plane_id_to_plane(crtc, enum plane_id) function.
Or we could just store the enum plane alongside the plane_id in the
plane, and make it clear that it should only be used by pre-SKL
platforms. In theory we could limit it to pre-gen4, or just gmch, but
I think we probably want to share a bunch of the primary plane code
all the way up to BDW, so allowing it's use there seems sane to me.

> +#define I915_SPRITE_NUM(p) ( \
> +	WARN_ON(p->base.type != DRM_PLANE_TYPE_OVERLAY), \
> +	p->plane - 1)
> +
>  enum port {
>  	PORT_A = 0,
>  	PORT_B,
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index fc00867..dab0b71 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11976,16 +11976,14 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
>  			DRM_DEBUG_KMS("%s PLANE:%d plane: %u.%u idx: %d "
>  				"disabled, scaler_id = %d\n",
>  				plane->type == DRM_PLANE_TYPE_CURSOR ? "CURSOR" : "STANDARD",
> -				plane->base.id, intel_plane->pipe,
> -				(crtc->base.primary == plane) ? 0 : intel_plane->plane + 1,
> +				plane->base.id, intel_plane->pipe, intel_plane->plane,
>  				drm_plane_index(plane), state->scaler_id);
>  			continue;
>  		}
>  
>  		DRM_DEBUG_KMS("%s PLANE:%d plane: %u.%u idx: %d enabled",
>  			plane->type == DRM_PLANE_TYPE_CURSOR ? "CURSOR" : "STANDARD",
> -			plane->base.id, intel_plane->pipe,
> -			crtc->base.primary == plane ? 0 : intel_plane->plane + 1,
> +			plane->base.id, intel_plane->pipe, intel_plane->plane,
>  			drm_plane_index(plane));
>  		DRM_DEBUG_KMS("\tFB:%d, fb = %ux%u format = 0x%x",
>  			fb->base.id, fb->width, fb->height, fb->pixel_format);
> @@ -13547,13 +13545,11 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>  		state->scaler_id = -1;
>  	}
>  	primary->pipe = pipe;
> -	primary->plane = pipe;
> +	primary->plane = 0;
>  	primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
>  	primary->check_plane = intel_check_primary_plane;
>  	primary->commit_plane = intel_commit_primary_plane;
>  	primary->disable_plane = intel_disable_primary_plane;
> -	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
> -		primary->plane = !pipe;
>  
>  	if (INTEL_INFO(dev)->gen >= 9) {
>  		intel_primary_formats = skl_primary_formats;
> @@ -13699,7 +13695,7 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
>  	cursor->can_scale = false;
>  	cursor->max_downscale = 1;
>  	cursor->pipe = pipe;
> -	cursor->plane = pipe;
> +	cursor->plane = PLANE_CURSOR;
>  	cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
>  	cursor->check_plane = intel_check_cursor_plane;
>  	cursor->commit_plane = intel_commit_cursor_plane;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 62de97e..9db19f2 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -1131,7 +1131,7 @@ static void vlv_invert_wms(struct intel_crtc *crtc)
>  					wm_state->wm[level].primary;
>  				break;
>  			case DRM_PLANE_TYPE_OVERLAY:
> -				sprite = plane->plane;
> +				sprite = I915_SPRITE_NUM(plane);
>  				wm_state->wm[level].sprite[sprite] = plane->wm.fifo_size -
>  					wm_state->wm[level].sprite[sprite];
>  				break;
> @@ -1195,7 +1195,7 @@ static void vlv_compute_wm(struct intel_crtc *crtc)
>  				wm_state->wm[level].primary = wm;
>  				break;
>  			case DRM_PLANE_TYPE_OVERLAY:
> -				sprite = plane->plane;
> +				sprite = I915_SPRITE_NUM(plane);
>  				wm_state->wm[level].sprite[sprite] = wm;
>  				break;
>  			}
> @@ -1221,7 +1221,7 @@ static void vlv_compute_wm(struct intel_crtc *crtc)
>  					    wm_state->wm[level].primary);
>  			break;
>  		case DRM_PLANE_TYPE_OVERLAY:
> -			sprite = plane->plane;
> +			sprite = I915_SPRITE_NUM(plane);
>  			for (level = 0; level < wm_state->num_levels; level++)
>  				wm_state->sr[level].plane =
>  					min(wm_state->sr[level].plane,
> @@ -1257,7 +1257,7 @@ static void vlv_pipe_set_fifo_size(struct intel_crtc *crtc)
>  
>  		if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
>  			sprite0_start = plane->wm.fifo_size;
> -		else if (plane->plane == 0)
> +		else if (I915_SPRITE_NUM(plane) == 0)
>  			sprite1_start = sprite0_start + plane->wm.fifo_size;
>  		else
>  			fifo_size = sprite1_start + plane->wm.fifo_size;
> @@ -4076,7 +4076,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
>  			plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, 0);
>  			break;
>  		case DRM_PLANE_TYPE_OVERLAY:
> -			sprite = plane->plane;
> +			sprite = I915_SPRITE_NUM(plane);
>  			plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, sprite + 1);
>  			break;
>  		}
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 4d27243..11ca40a 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -180,7 +180,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
>  	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
>  	const int pipe = intel_plane->pipe;
> -	const int plane = intel_plane->plane + 1;
> +	const int plane = I915_UNIVERSAL_NUM(intel_plane);
>  	u32 plane_ctl, stride_div, stride;
>  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  	const struct drm_intel_sprite_colorkey *key =
> @@ -280,7 +280,7 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_plane *intel_plane = to_intel_plane(dplane);
>  	const int pipe = intel_plane->pipe;
> -	const int plane = intel_plane->plane + 1;
> +	const int plane = I915_UNIVERSAL_NUM(intel_plane);
>  
>  	I915_WRITE(PLANE_CTL(pipe, plane), 0);
>  
> @@ -294,7 +294,7 @@ static void
>  chv_update_csc(struct intel_plane *intel_plane, uint32_t format)
>  {
>  	struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private;
> -	int plane = intel_plane->plane;
> +	int plane = I915_SPRITE_NUM(intel_plane);
>  
>  	/* Seems RGB data bypasses the CSC always */
>  	if (!format_is_yuv(format))
> @@ -342,7 +342,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
>  	struct intel_plane *intel_plane = to_intel_plane(dplane);
>  	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
>  	int pipe = intel_plane->pipe;
> -	int plane = intel_plane->plane;
> +	int plane = I915_SPRITE_NUM(intel_plane);
>  	u32 sprctl;
>  	unsigned long sprsurf_offset, linear_offset;
>  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> @@ -461,7 +461,7 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_plane *intel_plane = to_intel_plane(dplane);
>  	int pipe = intel_plane->pipe;
> -	int plane = intel_plane->plane;
> +	int plane = I915_SPRITE_NUM(intel_plane);
>  
>  	I915_WRITE(SPCNTR(pipe, plane), 0);
>  
> @@ -1121,8 +1121,9 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>  		return -ENODEV;
>  	}
>  
> +	/* primary = 0, sprites start from 1 */
> +	intel_plane->plane = plane + 1;
>  	intel_plane->pipe = pipe;
> -	intel_plane->plane = plane;
>  	intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane);
>  	intel_plane->check_plane = intel_check_sprite_plane;
>  	intel_plane->commit_plane = intel_commit_sprite_plane;
> -- 
> 2.1.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC


More information about the Intel-gfx mailing list