[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