[Intel-gfx] [PATCH 3/7] drm/i915: Have plane->get_hw_state() return the current pipe

Mika Kahola mika.kahola at intel.com
Fri Jun 1 08:38:56 UTC 2018


On Tue, 2018-01-30 at 22:38 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> Like we do for encoder let's make the plane->get_hw_state() return
> the pipe to which the plane is currently attached. We don't currently
> allow planes to move between the pipes, but perhaps one day we will.
> 
> In either case this makes the code more uniform and perhaps makes
> intel_plane_mapping_ok() slightly more clear.
> 
> Note that for i965 and g4x planes A and B still have pipe select bits
> but they're hardwired to pipe A and B respectively. This means we can
> safely interpret those bits just like on gen2/3. This allows the
> same readout code work for plane C (which can still be assigned
> to eiter pipe on i965) should we ever expose it.
> 
> g4x no longer allows moving the cursor planes between the pipes,
> but the pipe select bits can still be set in the register. Thus
> we have to ignore those bits. OTOH i965 still allows the cursors
> to move between pipes thus we have to trust the bits there.
> 
Reviewed-by: Mika Kahola <mika.kahola at intel.com>

> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h      |  2 +
>  drivers/gpu/drm/i915/intel_display.c | 71
> ++++++++++++++++++++++++++----------
>  drivers/gpu/drm/i915/intel_drv.h     |  4 +-
>  drivers/gpu/drm/i915/intel_sprite.c  | 40 ++++++++++++--------
>  4 files changed, 79 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index 64933fd74cb6..ebb41f279134 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -5908,6 +5908,8 @@ enum {
>  #define   CURSOR_MODE_128_ARGB_AX ((1 << 5) |
> CURSOR_MODE_128_32B_AX)
>  #define   CURSOR_MODE_256_ARGB_AX ((1 << 5) |
> CURSOR_MODE_256_32B_AX)
>  #define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
> +#define   MCURSOR_PIPE_SELECT_MASK	(0x3 << 28)
> +#define   MCURSOR_PIPE_SELECT_SHIFT	28
>  #define   MCURSOR_PIPE_SELECT(pipe)	((pipe) << 28)
>  #define   MCURSOR_GAMMA_ENABLE  (1 << 26)
>  #define   CURSOR_ROTATE_180	(1<<15)
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 6ffc1d088d7a..feae6bd51a44 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1224,7 +1224,10 @@ void assert_pipe(struct drm_i915_private
> *dev_priv,
>  
>  static void assert_plane(struct intel_plane *plane, bool state)
>  {
> -	bool cur_state = plane->get_hw_state(plane);
> +	enum pipe pipe;
> +	bool cur_state;
> +
> +	cur_state = plane->get_hw_state(plane, &pipe);
>  
>  	I915_STATE_WARN(cur_state != state,
>  			"%s assertion failure (expected %s, current
> %s)\n",
> @@ -3326,24 +3329,33 @@ static void i9xx_disable_plane(struct
> intel_plane *plane,
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
>  
> -static bool i9xx_plane_get_hw_state(struct intel_plane *plane)
> +static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
> +				    enum pipe *pipe)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane-
> >base.dev);
>  	enum intel_display_power_domain power_domain;
>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> -	enum pipe pipe = plane->pipe;
>  	bool ret;
> +	u32 val;
>  
>  	/*
>  	 * Not 100% correct for planes that can move between pipes,
>  	 * but that's only the case for gen2-4 which don't have any
>  	 * display power wells.
>  	 */
> -	power_domain = POWER_DOMAIN_PIPE(pipe);
> +	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
>  	if (!intel_display_power_get_if_enabled(dev_priv,
> power_domain))
>  		return false;
>  
> -	ret = I915_READ(DSPCNTR(i9xx_plane)) & DISPLAY_PLANE_ENABLE;
> +	val = I915_READ(DSPCNTR(i9xx_plane));
> +
> +	ret = val & DISPLAY_PLANE_ENABLE;
> +
> +	if (INTEL_GEN(dev_priv) >= 5)
> +		*pipe = plane->pipe;
> +	else
> +		*pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
> +			DISPPLANE_SEL_PIPE_SHIFT;
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
> @@ -7482,16 +7494,18 @@ i9xx_get_initial_plane_config(struct
> intel_crtc *crtc,
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_plane *plane = to_intel_plane(crtc-
> >base.primary);
>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> -	enum pipe pipe = crtc->pipe;
> +	enum pipe pipe;
>  	u32 val, base, offset;
>  	int fourcc, pixel_format;
>  	unsigned int aligned_height;
>  	struct drm_framebuffer *fb;
>  	struct intel_framebuffer *intel_fb;
>  
> -	if (!plane->get_hw_state(plane))
> +	if (!plane->get_hw_state(plane, &pipe))
>  		return;
>  
> +	WARN_ON(pipe != crtc->pipe);
> +
>  	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
>  	if (!intel_fb) {
>  		DRM_DEBUG_KMS("failed to alloc fb\n");
> @@ -8512,16 +8526,18 @@ skylake_get_initial_plane_config(struct
> intel_crtc *crtc,
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_plane *plane = to_intel_plane(crtc-
> >base.primary);
>  	enum plane_id plane_id = plane->id;
> -	enum pipe pipe = crtc->pipe;
> +	enum pipe pipe;
>  	u32 val, base, offset, stride_mult, tiling, alpha;
>  	int fourcc, pixel_format;
>  	unsigned int aligned_height;
>  	struct drm_framebuffer *fb;
>  	struct intel_framebuffer *intel_fb;
>  
> -	if (!plane->get_hw_state(plane))
> +	if (!plane->get_hw_state(plane, &pipe))
>  		return;
>  
> +	WARN_ON(pipe != crtc->pipe);
> +
>  	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
>  	if (!intel_fb) {
>  		DRM_DEBUG_KMS("failed to alloc fb\n");
> @@ -9502,7 +9518,8 @@ static void i845_disable_cursor(struct
> intel_plane *plane,
>  	i845_update_cursor(plane, NULL, NULL);
>  }
>  
> -static bool i845_cursor_get_hw_state(struct intel_plane *plane)
> +static bool i845_cursor_get_hw_state(struct intel_plane *plane,
> +				     enum pipe *pipe)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane-
> >base.dev);
>  	enum intel_display_power_domain power_domain;
> @@ -9514,6 +9531,8 @@ static bool i845_cursor_get_hw_state(struct
> intel_plane *plane)
>  
>  	ret = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
>  
> +	*pipe = PIPE_A;
> +
>  	intel_display_power_put(dev_priv, power_domain);
>  
>  	return ret;
> @@ -9713,23 +9732,32 @@ static void i9xx_disable_cursor(struct
> intel_plane *plane,
>  	i9xx_update_cursor(plane, NULL, NULL);
>  }
>  
> -static bool i9xx_cursor_get_hw_state(struct intel_plane *plane)
> +static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
> +				     enum pipe *pipe)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane-
> >base.dev);
>  	enum intel_display_power_domain power_domain;
> -	enum pipe pipe = plane->pipe;
>  	bool ret;
> +	u32 val;
>  
>  	/*
>  	 * Not 100% correct for planes that can move between pipes,
>  	 * but that's only the case for gen2-3 which don't have any
>  	 * display power wells.
>  	 */
> -	power_domain = POWER_DOMAIN_PIPE(pipe);
> +	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
>  	if (!intel_display_power_get_if_enabled(dev_priv,
> power_domain))
>  		return false;
>  
> -	ret = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
> +	val = I915_READ(CURCNTR(plane->pipe));
> +
> +	ret = val & CURSOR_MODE;
> +
> +	if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
> +		*pipe = plane->pipe;
> +	else
> +		*pipe = (val & MCURSOR_PIPE_SELECT_MASK) >>
> +			MCURSOR_PIPE_SELECT_SHIFT;
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
> @@ -14755,12 +14783,12 @@ void i830_disable_pipe(struct
> drm_i915_private *dev_priv, enum pipe pipe)
>  static bool intel_plane_mapping_ok(struct intel_crtc *crtc,
>  				   struct intel_plane *plane)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> -	u32 val = I915_READ(DSPCNTR(i9xx_plane));
> +	enum pipe pipe;
>  
> -	return (val & DISPLAY_PLANE_ENABLE) == 0 ||
> -		(val & DISPPLANE_SEL_PIPE_MASK) ==
> DISPPLANE_SEL_PIPE(crtc->pipe);
> +	if (!plane->get_hw_state(plane, &pipe))
> +		return true;
> +
> +	return pipe == crtc->pipe;
>  }
>  
>  static void
> @@ -14959,7 +14987,10 @@ static void readout_plane_state(struct
> intel_crtc *crtc)
>  	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
>  		struct intel_plane_state *plane_state =
>  			to_intel_plane_state(plane->base.state);
> -		bool visible = plane->get_hw_state(plane);
> +		enum pipe pipe;
> +		bool visible;
> +
> +		visible = plane->get_hw_state(plane, &pipe);
>  
>  		intel_set_plane_visible(crtc_state, plane_state,
> visible);
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 8335d27f4156..d80eae7a69ba 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -946,7 +946,7 @@ struct intel_plane {
>  			     const struct intel_plane_state
> *plane_state);
>  	void (*disable_plane)(struct intel_plane *plane,
>  			      struct intel_crtc *crtc);
> -	bool (*get_hw_state)(struct intel_plane *plane);
> +	bool (*get_hw_state)(struct intel_plane *plane, enum pipe
> *pipe);
>  	int (*check_plane)(struct intel_plane *plane,
>  			   struct intel_crtc_state *crtc_state,
>  			   struct intel_plane_state *state);
> @@ -2023,7 +2023,7 @@ void skl_update_plane(struct intel_plane
> *plane,
>  		      const struct intel_crtc_state *crtc_state,
>  		      const struct intel_plane_state *plane_state);
>  void skl_disable_plane(struct intel_plane *plane, struct intel_crtc
> *crtc);
> -bool skl_plane_get_hw_state(struct intel_plane *plane);
> +bool skl_plane_get_hw_state(struct intel_plane *plane, enum pipe
> *pipe);
>  bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
>  		       enum pipe pipe, enum plane_id plane_id);
>  
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> b/drivers/gpu/drm/i915/intel_sprite.c
> index aea21a9abf6c..86a31535fce3 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -326,19 +326,21 @@ skl_disable_plane(struct intel_plane *plane,
> struct intel_crtc *crtc)
>  }
>  
>  bool
> -skl_plane_get_hw_state(struct intel_plane *plane)
> +skl_plane_get_hw_state(struct intel_plane *plane,
> +		       enum pipe *pipe)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane-
> >base.dev);
>  	enum intel_display_power_domain power_domain;
>  	enum plane_id plane_id = plane->id;
> -	enum pipe pipe = plane->pipe;
>  	bool ret;
>  
> -	power_domain = POWER_DOMAIN_PIPE(pipe);
> +	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
>  	if (!intel_display_power_get_if_enabled(dev_priv,
> power_domain))
>  		return false;
>  
> -	ret = I915_READ(PLANE_CTL(pipe, plane_id)) &
> PLANE_CTL_ENABLE;
> +	ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) &
> PLANE_CTL_ENABLE;
> +
> +	*pipe = plane->pipe;
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
> @@ -523,19 +525,21 @@ vlv_disable_plane(struct intel_plane *plane,
> struct intel_crtc *crtc)
>  }
>  
>  static bool
> -vlv_plane_get_hw_state(struct intel_plane *plane)
> +vlv_plane_get_hw_state(struct intel_plane *plane,
> +		       enum pipe *pipe)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane-
> >base.dev);
>  	enum intel_display_power_domain power_domain;
>  	enum plane_id plane_id = plane->id;
> -	enum pipe pipe = plane->pipe;
>  	bool ret;
>  
> -	power_domain = POWER_DOMAIN_PIPE(pipe);
> +	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
>  	if (!intel_display_power_get_if_enabled(dev_priv,
> power_domain))
>  		return false;
>  
> -	ret = I915_READ(SPCNTR(pipe, plane_id)) & SP_ENABLE;
> +	ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
> +
> +	*pipe = plane->pipe;
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
> @@ -683,18 +687,20 @@ ivb_disable_plane(struct intel_plane *plane,
> struct intel_crtc *crtc)
>  }
>  
>  static bool
> -ivb_plane_get_hw_state(struct intel_plane *plane)
> +ivb_plane_get_hw_state(struct intel_plane *plane,
> +		       enum pipe *pipe)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane-
> >base.dev);
>  	enum intel_display_power_domain power_domain;
> -	enum pipe pipe = plane->pipe;
>  	bool ret;
>  
> -	power_domain = POWER_DOMAIN_PIPE(pipe);
> +	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
>  	if (!intel_display_power_get_if_enabled(dev_priv,
> power_domain))
>  		return false;
>  
> -	ret =  I915_READ(SPRCTL(pipe)) & SPRITE_ENABLE;
> +	ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
> +
> +	*pipe = plane->pipe;
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
> @@ -833,18 +839,20 @@ g4x_disable_plane(struct intel_plane *plane,
> struct intel_crtc *crtc)
>  }
>  
>  static bool
> -g4x_plane_get_hw_state(struct intel_plane *plane)
> +g4x_plane_get_hw_state(struct intel_plane *plane,
> +		       enum pipe *pipe)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane-
> >base.dev);
>  	enum intel_display_power_domain power_domain;
> -	enum pipe pipe = plane->pipe;
>  	bool ret;
>  
> -	power_domain = POWER_DOMAIN_PIPE(pipe);
> +	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
>  	if (!intel_display_power_get_if_enabled(dev_priv,
> power_domain))
>  		return false;
>  
> -	ret = I915_READ(DVSCNTR(pipe)) & DVS_ENABLE;
> +	ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
> +
> +	*pipe = plane->pipe;
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
-- 
Mika Kahola - Intel OTC



More information about the Intel-gfx mailing list