[Intel-gfx] [Intel-xe] [PATCH 35/42] drm/i915/lnl: Introduce MDCLK_CDCLK ratio to DBuf

Matt Roper matthew.d.roper at intel.com
Thu Aug 24 23:45:47 UTC 2023


On Wed, Aug 23, 2023 at 10:07:33AM -0700, Lucas De Marchi wrote:
> From: Stanislav Lisovskiy <stanislav.lisovskiy at intel.com>
> 
> When we change MDCLK/CDCLK the BSpec now instructs us to write a ratio
> between MDCLK/CDCLK to MBUS CTL and DBUF CTL registers during that
> change.
> 
> Previsouly DBuf state and CDCLK were not anyhow coupled together.  Now
> at compute stage when we know which CDCLK/MDCLK we are going to use, we
> need to update the DBuf state with that ratio, being properly encoded,
> so that it gets written to those registers, once DBuf state is being
> update. The criteria for updating DBuf state is also a CDCLK/MDCLK ratio
> change now.
> 
> Cc: Mika Kahola <mika.kahola at intel.com>
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy at intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>

Bspec: 68864

> ---
>  drivers/gpu/drm/i915/display/intel_cdclk.c    | 16 +++++++++
>  drivers/gpu/drm/i915/display/skl_watermark.c  | 35 ++++++++++++++++---
>  drivers/gpu/drm/i915/display/skl_watermark.h  |  1 +
>  .../gpu/drm/i915/display/skl_watermark_regs.h |  2 ++
>  4 files changed, 50 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index 04937aaabcee..aa1000db3cb9 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -37,6 +37,7 @@
>  #include "intel_pci_config.h"
>  #include "intel_pcode.h"
>  #include "intel_psr.h"
> +#include "skl_watermark.h"
>  #include "vlv_sideband.h"
>  
>  /**
> @@ -1827,6 +1828,15 @@ static bool cdclk_pll_is_unknown(unsigned int vco)
>  	return vco == ~0;
>  }
>  
> +static int get_mdclk_cdclk_ratio(struct drm_i915_private *i915,
> +				 const struct intel_cdclk_config *cdclk_config)
> +{
> +	if (DISPLAY_VER(i915) >= 20)
> +		return cdclk_config->mdclk / cdclk_config->cdclk - 1;

Should this be DIV_ROUND_UP?  Bspec 69482 and 69445 both say "If mdclk/cdclk is a
non-integer value, round up the result."

You might want a comment on this function noting that it returns the
register encoding of ratio (i.e., "- 1") rather than the ratio itself.

> +	else
> +		return 1;
> +}
> +
>  static int cdclk_squash_divider(u16 waveform)
>  {
>  	return hweight16(waveform ?: 0xffff);
> @@ -2727,6 +2737,7 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
>  	struct intel_crtc_state *crtc_state;
>  	int min_cdclk, i;
>  	enum pipe pipe;
> +	struct intel_dbuf_state *dbuf_state;
>  
>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
>  		int ret;
> @@ -2760,6 +2771,11 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
>  		}
>  	}
>  
> +	dbuf_state = intel_atomic_get_new_dbuf_state(state);
> +	if (dbuf_state)
> +		dbuf_state->mdclk_cdclk_ratio =
> +			get_mdclk_cdclk_ratio(dev_priv, &cdclk_state->actual);
> +
>  	min_cdclk = max(cdclk_state->force_min_cdclk,
>  			cdclk_state->bw_min_cdclk);
>  	for_each_pipe(dev_priv, pipe)
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 64a122d3c9c0..79454b4d99e3 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -3472,6 +3472,23 @@ int intel_dbuf_init(struct drm_i915_private *i915)
>  	return 0;
>  }
>  
> +static int get_mbus_mdclk_cdclk_ratio(struct drm_i915_private *i915,
> +				      int mdclk_cdclk_ratio,
> +				      int mbus_joined)
> +{
> +	if (DISPLAY_VER(i915) >= 20) {

We can drop this condition.  Since mdclk_cdclk_ratio is already "1" for
pre-20 platforms, the calculations here still come out right (returning
either 3 or 1 depending on joining) there too.


Matt

> +		if (mbus_joined)
> +			return (mdclk_cdclk_ratio << 1) + 1;
> +		else
> +			return mdclk_cdclk_ratio;
> +	}
> +
> +	if (mbus_joined)
> +		return 3;
> +
> +	return 1;
> +}
> +
>  /*
>   * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state before
>   * update the request state of all DBUS slices.
> @@ -3483,10 +3500,16 @@ static void update_mbus_pre_enable(struct intel_atomic_state *state)
>  	enum dbuf_slice slice;
>  	const struct intel_dbuf_state *dbuf_state =
>  		intel_atomic_get_new_dbuf_state(state);
> +	int tracker_state_service;
>  
>  	if (!HAS_MBUS_JOINING(i915))
>  		return;
>  
> +	tracker_state_service =
> +		get_mbus_mdclk_cdclk_ratio(i915,
> +					   dbuf_state->mdclk_cdclk_ratio,
> +					   dbuf_state->joined_mbus);
> +
>  	/*
>  	 * TODO: Implement vblank synchronized MBUS joining changes.
>  	 * Must be properly coordinated with dbuf reprogramming.
> @@ -3494,13 +3517,15 @@ static void update_mbus_pre_enable(struct intel_atomic_state *state)
>  	if (dbuf_state->joined_mbus) {
>  		mbus_ctl = MBUS_HASHING_MODE_1x4 | MBUS_JOIN |
>  			MBUS_JOIN_PIPE_SELECT_NONE;
> -		dbuf_min_tracker_val = DBUF_MIN_TRACKER_STATE_SERVICE(3);
>  	} else {
>  		mbus_ctl = MBUS_HASHING_MODE_2x2 |
>  			MBUS_JOIN_PIPE_SELECT_NONE;
> -		dbuf_min_tracker_val = DBUF_MIN_TRACKER_STATE_SERVICE(1);
>  	}
>  
> +	dbuf_min_tracker_val = DBUF_MIN_TRACKER_STATE_SERVICE(tracker_state_service);
> +
> +	mbus_ctl |= MBUS_TRANS_THROTTLE_MIN_SELECT(dbuf_state->mdclk_cdclk_ratio);
> +
>  	intel_de_rmw(i915, MBUS_CTL,
>  		     MBUS_HASHING_MODE_MASK | MBUS_JOIN |
>  		     MBUS_JOIN_PIPE_SELECT_MASK, mbus_ctl);
> @@ -3521,7 +3546,8 @@ void intel_dbuf_pre_plane_update(struct intel_atomic_state *state)
>  
>  	if (!new_dbuf_state ||
>  	    (new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices &&
> -	     new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus))
> +	     new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus &&
> +	     new_dbuf_state->mdclk_cdclk_ratio == old_dbuf_state->mdclk_cdclk_ratio))
>  		return;
>  
>  	WARN_ON(!new_dbuf_state->base.changed);
> @@ -3542,7 +3568,8 @@ void intel_dbuf_post_plane_update(struct intel_atomic_state *state)
>  
>  	if (!new_dbuf_state ||
>  	    (new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices &&
> -	     new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus))
> +	     new_dbuf_state->joined_mbus == old_dbuf_state->joined_mbus &&
> +	     new_dbuf_state->mdclk_cdclk_ratio == old_dbuf_state->mdclk_cdclk_ratio))
>  		return;
>  
>  	WARN_ON(!new_dbuf_state->base.changed);
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h
> index f91a3d4ddc07..54db5c7d517e 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.h
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.h
> @@ -56,6 +56,7 @@ struct intel_dbuf_state {
>  	u8 slices[I915_MAX_PIPES];
>  	u8 enabled_slices;
>  	u8 active_pipes;
> +	u8 mdclk_cdclk_ratio;
>  	bool joined_mbus;
>  };
>  
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark_regs.h b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
> index 628c5920ad49..4c820f1d351d 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark_regs.h
> +++ b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
> @@ -38,6 +38,8 @@
>  #define MBUS_HASHING_MODE_2x2		REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
>  #define MBUS_HASHING_MODE_1x4		REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
>  #define MBUS_JOIN_PIPE_SELECT_MASK	REG_GENMASK(28, 26)
> +#define MBUS_TRANS_THROTTLE_MIN_MASK	REG_GENMASK(15, 13)
> +#define MBUS_TRANS_THROTTLE_MIN_SELECT(ratio)	REG_FIELD_PREP(MBUS_TRANS_THROTTLE_MIN_MASK, ratio)
>  #define MBUS_JOIN_PIPE_SELECT(pipe)	REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
>  #define MBUS_JOIN_PIPE_SELECT_NONE	MBUS_JOIN_PIPE_SELECT(7)
>  
> -- 
> 2.40.1
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation


More information about the Intel-gfx mailing list