[Intel-gfx] [PATCH] drm/i915: Revert CDCLK changes to unbreak geminilake

Lisovskiy, Stanislav stanislav.lisovskiy at intel.com
Mon May 25 08:07:54 UTC 2020


On Mon, May 25, 2020 at 09:07:31AM +0100, Chris Wilson wrote:
> This reverts
> cac91e671ad5 ("drm/i915: Fix includes and local vars order")
> 82ea174dc542 ("drm/i915: Remove unneeded hack now for CDCLK")
> cd1915460861 ("drm/i915: Adjust CDCLK accordingly to our DBuf bw needs")
> 
> Cc: Stanislav Lisovskiy <stanislav.lisovskiy at intel.com>
> Cc: Manasi Navare <manasi.d.navare at intel.com>
> Cc: "Ville Syrjälä" <ville.syrjala at linux.intel.com>


I guess we still need to check more precisely if this patch caused
this - or have you already bisected that?
It is rather strange that it breaks only a GLK and only single test.

Stan

> ---
>  drivers/gpu/drm/i915/display/intel_bw.c      | 127 +------------------
>  drivers/gpu/drm/i915/display/intel_bw.h      |  10 --
>  drivers/gpu/drm/i915/display/intel_cdclk.c   |  41 +++---
>  drivers/gpu/drm/i915/display/intel_display.c |  39 +-----
>  drivers/gpu/drm/i915/i915_drv.h              |   1 -
>  drivers/gpu/drm/i915/intel_pm.c              |  33 +----
>  drivers/gpu/drm/i915/intel_pm.h              |   6 +-
>  7 files changed, 29 insertions(+), 228 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index a79bd7aeb03b..98bbe719cf4f 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -5,12 +5,12 @@
>  
>  #include <drm/drm_atomic_state_helper.h>
>  
> -#include "intel_atomic.h"
>  #include "intel_bw.h"
> -#include "intel_cdclk.h"
>  #include "intel_display_types.h"
> -#include "intel_pm.h"
>  #include "intel_sideband.h"
> +#include "intel_atomic.h"
> +#include "intel_pm.h"
> +
>  
>  /* Parameters for Qclk Geyserville (QGV) */
>  struct intel_qgv_point {
> @@ -428,127 +428,6 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state)
>  	return to_intel_bw_state(bw_state);
>  }
>  
> -int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> -	struct intel_bw_state *new_bw_state = NULL;
> -	struct intel_bw_state *old_bw_state = NULL;
> -	const struct intel_crtc_state *crtc_state;
> -	struct intel_crtc *crtc;
> -	int max_bw = 0;
> -	int slice_id;
> -	int i;
> -
> -	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -		enum plane_id plane_id;
> -		struct intel_dbuf_bw *crtc_bw;
> -
> -		new_bw_state = intel_atomic_get_bw_state(state);
> -		if (IS_ERR(new_bw_state))
> -			return PTR_ERR(new_bw_state);
> -
> -		crtc_bw = &new_bw_state->dbuf_bw[crtc->pipe];
> -
> -		memset(&crtc_bw->used_bw, 0, sizeof(crtc_bw->used_bw));
> -
> -		for_each_plane_id_on_crtc(crtc, plane_id) {
> -			const struct skl_ddb_entry *plane_alloc =
> -				&crtc_state->wm.skl.plane_ddb_y[plane_id];
> -			const struct skl_ddb_entry *uv_plane_alloc =
> -				&crtc_state->wm.skl.plane_ddb_uv[plane_id];
> -			unsigned int data_rate = crtc_state->data_rate[plane_id];
> -			unsigned int dbuf_mask = 0;
> -
> -			dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, plane_alloc);
> -			dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, uv_plane_alloc);
> -
> -			/*
> -			 * FIXME: To calculate that more properly we probably
> -			 * need to to split per plane data_rate into data_rate_y
> -			 * and data_rate_uv for multiplanar formats in order not
> -			 * to get accounted those twice if they happen to reside
> -			 * on different slices.
> -			 * However for pre-icl this would work anyway because
> -			 * we have only single slice and for icl+ uv plane has
> -			 * non-zero data rate.
> -			 * So in worst case those calculation are a bit
> -			 * pessimistic, which shouldn't pose any significant
> -			 * problem anyway.
> -			 */
> -			for_each_dbuf_slice_in_mask(slice_id, dbuf_mask)
> -				crtc_bw->used_bw[slice_id] += data_rate;
> -		}
> -
> -		for_each_dbuf_slice(slice_id) {
> -			/*
> -			 * Current experimental observations show that contrary
> -			 * to BSpec we get underruns once we exceed 64 * CDCLK
> -			 * for slices in total.
> -			 * As a temporary measure in order not to keep CDCLK
> -			 * bumped up all the time we calculate CDCLK according
> -			 * to this formula for  overall bw consumed by slices.
> -			 */
> -			max_bw += crtc_bw->used_bw[slice_id];
> -		}
> -
> -		new_bw_state->min_cdclk = max_bw / 64;
> -
> -		old_bw_state = intel_atomic_get_old_bw_state(state);
> -	}
> -
> -	if (!old_bw_state)
> -		return 0;
> -
> -	if (new_bw_state->min_cdclk != old_bw_state->min_cdclk) {
> -		int ret = intel_atomic_lock_global_state(&new_bw_state->base);
> -
> -		if (ret)
> -			return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -int intel_bw_calc_min_cdclk(struct intel_atomic_state *state)
> -{
> -	int i;
> -	const struct intel_crtc_state *crtc_state;
> -	struct intel_crtc *crtc;
> -	int min_cdclk = 0;
> -	struct intel_bw_state *new_bw_state = NULL;
> -	struct intel_bw_state *old_bw_state = NULL;
> -
> -	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -		struct intel_cdclk_state *cdclk_state;
> -
> -		new_bw_state = intel_atomic_get_bw_state(state);
> -		if (IS_ERR(new_bw_state))
> -			return PTR_ERR(new_bw_state);
> -
> -		cdclk_state = intel_atomic_get_cdclk_state(state);
> -		if (IS_ERR(cdclk_state))
> -			return PTR_ERR(cdclk_state);
> -
> -		min_cdclk = max(cdclk_state->min_cdclk[crtc->pipe], min_cdclk);
> -
> -		new_bw_state->min_cdclk = min_cdclk;
> -
> -		old_bw_state = intel_atomic_get_old_bw_state(state);
> -	}
> -
> -	if (!old_bw_state)
> -		return 0;
> -
> -	if (new_bw_state->min_cdclk != old_bw_state->min_cdclk) {
> -		int ret = intel_atomic_lock_global_state(&new_bw_state->base);
> -
> -		if (ret)
> -			return ret;
> -	}
> -
> -	return 0;
> -}
> -
>  int intel_bw_atomic_check(struct intel_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h
> index 46c6eecbd917..bbcaaa73ec1b 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.h
> +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> @@ -9,20 +9,14 @@
>  #include <drm/drm_atomic.h>
>  
>  #include "intel_display.h"
> -#include "intel_display_power.h"
>  #include "intel_global_state.h"
>  
>  struct drm_i915_private;
>  struct intel_atomic_state;
>  struct intel_crtc_state;
>  
> -struct intel_dbuf_bw {
> -	int used_bw[I915_MAX_DBUF_SLICES];
> -};
> -
>  struct intel_bw_state {
>  	struct intel_global_state base;
> -	struct intel_dbuf_bw dbuf_bw[I915_MAX_PIPES];
>  
>  	/*
>  	 * Contains a bit mask, used to determine, whether correspondent
> @@ -42,8 +36,6 @@ struct intel_bw_state {
>  
>  	/* bitmask of active pipes */
>  	u8 active_pipes;
> -
> -	int min_cdclk;
>  };
>  
>  #define to_intel_bw_state(x) container_of((x), struct intel_bw_state, base)
> @@ -64,7 +56,5 @@ void intel_bw_crtc_update(struct intel_bw_state *bw_state,
>  			  const struct intel_crtc_state *crtc_state);
>  int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
>  				  u32 points_mask);
> -int intel_bw_calc_min_cdclk(struct intel_atomic_state *state);
> -int skl_bw_calc_min_cdclk(struct intel_atomic_state *state);
>  
>  #endif /* __INTEL_BW_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index f9b0fc7317de..9419a4724357 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -21,10 +21,7 @@
>   * DEALINGS IN THE SOFTWARE.
>   */
>  
> -#include <linux/time.h>
> -
>  #include "intel_atomic.h"
> -#include "intel_bw.h"
>  #include "intel_cdclk.h"
>  #include "intel_display_types.h"
>  #include "intel_sideband.h"
> @@ -2071,6 +2068,18 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
>  	/* Account for additional needs from the planes */
>  	min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
>  
> +	/*
> +	 * HACK. Currently for TGL platforms we calculate
> +	 * min_cdclk initially based on pixel_rate divided
> +	 * by 2, accounting for also plane requirements,
> +	 * however in some cases the lowest possible CDCLK
> +	 * doesn't work and causing the underruns.
> +	 * Explicitly stating here that this seems to be currently
> +	 * rather a Hack, than final solution.
> +	 */
> +	if (IS_TIGERLAKE(dev_priv))
> +		min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
> +
>  	if (min_cdclk > dev_priv->max_cdclk_freq) {
>  		drm_dbg_kms(&dev_priv->drm,
>  			    "required cdclk (%d kHz) exceeds max (%d kHz)\n",
> @@ -2084,9 +2093,11 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
>  static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
>  {
>  	struct intel_atomic_state *state = cdclk_state->base.state;
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	struct intel_crtc *crtc;
>  	struct intel_crtc_state *crtc_state;
>  	int min_cdclk, i;
> +	enum pipe pipe;
>  
>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
>  		int ret;
> @@ -2106,18 +2117,8 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
>  	}
>  
>  	min_cdclk = cdclk_state->force_min_cdclk;
> -
> -	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -		struct intel_bw_state *bw_state;
> -
> -		min_cdclk = max(cdclk_state->min_cdclk[crtc->pipe], min_cdclk);
> -
> -		bw_state = intel_atomic_get_bw_state(state);
> -		if (IS_ERR(bw_state))
> -			return PTR_ERR(bw_state);
> -
> -		min_cdclk = max(bw_state->min_cdclk, min_cdclk);
> -	}
> +	for_each_pipe(dev_priv, pipe)
> +		min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);
>  
>  	return min_cdclk;
>  }
> @@ -2789,30 +2790,25 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
>  {
>  	if (INTEL_GEN(dev_priv) >= 12) {
>  		dev_priv->display.set_cdclk = bxt_set_cdclk;
> -		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
>  		dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
>  		dev_priv->cdclk.table = icl_cdclk_table;
>  	} else if (IS_ELKHARTLAKE(dev_priv)) {
>  		dev_priv->display.set_cdclk = bxt_set_cdclk;
> -		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
>  		dev_priv->display.calc_voltage_level = ehl_calc_voltage_level;
>  		dev_priv->cdclk.table = icl_cdclk_table;
>  	} else if (INTEL_GEN(dev_priv) >= 11) {
>  		dev_priv->display.set_cdclk = bxt_set_cdclk;
> -		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
>  		dev_priv->display.calc_voltage_level = icl_calc_voltage_level;
>  		dev_priv->cdclk.table = icl_cdclk_table;
>  	} else if (IS_CANNONLAKE(dev_priv)) {
> -		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
>  		dev_priv->display.set_cdclk = bxt_set_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
>  		dev_priv->display.calc_voltage_level = cnl_calc_voltage_level;
>  		dev_priv->cdclk.table = cnl_cdclk_table;
>  	} else if (IS_GEN9_LP(dev_priv)) {
> -		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
>  		dev_priv->display.set_cdclk = bxt_set_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
>  		dev_priv->display.calc_voltage_level = bxt_calc_voltage_level;
> @@ -2821,23 +2817,18 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
>  		else
>  			dev_priv->cdclk.table = bxt_cdclk_table;
>  	} else if (IS_GEN9_BC(dev_priv)) {
> -		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
>  		dev_priv->display.set_cdclk = skl_set_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = skl_modeset_calc_cdclk;
>  	} else if (IS_BROADWELL(dev_priv)) {
> -		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
>  		dev_priv->display.set_cdclk = bdw_set_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = bdw_modeset_calc_cdclk;
>  	} else if (IS_CHERRYVIEW(dev_priv)) {
> -		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
>  		dev_priv->display.set_cdclk = chv_set_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = vlv_modeset_calc_cdclk;
>  	} else if (IS_VALLEYVIEW(dev_priv)) {
> -		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
>  		dev_priv->display.set_cdclk = vlv_set_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = vlv_modeset_calc_cdclk;
>  	} else {
> -		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
>  		dev_priv->display.modeset_calc_cdclk = fixed_modeset_calc_cdclk;
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index f40b909952cc..fe3706a0aca1 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14707,14 +14707,16 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
>  static int intel_atomic_check_cdclk(struct intel_atomic_state *state,
>  				    bool *need_cdclk_calc)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_cdclk_state *new_cdclk_state;
>  	int i;
>  	struct intel_plane_state *plane_state;
>  	struct intel_plane *plane;
>  	int ret;
> -	struct intel_cdclk_state *new_cdclk_state;
> -	struct intel_crtc_state *new_crtc_state;
> -	struct intel_crtc *crtc;
> +
> +	new_cdclk_state = intel_atomic_get_new_cdclk_state(state);
> +	if (new_cdclk_state && new_cdclk_state->force_min_cdclk_changed)
> +		*need_cdclk_calc = true;
> +
>  	/*
>  	 * active_planes bitmask has been updated, and potentially
>  	 * affected planes are part of the state. We can now
> @@ -14726,35 +14728,6 @@ static int intel_atomic_check_cdclk(struct intel_atomic_state *state,
>  			return ret;
>  	}
>  
> -	new_cdclk_state = intel_atomic_get_new_cdclk_state(state);
> -
> -	if (new_cdclk_state && new_cdclk_state->force_min_cdclk_changed)
> -		*need_cdclk_calc = true;
> -
> -	ret = dev_priv->display.bw_calc_min_cdclk(state);
> -	if (ret)
> -		return ret;
> -
> -	if (!new_cdclk_state)
> -		return 0;
> -
> -	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> -		struct intel_bw_state *bw_state;
> -		int min_cdclk = 0;
> -
> -		min_cdclk = max(new_cdclk_state->min_cdclk[crtc->pipe], min_cdclk);
> -
> -		bw_state = intel_atomic_get_bw_state(state);
> -		if (IS_ERR(bw_state))
> -			return PTR_ERR(bw_state);
> -
> -		/*
> -		 * Currently do this change only if we need to increase
> -		 */
> -		if (bw_state->min_cdclk > min_cdclk)
> -			*need_cdclk_calc = true;
> -	}
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 98f2c448cd92..10383e01efde 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -273,7 +273,6 @@ struct drm_i915_display_funcs {
>  	void (*set_cdclk)(struct drm_i915_private *dev_priv,
>  			  const struct intel_cdclk_config *cdclk_config,
>  			  enum pipe pipe);
> -	int (*bw_calc_min_cdclk)(struct intel_atomic_state *state);
>  	int (*get_fifo_size)(struct drm_i915_private *dev_priv,
>  			     enum i9xx_plane_id i9xx_plane);
>  	int (*compute_pipe_wm)(struct intel_crtc_state *crtc_state);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index b134a1b9d738..4d885ef0bac5 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -33,7 +33,6 @@
>  #include <drm/drm_plane_helper.h>
>  
>  #include "display/intel_atomic.h"
> -#include "display/intel_bw.h"
>  #include "display/intel_display_types.h"
>  #include "display/intel_fbc.h"
>  #include "display/intel_sprite.h"
> @@ -44,6 +43,7 @@
>  #include "i915_fixed.h"
>  #include "i915_irq.h"
>  #include "i915_trace.h"
> +#include "display/intel_bw.h"
>  #include "intel_pm.h"
>  #include "intel_sideband.h"
>  #include "../../../platform/x86/intel_ips.h"
> @@ -4031,9 +4031,10 @@ icl_get_first_dbuf_slice_offset(u32 dbuf_slice_mask,
>  	return offset;
>  }
>  
> -u16 intel_get_ddb_size(struct drm_i915_private *dev_priv)
> +static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv)
>  {
>  	u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size;
> +
>  	drm_WARN_ON(&dev_priv->drm, ddb_size == 0);
>  
>  	if (INTEL_GEN(dev_priv) < 11)
> @@ -4042,34 +4043,6 @@ u16 intel_get_ddb_size(struct drm_i915_private *dev_priv)
>  	return ddb_size;
>  }
>  
> -u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *dev_priv,
> -			    const struct skl_ddb_entry *entry)
> -{
> -	u32 slice_mask = 0;
> -	u16 ddb_size = intel_get_ddb_size(dev_priv);
> -	u16 num_supported_slices = INTEL_INFO(dev_priv)->num_supported_dbuf_slices;
> -	u16 slice_size = ddb_size / num_supported_slices;
> -	u16 start_slice;
> -	u16 end_slice;
> -
> -	if (!skl_ddb_entry_size(entry))
> -		return 0;
> -
> -	start_slice = entry->start / slice_size;
> -	end_slice = (entry->end - 1) / slice_size;
> -
> -	/*
> -	 * Per plane DDB entry can in a really worst case be on multiple slices
> -	 * but single entry is anyway contigious.
> -	 */
> -	while (start_slice <= end_slice) {
> -		slice_mask |= BIT(start_slice);
> -		start_slice++;
> -	}
> -
> -	return slice_mask;
> -}
> -
>  static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state,
>  				  u8 active_pipes);
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
> index a2473594c2db..6636d2a057cd 100644
> --- a/drivers/gpu/drm/i915/intel_pm.h
> +++ b/drivers/gpu/drm/i915/intel_pm.h
> @@ -8,10 +8,10 @@
>  
>  #include <linux/types.h>
>  
> -#include "display/intel_bw.h"
>  #include "display/intel_global_state.h"
>  
>  #include "i915_reg.h"
> +#include "display/intel_bw.h"
>  
>  struct drm_device;
>  struct drm_i915_private;
> @@ -39,10 +39,6 @@ u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *dev_priv);
>  void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc,
>  			       struct skl_ddb_entry *ddb_y,
>  			       struct skl_ddb_entry *ddb_uv);
> -void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv);
> -u16 intel_get_ddb_size(struct drm_i915_private *dev_priv);
> -u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *dev_priv,
> -			    const struct skl_ddb_entry *entry);
>  void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
>  			      struct skl_pipe_wm *out);
>  void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
> -- 
> 2.20.1
> 


More information about the Intel-gfx mailing list