All of lore.kernel.org
 help / color / mirror / Atom feed
From: Damien Lespiau <damien.lespiau@intel.com>
To: Mika Kahola <mika.kahola@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v4 12/12] drm/i915: BDW clock change support
Date: Fri, 29 May 2015 12:45:25 +0100	[thread overview]
Message-ID: <20150529114525.GD28280@strange.ger.corp.intel.com> (raw)
In-Reply-To: <1432282962-3530-13-git-send-email-mika.kahola@intel.com>

On Fri, May 22, 2015 at 11:22:42AM +0300, Mika Kahola wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Add support for changing cdclk frequency during runtime on BDW. The
> procedure is quite a bit different on BDW from the one on HSW, so
> add a separate function for it.
> 
> Also with IPS enabled the actual pixel rate mustn't exceed 95% of cdclk,
> so take that into account when computing the max pixel rate.
> 
> v2: Grab rps.hw_lock around sandybridge_pcode_write()
> v3: Rebase due to power well vs. .global_resources() reordering
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> v4: Rebased to the latest
> v5: Rebased to the latest
> 
> Reviewed-by: Mika Kahola <mika.kahola@intel.com>
> 
> Author:    Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---

(fwiw, I'm making the SKL cdclk code look like those HSW/BDW patches a
bit more. We may want to extract a few low level vfuncs
(set_core_display_clock(), ...) but that's for another time)

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

>  drivers/gpu/drm/i915/i915_reg.h      |   1 +
>  drivers/gpu/drm/i915/intel_display.c | 139 ++++++++++++++++++++++++++++++-----
>  2 files changed, 122 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 015fe12..64ec500 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6702,6 +6702,7 @@ enum skl_disp_power_wells {
>  #define     GEN6_ENCODE_RC6_VID(mv)		(((mv) - 245) / 5)
>  #define     GEN6_DECODE_RC6_VID(vids)		(((vids) * 5) + 245)
>  #define   HSW_PCODE_DE_WRITE_FREQ_REQ		0x17
> +#define   BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ	0x18
>  #define   GEN9_PCODE_READ_MEM_LATENCY		0x6
>  #define     GEN9_MEM_LATENCY_LEVEL_MASK		0xFF
>  #define     GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT	8
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 556d0ec7..71efd2f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5545,7 +5545,22 @@ static void intel_update_max_cdclk(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (IS_HASWELL(dev)) {
> +	if (IS_BROADWELL(dev))  {
> +		/*
> +		 * FIXME with extra cooling we can allow
> +		 * 540 MHz for ULX and 675 Mhz for ULT.
> +		 * How can we know if extra cooling is
> +		 * available? PCI ID, VTB, something else?
> +		 */
> +		if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
> +			dev_priv->max_cdclk_freq = 450000;
> +		else if (IS_BDW_ULX(dev))
> +			dev_priv->max_cdclk_freq = 450000;
> +		else if (IS_BDW_ULT(dev))
> +			dev_priv->max_cdclk_freq = 540000;
> +		else
> +			dev_priv->max_cdclk_freq = 675000;
> +	} else if (IS_HASWELL(dev)) {
>  		if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
>  			dev_priv->max_cdclk_freq = 450000;
>  		else if (IS_HSW_ULX(dev))
> @@ -6426,13 +6441,11 @@ static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
>  		return true;
>  
>  	/*
> -	 * FIXME if we compare against max we should then
> -	 * increase the cdclk frequency when the current
> -	 * value is too low. The other option is to compare
> -	 * against the cdclk frequency we're going have post
> -	 * modeset (ie. one we computed using other constraints).
> -	 * Need to measure whether using a lower cdclk w/o IPS
> -	 * is better or worse than a higher cdclk w/ IPS.
> +	 * We compare against max which means we must take
> +	 * the increased cdclk requirement into account when
> +	 * calculating the new cdclk.
> +	 *
> +	 * Should measure whether using a lower cdclk w/o IPS
>  	 */
>  	return ilk_pipe_pixel_rate(pipe_config) <=
>  		dev_priv->max_cdclk_freq * 95 / 100;
> @@ -9421,9 +9434,18 @@ static int ilk_max_pixel_rate(struct drm_i915_private *dev_priv)
>  	int max_pixel_rate = 0;
>  
>  	for_each_intel_crtc(dev, crtc) {
> -		if (crtc->new_enabled)
> -			max_pixel_rate = max((int)max_pixel_rate,
> -					     (int)ilk_pipe_pixel_rate(crtc->config));
> +		int pixel_rate;
> +
> +		if (!crtc->new_enabled)
> +			continue;
> +
> +		pixel_rate = ilk_pipe_pixel_rate(crtc->config);
> +
> +		/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
> +		if (IS_BROADWELL(dev) && crtc->config->ips_enabled)
> +			pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95);
> +
> +		max_pixel_rate = max(max_pixel_rate, pixel_rate);
>  	}
>  
>  	return max_pixel_rate;
> @@ -9438,7 +9460,9 @@ static int haswell_calc_cdclk(struct drm_i915_private *dev_priv,
>  	 * FIXME should also account for plane ratio
>  	 * once 64bpp pixel formats are supported.
>  	 */
> -	if (max_pixel_rate > 450000)
> +	if (max_pixel_rate > 540000)
> +		cdclk = 675000;
> +	else if (max_pixel_rate > 450000)
>  		cdclk = 540000;
>  	else if (max_pixel_rate > 337500 || !IS_HSW_ULX(dev_priv))
>  		cdclk = 450000;
> @@ -9503,6 +9527,83 @@ static void haswell_set_cdclk(struct drm_device *dev, int cdclk)
>  	     cdclk, dev_priv->cdclk_freq);
>  }

Quite frankly, I'd split out a broadwell cacl_cdclk out.

>  
> +static void broadwell_set_cdclk(struct drm_device *dev, int cdclk)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	uint32_t val, data;
> +	int ret;
> +
> +	if (WARN((I915_READ(LCPLL_CTL) &
> +		  (LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |
> +		   LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE |
> +		   LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW |
> +		   LCPLL_CD_SOURCE_FCLK)) != LCPLL_PLL_LOCK,
> +		 "trying to change cdclk frequency with cdclk not enabled\n"))
> +		return;
> +
> +	mutex_lock(&dev_priv->rps.hw_lock);
> +	ret = sandybridge_pcode_write(dev_priv,
> +				      BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
> +	mutex_unlock(&dev_priv->rps.hw_lock);
> +	if (ret) {
> +		DRM_ERROR("failed to inform pcode about cdclk change\n");
> +		return;
> +	}
> +
> +	val = I915_READ(LCPLL_CTL);
> +	val |= LCPLL_CD_SOURCE_FCLK;
> +	I915_WRITE(LCPLL_CTL, val);
> +
> +	if (wait_for_atomic_us(I915_READ(LCPLL_CTL) &
> +			       LCPLL_CD_SOURCE_FCLK_DONE, 1))
> +		DRM_ERROR("Switching to FCLK failed\n");
> +
> +	val = I915_READ(LCPLL_CTL);
> +	val &= ~LCPLL_CLK_FREQ_MASK;
> +
> +	switch (cdclk) {
> +	case 450000:
> +		val |= LCPLL_CLK_FREQ_450;
> +		data = 0;
> +		break;
> +	case 540000:
> +		val |= LCPLL_CLK_FREQ_54O_BDW;
> +		data = 1;
> +		break;
> +	case 337500:
> +		val |= LCPLL_CLK_FREQ_337_5_BDW;
> +		data = 2;
> +		break;
> +	case 675000:
> +		val |= LCPLL_CLK_FREQ_675_BDW;
> +		data = 3;
> +		break;
> +	default:
> +		WARN(1, "invalid cdclk frequency\n");
> +		return;
> +	}
> +
> +	I915_WRITE(LCPLL_CTL, val);
> +
> +	val = I915_READ(LCPLL_CTL);
> +	val &= ~LCPLL_CD_SOURCE_FCLK;
> +	I915_WRITE(LCPLL_CTL, val);
> +
> +	if (wait_for_atomic_us((I915_READ(LCPLL_CTL) &
> +				LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
> +		DRM_ERROR("Switching back to LCPLL failed\n");
> +
> +	mutex_lock(&dev_priv->rps.hw_lock);
> +	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
> +	mutex_unlock(&dev_priv->rps.hw_lock);
> +
> +	intel_update_cdclk(dev);
> +
> +	WARN(cdclk != dev_priv->cdclk_freq,
> +	     "cdclk requested %d kHz but got %d kHz\n",
> +	     cdclk, dev_priv->cdclk_freq);
> +}
> +
>  static int haswell_modeset_global_pipes(struct drm_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> @@ -9542,7 +9643,10 @@ static void haswell_modeset_global_resources(struct drm_atomic_state *state)
>  	int req_cdclk = haswell_calc_cdclk(dev_priv, max_pixel_rate);
>  
>  	if (req_cdclk != dev_priv->cdclk_freq) {
> -		haswell_set_cdclk(dev, req_cdclk);
> +		if (IS_BROADWELL(dev))
> +			broadwell_set_cdclk(dev, req_cdclk);
> +		else
> +			haswell_set_cdclk(dev, req_cdclk);
>  	}
>  }
>  
> @@ -12724,8 +12828,8 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
>  	 * mode set on this crtc.  For other crtcs we need to use the
>  	 * adjusted_mode bits in the crtc directly.
>  	 */
> -	if (IS_VALLEYVIEW(dev) || IS_BROXTON(dev) || IS_HASWELL(dev)) {
> -		if (IS_VALLEYVIEW(dev) || IS_BROXTON(dev)) {
> +	if (IS_VALLEYVIEW(dev) || IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> +		if (IS_VALLEYVIEW(dev) || IS_BROXTON(dev) || IS_BROADWELL(dev)) {
>  			ret = valleyview_modeset_global_pipes(state);
>  			if (ret)
>  				return ret;
> @@ -14616,9 +14720,8 @@ static void intel_init_display(struct drm_device *dev)
>  		dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
>  	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
>  		dev_priv->display.fdi_link_train = hsw_fdi_link_train;
> -		if (IS_HASWELL(dev))
> -			dev_priv->display.modeset_global_resources =
> -				haswell_modeset_global_resources;
> +		dev_priv->display.modeset_global_resources =
> +			haswell_modeset_global_resources;
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		dev_priv->display.modeset_global_resources =
>  			valleyview_modeset_global_resources;
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2015-05-29 11:45 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-22  8:22 [PATCH v4 00/12] All sort of cdclk stuff Mika Kahola
2015-05-22  8:22 ` [PATCH v4 01/12] drm/i915: Fix i855 get_display_clock_speed Mika Kahola
2015-05-28 18:12   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 02/12] drm/i915: Fix 852GM/GMV cdclk Mika Kahola
2015-05-28 18:16   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 03/12] drm/i915: Add cdclk extraction for g33, g965gm and g4x Mika Kahola
2015-05-28 18:17   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 04/12] drm/i915: Warn when cdclk for the platforms is not known Mika Kahola
2015-05-28 18:19   ` Damien Lespiau
2015-05-29  7:57     ` Daniel Vetter
2015-05-22  8:22 ` [PATCH v4 05/12] drm/i915: Cache current cdclk frequency in dev_priv Mika Kahola
2015-05-28 18:24   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 06/12] drm/i915: Use cached cdclk value Mika Kahola
2015-05-28 18:27   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 07/12] drm/i915: Unify ilk and hsw .get_aux_clock_divider Mika Kahola
2015-05-28 18:31   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 8/8] drm/i915: Store max cdclk value in dev_priv Mika Kahola
2015-05-28 18:32   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 09/12] drm/i915: Don't enable IPS when pixel rate exceeds 95% Mika Kahola
2015-05-28 18:35   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 10/12] drm/i915: HSW cdclk support Mika Kahola
2015-05-29 11:30   ` Damien Lespiau
2015-05-29 12:06     ` Kahola, Mika
2015-05-29 12:56       ` Damien Lespiau
2015-05-29 13:51     ` Ville Syrjälä
2015-05-22  8:22 ` [PATCH v4 11/12] drm/i915: Add IS_BDW_ULX Mika Kahola
2015-05-29 11:33   ` Damien Lespiau
2015-05-22  8:22 ` [PATCH v4 12/12] drm/i915: BDW clock change support Mika Kahola
2015-05-29 11:45   ` Damien Lespiau [this message]
2015-05-22  8:41 ` [PATCH v4 00/12] All sort of cdclk stuff Jani Nikula
2015-05-22  8:46   ` Jani Nikula
2015-05-27 21:49 ` Joe Konno
2015-05-28 15:29   ` Damien Lespiau
2015-05-28 16:01     ` Daniel Vetter
2015-05-28 17:11       ` Joe Konno
2015-05-28 17:20         ` Damien Lespiau
2015-05-28 17:17       ` Jani Nikula
2015-05-28 17:28         ` Damien Lespiau
2015-05-28 17:40           ` Jani Nikula

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=20150529114525.GD28280@strange.ger.corp.intel.com \
    --to=damien.lespiau@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=mika.kahola@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.