[Intel-gfx] [PATCH 5/6] drm/i915/gen9: Get rid of redundant watermark values

Paulo Zanoni paulo.r.zanoni at intel.com
Wed Oct 5 21:44:04 UTC 2016


Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> Now that we've make skl_wm_levels make a little more sense, we can
> remove all of the redundant wm information. Up until now we'd been
> storing two copies of all of the skl watermarks: one being the
> skl_pipe_wm structs, the other being the global wm struct in
> drm_i915_private containing the raw register values. This is
> confusing
> and problematic, since it means we're prone to accidentally letting
> the
> two copies go out of sync. So, get rid of all of the functions
> responsible for computing the register values and just use a single
> helper, skl_write_wm_level(), to convert and write the new watermarks
> on
> the fly.

I like the direction of this patch too, but there are some small
possible problems. See below.


> 
> Signed-off-by: Lyude <cpaul at redhat.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Cc: Matt Roper <matthew.d.roper at intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   2 -
>  drivers/gpu/drm/i915/intel_display.c |  14 ++-
>  drivers/gpu/drm/i915/intel_drv.h     |   6 +-
>  drivers/gpu/drm/i915/intel_pm.c      | 203 ++++++++++++-------------
> ----------
>  drivers/gpu/drm/i915/intel_sprite.c  |   8 +-
>  5 files changed, 88 insertions(+), 145 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 0f97d43..63519ac 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1643,8 +1643,6 @@ struct skl_ddb_allocation {
>  struct skl_wm_values {
>  	unsigned dirty_pipes;
>  	struct skl_ddb_allocation ddb;
> -	uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> -	uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
>  };
>  
>  struct skl_wm_level {
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index dd15ae2..c580d3d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3378,6 +3378,8 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> >base.crtc);
>  	struct drm_framebuffer *fb = plane_state->base.fb;
>  	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
> +	const struct skl_plane_wm *p_wm =
> +		&crtc_state->wm.skl.optimal.planes[0];

I wish someone would do a patch to convert all these hardcoded values
to PLANE_X, and convert "int"s  to "enum plane"s everywhere.


>  	int pipe = intel_crtc->pipe;
>  	u32 plane_ctl;
>  	unsigned int rotation = plane_state->base.rotation;
> @@ -3414,7 +3416,7 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
>  	intel_crtc->adjusted_y = src_y;
>  
>  	if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base))
> -		skl_write_plane_wm(intel_crtc, wm, 0);
> +		skl_write_plane_wm(intel_crtc, p_wm, &wm->ddb, 0);
>  
>  	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
>  	I915_WRITE(PLANE_OFFSET(pipe, 0), (src_y << 16) | src_x);
> @@ -3448,6 +3450,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> +	const struct skl_plane_wm *p_wm = &cstate-
> >wm.skl.optimal.planes[0];
>  	int pipe = intel_crtc->pipe;
>  
>  	/*
> @@ -3455,7 +3459,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
>  	 * plane's visiblity isn't actually changing neither is its
> watermarks.
>  	 */
>  	if (!crtc->primary->state->visible)
> -		skl_write_plane_wm(intel_crtc, &dev_priv-
> >wm.skl_results, 0);
> +		skl_write_plane_wm(intel_crtc, p_wm,
> +				   &dev_priv->wm.skl_results.ddb,
> 0);
>  
>  	I915_WRITE(PLANE_CTL(pipe, 0), 0);
>  	I915_WRITE(PLANE_SURF(pipe, 0), 0);
> @@ -10819,12 +10824,15 @@ static void i9xx_update_cursor(struct
> drm_crtc *crtc, u32 base,
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
>  	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
> +	const struct skl_plane_wm *p_wm =
> +		&cstate->wm.skl.optimal.planes[PLANE_CURSOR];
>  	int pipe = intel_crtc->pipe;
>  	uint32_t cntl = 0;
>  
>  	if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes &
> drm_crtc_mask(crtc))
> -		skl_write_cursor_wm(intel_crtc, wm);
> +		skl_write_cursor_wm(intel_crtc, p_wm, &wm->ddb);
>  
>  	if (plane_state && plane_state->base.visible) {
>  		cntl = MCURSOR_GAMMA_ENABLE;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index d684f4f..958dc72 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1765,9 +1765,11 @@ bool skl_ddb_allocation_equals(const struct
> skl_ddb_allocation *old,
>  bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
>  				 struct intel_crtc *intel_crtc);
>  void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> -			 const struct skl_wm_values *wm);
> +			 const struct skl_plane_wm *wm,
> +			 const struct skl_ddb_allocation *ddb);
>  void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> -			const struct skl_wm_values *wm,
> +			const struct skl_plane_wm *wm,
> +			const struct skl_ddb_allocation *ddb,
>  			int plane);
>  uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state
> *pipe_config);
>  bool ilk_disable_lp_wm(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 250f12d..7708646 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3000,6 +3000,8 @@ bool intel_can_enable_sagv(struct
> drm_atomic_state *state)
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_atomic_state *intel_state =
> to_intel_atomic_state(state);
>  	struct drm_crtc *crtc;
> +	struct intel_crtc_state *cstate;
> +	struct skl_plane_wm *wm;
>  	enum pipe pipe;
>  	int level, plane;
>  
> @@ -3020,18 +3022,21 @@ bool intel_can_enable_sagv(struct
> drm_atomic_state *state)
>  	/* Since we're now guaranteed to only have one active
> CRTC... */
>  	pipe = ffs(intel_state->active_crtcs) - 1;
>  	crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> +	cstate = intel_atomic_get_crtc_state(state,
> to_intel_crtc(crtc));
>  
>  	if (crtc->state->mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		return false;
>  
>  	for_each_plane(dev_priv, pipe, plane) {
> +		wm = &cstate->wm.skl.optimal.planes[plane];
> +
>  		/* Skip this plane if it's not enabled */
> -		if (intel_state->wm_results.plane[pipe][plane][0] ==
> 0)
> +		if (!wm->wm[0].plane_en)
>  			continue;
>  
>  		/* Find the highest enabled wm level for this plane
> */
> -		for (level = ilk_wm_max_level(dev);
> -		     intel_state-
> >wm_results.plane[pipe][plane][level] == 0; --level)
> +		for (level = ilk_wm_max_level(dev); !wm-
> >wm[level].plane_en;
> +		     --level)
>  		     { }
>  
>  		/*
> @@ -3777,67 +3782,6 @@ static int skl_build_pipe_wm(struct
> intel_crtc_state *cstate,
>  	return 0;
>  }
>  
> -static void skl_compute_wm_results(struct drm_device *dev,
> -				   struct skl_pipe_wm *p_wm,
> -				   struct skl_wm_values *r,
> -				   struct intel_crtc *intel_crtc)
> -{
> -	int level, max_level = ilk_wm_max_level(dev);
> -	struct skl_plane_wm *plane_wm;
> -	enum pipe pipe = intel_crtc->pipe;
> -	uint32_t temp;
> -	int i;
> -
> -	for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> -		plane_wm = &p_wm->planes[i];
> -
> -		for (level = 0; level <= max_level; level++) {
> -			temp = 0;
> -
> -			temp |= plane_wm->wm[level].plane_res_l <<
> -					PLANE_WM_LINES_SHIFT;
> -			temp |= plane_wm->wm[level].plane_res_b;
> -			if (plane_wm->wm[level].plane_en)
> -				temp |= PLANE_WM_EN;
> -
> -			r->plane[pipe][i][level] = temp;
> -		}
> -
> -	}
> -
> -	for (level = 0; level <= max_level; level++) {
> -		plane_wm = &p_wm->planes[PLANE_CURSOR];
> -		temp = 0;
> -		temp |= plane_wm->wm[level].plane_res_l <<
> PLANE_WM_LINES_SHIFT;
> -		temp |= plane_wm->wm[level].plane_res_b;
> -		if (plane_wm->wm[level].plane_en)
> -			temp |= PLANE_WM_EN;
> -
> -		r->plane[pipe][PLANE_CURSOR][level] = temp;
> -	}
> -
> -	/* transition WMs */
> -	for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> -		plane_wm = &p_wm->planes[i];
> -		temp = 0;
> -		temp |= plane_wm->trans_wm.plane_res_l <<
> PLANE_WM_LINES_SHIFT;
> -		temp |= plane_wm->trans_wm.plane_res_b;
> -		if (plane_wm->trans_wm.plane_en)
> -			temp |= PLANE_WM_EN;
> -
> -		r->plane_trans[pipe][i] = temp;
> -	}
> -
> -	plane_wm = &p_wm->planes[PLANE_CURSOR];
> -	temp = 0;
> -	temp |= plane_wm->trans_wm.plane_res_l <<
> PLANE_WM_LINES_SHIFT;
> -	temp |= plane_wm->trans_wm.plane_res_b;
> -	if (plane_wm->trans_wm.plane_en)
> -		temp |= PLANE_WM_EN;
> -
> -	r->plane_trans[pipe][PLANE_CURSOR] = temp;
> -}
> -
>  static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
>  				i915_reg_t reg,
>  				const struct skl_ddb_entry *entry)
> @@ -3848,8 +3792,22 @@ static void skl_ddb_entry_write(struct
> drm_i915_private *dev_priv,
>  		I915_WRITE(reg, 0);
>  }
>  
> +static void skl_write_wm_level(struct drm_i915_private *dev_priv,
> +			       i915_reg_t reg,
> +			       const struct skl_wm_level *level)
> +{
> +	uint32_t val = 0;
> +
> +	val |= level->plane_res_b;
> +	val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
> +	val |= level->plane_en;

The line above seems wrong, you should check for plane_en and then set
PLANE_WM_EN.

IMHO it would even better if we completely zeroed the register in case
plane_en is false, so we could have:

uint32_t val = 0;

if (level->plane_en) {
	val |= PLANE_WM_EN;
	val |= level->plane_res_b;
	val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
}


> +
> +	I915_WRITE(reg, val);
> +}
> +
>  void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> -			const struct skl_wm_values *wm,
> +			const struct skl_plane_wm *wm,
> +			const struct skl_ddb_allocation *ddb,
>  			int plane)
>  {
>  	struct drm_crtc *crtc = &intel_crtc->base;
> @@ -3859,19 +3817,21 @@ void skl_write_plane_wm(struct intel_crtc
> *intel_crtc,
>  	enum pipe pipe = intel_crtc->pipe;
>  
>  	for (level = 0; level <= max_level; level++) {
> -		I915_WRITE(PLANE_WM(pipe, plane, level),
> -			   wm->plane[pipe][plane][level]);
> +		skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane,
> level),
> +				   &wm->wm[level]);
>  	}
> -	I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm-
> >plane_trans[pipe][plane]);
> +	skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane),
> +			   &wm->trans_wm);
>  
>  	skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane),
> -			    &wm->ddb.plane[pipe][plane]);
> +			    &ddb->plane[pipe][plane]);
>  	skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe,
> plane),
> -			    &wm->ddb.y_plane[pipe][plane]);
> +			    &ddb->y_plane[pipe][plane]);
>  }
>  
>  void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> -			 const struct skl_wm_values *wm)
> +			 const struct skl_plane_wm *wm,
> +			 const struct skl_ddb_allocation *ddb)
>  {
>  	struct drm_crtc *crtc = &intel_crtc->base;
>  	struct drm_device *dev = crtc->dev;
> @@ -3880,13 +3840,13 @@ void skl_write_cursor_wm(struct intel_crtc
> *intel_crtc,
>  	enum pipe pipe = intel_crtc->pipe;
>  
>  	for (level = 0; level <= max_level; level++) {
> -		I915_WRITE(CUR_WM(pipe, level),
> -			   wm->plane[pipe][PLANE_CURSOR][level]);
> +		skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
> +				   &wm->wm[level]);
>  	}
> -	I915_WRITE(CUR_WM_TRANS(pipe), wm-
> >plane_trans[pipe][PLANE_CURSOR]);
> +	skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm-
> >trans_wm);
>  
>  	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
> -			    &wm->ddb.plane[pipe][PLANE_CURSOR]);
> +			    &ddb->plane[pipe][PLANE_CURSOR]);
>  }
>  
>  static inline bool skl_ddb_entries_overlap(const struct
> skl_ddb_entry *a,
> @@ -4064,11 +4024,6 @@ skl_copy_wm_for_pipe(struct skl_wm_values
> *dst,
>  		     struct skl_wm_values *src,
>  		     enum pipe pipe)
>  {
> -	memcpy(dst->plane[pipe], src->plane[pipe],
> -	       sizeof(dst->plane[pipe]));
> -	memcpy(dst->plane_trans[pipe], src->plane_trans[pipe],
> -	       sizeof(dst->plane_trans[pipe]));
> -
>  	memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe],
>  	       sizeof(dst->ddb.y_plane[pipe]));
>  	memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
> @@ -4117,7 +4072,6 @@ skl_compute_wm(struct drm_atomic_state *state)
>  	 * no suitable watermark values can be found.
>  	 */
>  	for_each_crtc_in_state(state, crtc, cstate, i) {
> -		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  		struct intel_crtc_state *intel_cstate =
>  			to_intel_crtc_state(cstate);
>  
> @@ -4135,7 +4089,6 @@ skl_compute_wm(struct drm_atomic_state *state)
>  			continue;
>  
>  		intel_cstate->update_wm_pre = true;
> -		skl_compute_wm_results(crtc->dev, pipe_wm, results,
> intel_crtc);
>  	}
>  
>  	return 0;
> @@ -4169,9 +4122,11 @@ static void skl_update_wm(struct drm_crtc
> *crtc)
>  		int plane;
>  
>  		for (plane = 0; plane <
> intel_num_planes(intel_crtc); plane++)
> -			skl_write_plane_wm(intel_crtc, results,
> plane);
> +			skl_write_plane_wm(intel_crtc, &pipe_wm-
> >planes[plane],
> +					   &results->ddb, plane);
>  
> -		skl_write_cursor_wm(intel_crtc, results);
> +		skl_write_cursor_wm(intel_crtc, &pipe_wm-
> >planes[PLANE_CURSOR],
> +				    &results->ddb);
>  	}
>  
>  	skl_copy_wm_for_pipe(hw_vals, results, pipe);
> @@ -4256,28 +4211,13 @@ static void ilk_optimize_watermarks(struct
> intel_crtc_state *cstate)
>  	mutex_unlock(&dev_priv->wm.wm_mutex);
>  }
>  
> -static void skl_pipe_wm_active_state(uint32_t val,
> -				     struct skl_pipe_wm *active,
> -				     bool is_transwm,
> -				     int i,
> -				     int level)
> +static inline void skl_wm_level_from_reg_val(uint32_t val,
> +					     struct skl_wm_level
> *level)
>  {
> -	struct skl_plane_wm *plane_wm = &active->planes[i];
> -	bool is_enabled = (val & PLANE_WM_EN) != 0;
> -
> -	if (!is_transwm) {
> -		plane_wm->wm[level].plane_en = is_enabled;
> -		plane_wm->wm[level].plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> -		plane_wm->wm[level].plane_res_l =
> -			(val >> PLANE_WM_LINES_SHIFT) &
> -			PLANE_WM_LINES_MASK;
> -	} else {
> -		plane_wm->trans_wm.plane_en = is_enabled;
> -		plane_wm->trans_wm.plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> -		plane_wm->trans_wm.plane_res_l =
> -			(val >> PLANE_WM_LINES_SHIFT) &
> -			PLANE_WM_LINES_MASK;
> -	}
> +	level->plane_en = val & PLANE_WM_EN;
> +	level->plane_res_b = val & PLANE_WM_BLOCKS_MASK;
> +	level->plane_res_l = (val & PLANE_WM_LINES_MASK) >>
> +		PLANE_WM_LINES_SHIFT;

This also looks wrong, since PLANE_WM_LINES_MASK is 0x1f. We should do
like the original code did: shifting before masking.


>  }
>  
>  static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> @@ -4287,23 +4227,33 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  	struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> +	struct intel_plane *intel_plane;
>  	struct skl_pipe_wm *active = &cstate->wm.skl.optimal;
> +	struct skl_plane_wm *wm;
>  	enum pipe pipe = intel_crtc->pipe;
> -	int level, i, max_level;
> -	uint32_t temp;
> +	int level, id, max_level = ilk_wm_max_level(dev);
> +	uint32_t val;
>  
> -	max_level = ilk_wm_max_level(dev);
> +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> +		id = skl_wm_plane_id(intel_plane);
> +		wm = &cstate->wm.skl.optimal.planes[id];
>  
> -	for (level = 0; level <= max_level; level++) {
> -		for (i = 0; i < intel_num_planes(intel_crtc); i++)
> -			hw->plane[pipe][i][level] =
> -					I915_READ(PLANE_WM(pipe, i,
> level));
> -		hw->plane[pipe][PLANE_CURSOR][level] =
> I915_READ(CUR_WM(pipe, level));
> -	}
> +		for (level = 0; level <= max_level; level++) {
> +			if (id != PLANE_CURSOR)
> +				val = I915_READ(PLANE_WM(pipe, id,
> level));
> +			else
> +				val = I915_READ(CUR_WM(pipe,
> level));
> +
> +			skl_wm_level_from_reg_val(val, &wm-
> >wm[level]);
> +		}
>  
> -	for (i = 0; i < intel_num_planes(intel_crtc); i++)
> -		hw->plane_trans[pipe][i] =
> I915_READ(PLANE_WM_TRANS(pipe, i));
> -	hw->plane_trans[pipe][PLANE_CURSOR] =
> I915_READ(CUR_WM_TRANS(pipe));
> +		if (id != PLANE_CURSOR)
> +			val = I915_READ(PLANE_WM_TRANS(pipe, id));
> +		else
> +			val = I915_READ(CUR_WM_TRANS(pipe));
> +
> +		skl_wm_level_from_reg_val(val, &wm->trans_wm);
> +	}
>  
>  	if (!intel_crtc->active)
>  		return;
> @@ -4311,25 +4261,6 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
>  	hw->dirty_pipes |= drm_crtc_mask(crtc);
>  
>  	active->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
> -
> -	for (level = 0; level <= max_level; level++) {
> -		for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> -			temp = hw->plane[pipe][i][level];
> -			skl_pipe_wm_active_state(temp, active,
> false, i, level);
> -		}
> -		temp = hw->plane[pipe][PLANE_CURSOR][level];
> -		skl_pipe_wm_active_state(temp, active, false, i,
> level);
> -	}
> -
> -	for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> -		temp = hw->plane_trans[pipe][i];
> -		skl_pipe_wm_active_state(temp, active, true, i, 0);
> -	}
> -
> -	temp = hw->plane_trans[pipe][PLANE_CURSOR];
> -	skl_pipe_wm_active_state(temp, active, true, i, 0);
> -
> -	intel_crtc->wm.active.skl = *active;

As far as I understood, we should still be setting intel_crtc-
>wm.active.skl. Shouldn't we? If not, why?


Now, due to the problems above, weren't you getting some WARNs about
the hw state not matching what it should? In case not, maybe you could
investigate why.


>  }
>  
>  void skl_wm_get_hw_state(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> b/drivers/gpu/drm/i915/intel_sprite.c
> index 73a521f..0fb775b 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -208,6 +208,8 @@ skl_update_plane(struct drm_plane *drm_plane,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	const int pipe = intel_plane->pipe;
>  	const int plane = intel_plane->plane + 1;
> +	const struct skl_plane_wm *p_wm =
> +		&crtc_state->wm.skl.optimal.planes[plane];
>  	u32 plane_ctl;
>  	const struct drm_intel_sprite_colorkey *key = &plane_state-
> >ckey;
>  	u32 surf_addr = plane_state->main.offset;
> @@ -232,7 +234,7 @@ skl_update_plane(struct drm_plane *drm_plane,
>  	plane_ctl |= skl_plane_ctl_rotation(rotation);
>  
>  	if (wm->dirty_pipes & drm_crtc_mask(crtc))
> -		skl_write_plane_wm(intel_crtc, wm, plane);
> +		skl_write_plane_wm(intel_crtc, p_wm, &wm->ddb,
> plane);
>  
>  	if (key->flags) {
>  		I915_WRITE(PLANE_KEYVAL(pipe, plane), key-
> >min_value);
> @@ -289,6 +291,7 @@ skl_disable_plane(struct drm_plane *dplane,
> struct drm_crtc *crtc)
>  	struct drm_device *dev = dplane->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_plane *intel_plane = to_intel_plane(dplane);
> +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
>  	const int pipe = intel_plane->pipe;
>  	const int plane = intel_plane->plane + 1;
>  
> @@ -298,7 +301,8 @@ skl_disable_plane(struct drm_plane *dplane,
> struct drm_crtc *crtc)
>  	 */
>  	if (!dplane->state->visible)
>  		skl_write_plane_wm(to_intel_crtc(crtc),
> -				   &dev_priv->wm.skl_results,
> plane);
> +				   &cstate-
> >wm.skl.optimal.planes[plane],
> +				   &dev_priv->wm.skl_results.ddb,
> plane);
>  
>  	I915_WRITE(PLANE_CTL(pipe, plane), 0);
>  


More information about the Intel-gfx mailing list