All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Ausmus <james.ausmus@intel.com>
To: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 01/17] drm/i915/icl: add the main CDCLK functions
Date: Fri, 2 Feb 2018 14:12:07 -0800	[thread overview]
Message-ID: <20180202221206.GB17879@jausmus-gentoo-dev6.jf.intel.com> (raw)
In-Reply-To: <20180202195702.20008-1-paulo.r.zanoni@intel.com>

On Fri, Feb 02, 2018 at 05:57:02PM -0200, Paulo Zanoni wrote:
> This commit adds the basic CDCLK functions, but it's still missing
> pieces of the display initialization sequence.
> 
> v2:
>  - Implement the voltage levels.
>  - Rebase.
> v3:
>  - Adjust to the new "bypass" clock (Imre).
>  - Call intel_dump_cdclk_state() too.
>  - Rename a variable to avoid confusion.
>  - Simplify the DVFS part.
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h    |  10 +-
>  drivers/gpu/drm/i915/intel_cdclk.c | 235 ++++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_drv.h   |   2 +
>  3 files changed, 243 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index f6e1677e8211..856e88c6ee97 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7182,8 +7182,12 @@ enum {
>  #define SKL_DFSM_PIPE_B_DISABLE		(1 << 21)
>  #define SKL_DFSM_PIPE_C_DISABLE		(1 << 28)
>  
> -#define SKL_DSSM			_MMIO(0x51004)
> -#define CNL_DSSM_CDCLK_PLL_REFCLK_24MHz	(1 << 31)
> +#define SKL_DSSM				_MMIO(0x51004)
> +#define CNL_DSSM_CDCLK_PLL_REFCLK_24MHz		(1 << 31)
> +#define ICL_DSSM_CDCLK_PLL_REFCLK_MASK		(7 << 29)
> +#define ICL_DSSM_CDCLK_PLL_REFCLK_24MHz		(0 << 29)
> +#define ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz	(1 << 29)
> +#define ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz	(2 << 29)
>  
>  #define GEN7_FF_SLICE_CS_CHICKEN1	_MMIO(0x20e0)
>  #define   GEN9_FFSC_PERCTX_PREEMPT_CTRL	(1<<14)
> @@ -8831,6 +8835,8 @@ enum skl_power_gate {
>  #define  BXT_CDCLK_CD2X_PIPE_NONE	BXT_CDCLK_CD2X_PIPE(3)
>  #define  BXT_CDCLK_SSA_PRECHARGE_ENABLE	(1<<16)
>  #define  CDCLK_FREQ_DECIMAL_MASK	(0x7ff)
> +#define  ICL_CDCLK_CD2X_PIPE(pipe)	((pipe) << 19)

This is still wrong :)

> +#define  ICL_CDCLK_CD2X_PIPE_NONE	ICL_CDCLK_CD2X_PIPE(7)
>  
>  /* LCPLL_CTL */
>  #define LCPLL1_CTL		_MMIO(0x46010)
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index ee788d5be5e3..52a15d0eaae9 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1778,6 +1778,197 @@ static void cnl_sanitize_cdclk(struct drm_i915_private *dev_priv)
>  	dev_priv->cdclk.hw.vco = -1;
>  }
>  
> +static int icl_calc_cdclk(int min_cdclk, unsigned int ref)
> +{
> +	int ranges_24[] = { 312000, 552000, 648000 };
> +	int ranges_19_38[] = { 307200, 556800, 652800 };
> +	int *ranges;
> +
> +	switch (ref) {
> +	default:
> +		MISSING_CASE(ref);
> +	case 24000:
> +		ranges = ranges_24;
> +		break;
> +	case 19200:
> +	case 38400:
> +		ranges = ranges_19_38;
> +		break;
> +	}
> +
> +	if (min_cdclk > ranges[1])
> +		return ranges[2];
> +	else if (min_cdclk > ranges[0])
> +		return ranges[1];
> +	else
> +		return ranges[0];
> +}
> +
> +static int icl_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
> +{
> +	int ratio;
> +
> +	if (cdclk == dev_priv->cdclk.hw.bypass)
> +		return 0;
> +
> +	switch (cdclk) {
> +	default:
> +		MISSING_CASE(cdclk);
> +	case 307200:
> +	case 556800:
> +	case 652800:
> +		WARN_ON(dev_priv->cdclk.hw.ref != 19200 &&
> +			dev_priv->cdclk.hw.ref != 38400);
> +		break;
> +	case 312000:
> +	case 552000:
> +	case 648000:
> +		WARN_ON(dev_priv->cdclk.hw.ref != 24000);
> +	}
> +
> +	ratio = cdclk / (dev_priv->cdclk.hw.ref / 2);
> +
> +	return dev_priv->cdclk.hw.ref * ratio;
> +}
> +
> +static void icl_set_cdclk(struct drm_i915_private *dev_priv,
> +			  const struct intel_cdclk_state *cdclk_state)
> +{
> +	unsigned int cdclk = cdclk_state->cdclk;
> +	unsigned int vco = cdclk_state->vco;
> +	int ret;
> +
> +	mutex_lock(&dev_priv->pcu_lock);
> +	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
> +				SKL_CDCLK_PREPARE_FOR_CHANGE,
> +				SKL_CDCLK_READY_FOR_CHANGE,
> +				SKL_CDCLK_READY_FOR_CHANGE, 3);
> +	mutex_unlock(&dev_priv->pcu_lock);
> +	if (ret) {
> +		DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
> +			  ret);
> +		return;
> +	}
> +
> +	if (dev_priv->cdclk.hw.vco != 0 &&
> +	    dev_priv->cdclk.hw.vco != vco)
> +		cnl_cdclk_pll_disable(dev_priv);
> +
> +	if (dev_priv->cdclk.hw.vco != vco)
> +		cnl_cdclk_pll_enable(dev_priv, vco);
> +
> +	I915_WRITE(CDCLK_CTL, ICL_CDCLK_CD2X_PIPE_NONE |
> +			      skl_cdclk_decimal(cdclk));
> +
> +	mutex_lock(&dev_priv->pcu_lock);
> +	/* TODO: add proper DVFS support. */
> +	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, 2);
> +	mutex_unlock(&dev_priv->pcu_lock);
> +
> +	intel_update_cdclk(dev_priv);
> +}
> +
> +static void icl_get_cdclk(struct drm_i915_private *dev_priv,
> +			  struct intel_cdclk_state *cdclk_state)
> +{
> +	u32 val;
> +
> +	cdclk_state->bypass = 50000;
> +
> +	val = I915_READ(SKL_DSSM);
> +	switch (val & ICL_DSSM_CDCLK_PLL_REFCLK_MASK) {
> +	default:
> +		MISSING_CASE(val);
> +	case ICL_DSSM_CDCLK_PLL_REFCLK_24MHz:
> +		cdclk_state->ref = 24000;
> +		break;
> +	case ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz:
> +		cdclk_state->ref = 19200;
> +		break;
> +	case ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz:
> +		cdclk_state->ref = 38400;
> +		break;
> +	}
> +
> +	val = I915_READ(BXT_DE_PLL_ENABLE);
> +	if ((val & BXT_DE_PLL_PLL_ENABLE) == 0 ||
> +	    (val & BXT_DE_PLL_LOCK) == 0) {
> +		/* CDCLK PLL is disabled, the VCO/ratio doesn't matter, but
> +		 * setting it to zero is a way to signal that. */
> +		cdclk_state->vco = 0;
> +		cdclk_state->cdclk = cdclk_state->bypass;
> +		return;
> +	}
> +
> +	cdclk_state->vco = (val & BXT_DE_PLL_RATIO_MASK) * cdclk_state->ref;
> +
> +	val = I915_READ(CDCLK_CTL);
> +	WARN_ON((val & BXT_CDCLK_CD2X_DIV_SEL_MASK) != 0);
> +
> +	cdclk_state->cdclk = cdclk_state->vco / 2;
> +}
> +
> +/**
> + * icl_init_cdclk - Initialize CDCLK on ICL
> + * @dev_priv: i915 device
> + *
> + * Initialize CDCLK for ICL. This consists mainly of initializing
> + * dev_priv->cdclk.hw and sanitizing the state of the hardware if needed. This
> + * is generally done only during the display core initialization sequence, after
> + * which the DMC will take care of turning CDCLK off/on as needed.
> + */
> +void icl_init_cdclk(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_cdclk_state sanitized_state;
> +	u32 val;
> +
> +	/* This sets dev_priv->cdclk.hw. */
> +	intel_update_cdclk(dev_priv);
> +	intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK");
> +
> +	/* This means CDCLK disabled. */
> +	if (dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
> +		goto sanitize;
> +
> +	val = I915_READ(CDCLK_CTL);
> +
> +	if ((val & BXT_CDCLK_CD2X_DIV_SEL_MASK) != 0)
> +		goto sanitize;
> +
> +	if ((val & CDCLK_FREQ_DECIMAL_MASK) !=
> +	    skl_cdclk_decimal(dev_priv->cdclk.hw.cdclk))
> +		goto sanitize;
> +
> +	return;
> +
> +sanitize:
> +	DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
> +
> +	sanitized_state.ref = dev_priv->cdclk.hw.ref;
> +	sanitized_state.cdclk = icl_calc_cdclk(0, sanitized_state.ref);
> +	sanitized_state.vco = icl_calc_cdclk_pll_vco(dev_priv,
> +						     sanitized_state.cdclk);
> +
> +	icl_set_cdclk(dev_priv, &sanitized_state);
> +}
> +
> +/**
> + * icl_uninit_cdclk - Uninitialize CDCLK on ICL
> + * @dev_priv: i915 device
> + *
> + * Uninitialize CDCLK for ICL. This is done only during the display core
> + * uninitialization sequence.
> + */
> +void icl_uninit_cdclk(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw;
> +
> +	cdclk_state.cdclk = cdclk_state.bypass;
> +	cdclk_state.vco = 0;
> +
> +	icl_set_cdclk(dev_priv, &cdclk_state);
> +}
> +
>  /**
>   * cnl_init_cdclk - Initialize CDCLK on CNL
>   * @dev_priv: i915 device
> @@ -2216,6 +2407,36 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
>  	return 0;
>  }
>  
> +static int icl_modeset_calc_cdclk(struct drm_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->dev);
> +	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> +	unsigned int ref = intel_state->cdclk.logical.ref;
> +	int min_cdclk, cdclk, vco;
> +
> +	min_cdclk = intel_compute_min_cdclk(state);
> +	if (min_cdclk < 0)
> +		return min_cdclk;
> +
> +	cdclk = icl_calc_cdclk(min_cdclk, ref);
> +	vco = icl_calc_cdclk_pll_vco(dev_priv, cdclk);
> +
> +	intel_state->cdclk.logical.vco = vco;
> +	intel_state->cdclk.logical.cdclk = cdclk;
> +
> +	if (!intel_state->active_crtcs) {
> +		cdclk = icl_calc_cdclk(0, ref);
> +		vco = icl_calc_cdclk_pll_vco(dev_priv, cdclk);
> +
> +		intel_state->cdclk.actual.vco = vco;
> +		intel_state->cdclk.actual.cdclk = cdclk;
> +	} else {
> +		intel_state->cdclk.actual = intel_state->cdclk.logical;
> +	}
> +
> +	return 0;
> +}
> +
>  static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
>  {
>  	int max_cdclk_freq = dev_priv->max_cdclk_freq;
> @@ -2249,7 +2470,12 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
>   */
>  void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
>  {
> -	if (IS_CANNONLAKE(dev_priv)) {
> +	if (IS_ICELAKE(dev_priv)) {
> +		if (dev_priv->cdclk.hw.ref == 24000)
> +			dev_priv->max_cdclk_freq = 648000;
> +		else
> +			dev_priv->max_cdclk_freq = 652800;
> +	} else if (IS_CANNONLAKE(dev_priv)) {
>  		dev_priv->max_cdclk_freq = 528000;
>  	} else if (IS_GEN9_BC(dev_priv)) {
>  		u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
> @@ -2473,9 +2699,14 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
>  		dev_priv->display.set_cdclk = cnl_set_cdclk;
>  		dev_priv->display.modeset_calc_cdclk =
>  			cnl_modeset_calc_cdclk;
> +	} else if (IS_ICELAKE(dev_priv)) {
> +		dev_priv->display.set_cdclk = icl_set_cdclk;
> +		dev_priv->display.modeset_calc_cdclk = icl_modeset_calc_cdclk;
>  	}
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		dev_priv->display.get_cdclk = icl_get_cdclk;
> +	else if (IS_CANNONLAKE(dev_priv))
>  		dev_priv->display.get_cdclk = cnl_get_cdclk;
>  	else if (IS_GEN9_BC(dev_priv))
>  		dev_priv->display.get_cdclk = skl_get_cdclk;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index d6a808374dfb..cca7ecae5cce 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1403,6 +1403,8 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv);
>  void cnl_uninit_cdclk(struct drm_i915_private *dev_priv);
>  void bxt_init_cdclk(struct drm_i915_private *dev_priv);
>  void bxt_uninit_cdclk(struct drm_i915_private *dev_priv);
> +void icl_init_cdclk(struct drm_i915_private *dev_priv);
> +void icl_uninit_cdclk(struct drm_i915_private *dev_priv);
>  void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
>  void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
>  void intel_update_cdclk(struct drm_i915_private *dev_priv);
> -- 
> 2.14.3
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2018-02-02 22:09 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-23 19:05 [PATCH 00/17] ICL display initialization and some plane bits Paulo Zanoni
2018-01-23 19:05 ` [PATCH 01/17] drm/i915/icl: add the main CDCLK functions Paulo Zanoni
2018-01-26 23:14   ` James Ausmus
2018-02-01 20:09     ` Paulo Zanoni
2018-01-29 10:51   ` Imre Deak
2018-02-01 20:08     ` Paulo Zanoni
2018-02-01 20:40       ` Imre Deak
2018-02-02 19:57   ` Paulo Zanoni
2018-02-02 22:12     ` James Ausmus [this message]
2018-01-23 19:05 ` [PATCH 02/17] drm/i915/icl: add ICL support to cnl_set_procmon_ref_values Paulo Zanoni
2018-01-24  0:32   ` James Ausmus
2018-01-26 20:24     ` Paulo Zanoni
2018-01-26 20:47       ` James Ausmus
2018-01-26 20:33   ` Ville Syrjälä
2018-02-02 16:23   ` Paulo Zanoni
2018-02-02 18:17     ` James Ausmus
2018-01-23 19:05 ` [PATCH 03/17] drm/i915/icl: implement the display init/uninit sequences Paulo Zanoni
2018-01-26 23:25   ` James Ausmus
2018-01-23 19:05 ` [PATCH 04/17] drm/i915/icl: Enable both DBuf slices during init Paulo Zanoni
2018-01-24  0:49   ` James Ausmus
2018-01-26 20:50     ` Paulo Zanoni
2018-01-29 17:47       ` Paulo Zanoni
2018-01-23 19:05 ` [PATCH 05/17] drm/i915/icl: Don't allocate fixed bypass path blocks for ICL Paulo Zanoni
2018-01-24  0:58   ` James Ausmus
2018-01-23 19:05 ` [PATCH 06/17] drm/i915/icl: Do not fix dbuf block size to 512 Paulo Zanoni
2018-01-24  1:14   ` James Ausmus
2018-01-29 23:07   ` Paulo Zanoni
2018-01-29 23:32     ` James Ausmus
2018-01-23 19:05 ` [PATCH 07/17] drm/i915/icl: Fail flip if ddb allocated are less than min display buffer needed Paulo Zanoni
2018-01-26 23:50   ` James Ausmus
2018-01-29 18:16     ` Paulo Zanoni
2018-01-29 23:08   ` [PATCH 07/13] " Paulo Zanoni
2018-01-23 19:05 ` [PATCH 08/17] drm/i915/icl: NV12 y-plane ddb is not in same plane Paulo Zanoni
2018-01-25 22:31   ` James Ausmus
2018-01-23 19:05 ` [PATCH 09/17] drm/i915/icl: Introduce MBus related registers Paulo Zanoni
2018-01-25 22:38   ` James Ausmus
2018-01-23 19:05 ` [PATCH 10/17] drm/i915/icl: initialize MBus during display init Paulo Zanoni
2018-01-25 22:39   ` James Ausmus
2018-01-23 19:05 ` [PATCH 11/17] drm/i915/icl: program mbus during pipe enable Paulo Zanoni
2018-01-25 22:42   ` James Ausmus
2018-01-23 19:05 ` [PATCH 12/17] drm/i915/icl: track dbuf slice-2 status Paulo Zanoni
2018-01-25 23:08   ` James Ausmus
2018-01-23 19:05 ` [PATCH 13/17] drm/i915/icl: Enable 2nd DBuf slice only when needed Paulo Zanoni
2018-01-25 22:56   ` James Ausmus
2018-03-14 16:19   ` [PATCH 2/2] " Mahesh Kumar
2018-01-23 19:05 ` [PATCH 14/17] drm/i915/icl: update ddb entry start/end mask during hw ddb readout Paulo Zanoni
2018-01-25 23:00   ` James Ausmus
2018-01-23 19:05 ` [PATCH 15/17] drm/i915/gen11: fix the SAGV block time for gen11 Paulo Zanoni
2018-01-25 23:09   ` James Ausmus
2018-01-23 19:05 ` [PATCH 16/17] drm/i915/icl: enable SAGV for ICL platform Paulo Zanoni
2018-01-25 23:09   ` James Ausmus
2018-01-29 22:07   ` Paulo Zanoni
2018-01-23 19:05 ` [PATCH 17/17] drm/i915/icl: Handle expanded PLANE_CTL_FORMAT field Paulo Zanoni
2018-01-23 19:32 ` ✗ Fi.CI.BAT: failure for ICL display initialization and some plane bits Patchwork
2018-01-23 20:32 ` Patchwork
2018-01-29 23:27 ` ✗ Fi.CI.BAT: failure for ICL display initialization and some plane bits (rev2) Patchwork
2018-02-02 17:10 ` ✗ Fi.CI.BAT: failure for ICL display initialization and some plane bits (rev4) Patchwork
2018-02-02 17:28 ` Patchwork
2018-02-02 20:22 ` ✗ Fi.CI.BAT: failure for ICL display initialization and some plane bits (rev5) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180202221206.GB17879@jausmus-gentoo-dev6.jf.intel.com \
    --to=james.ausmus@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=paulo.r.zanoni@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.