[Intel-gfx] [PATCH] drm/i915: Don't clobber plane state on internal disables

Daniel Vetter daniel at ffwll.ch
Thu Mar 5 04:33:53 PST 2015


On Wed, Mar 04, 2015 at 10:49:04AM -0800, Matt Roper wrote:
> We need to disable all sprite planes when disabling the CRTC.  We had
> been using the top-level atomic 'disable' entrypoint to accomplish this,
> which was wrong.  Not only can this lead to various locking issues, it
> also modifies the actual plane state, making it impossible to restore
> the plane properly later.  For example, a DPMS off followed by a DPMS on
> will result in any sprite planes in use not being restored properly.
> 
> The proper solution here is to call directly into our 'commit plane'
> hook with a copy of the plane's current state that has 'visible' set to
> false.  Committing this dummy state will turn off the plane, but will
> not touch the actual plane->state pointer, allowing us to properly
> restore the plane state later.
> 
> Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> ---
> This was a pretty big problem so I suspect this is probably tied to some of our
> existing bugzilla's but I'm not sure exactly which ones.  It seems that we lack
> an i-g-t test for plane status across DPMS, so I'll send along a new i-g-t test
> for that shortly.
> 
>  drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 92cb2ff..6277701 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4201,6 +4201,24 @@ static void intel_enable_sprite_planes(struct drm_crtc *crtc)
>  	}
>  }
>  
> +/*
> + * Disable a plane internally without actually modifying the plane's state.
> + * This will allow us to easily restore the plane later by just reprogramming
> + * its state.
> + */
> +static void disable_plane_internal(struct drm_plane *plane)
> +{
> +	struct intel_plane *intel_plane = to_intel_plane(plane);
> +	struct drm_plane_state *state =
> +		plane->funcs->atomic_duplicate_state(plane);
> +	struct intel_plane_state *intel_state = to_intel_plane_state(state);
> +
> +	intel_state->visible = false;
> +	intel_plane->commit_plane(plane, intel_state);
> +
> +	intel_plane_destroy_state(plane, state);

I wonder whether long-term we should do a full atomic commit including the
begin/end dance here. But this is more than good enough for now, so merged
to dinq.

Thanks, Daniel

> +}
> +
>  static void intel_disable_sprite_planes(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
> @@ -4210,8 +4228,8 @@ static void intel_disable_sprite_planes(struct drm_crtc *crtc)
>  
>  	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
>  		intel_plane = to_intel_plane(plane);
> -		if (intel_plane->pipe == pipe)
> -			plane->funcs->disable_plane(plane);
> +		if (plane->fb && intel_plane->pipe == pipe)
> +			disable_plane_internal(plane);
>  	}
>  }
>  
> -- 
> 1.8.5.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


More information about the Intel-gfx mailing list