diff mbox

[03/67] drm/i915/cnp: Get/set proper Raw clock frequency on CNP.

Message ID 1491506163-14587-3-git-send-email-rodrigo.vivi@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Rodrigo Vivi April 6, 2017, 7:14 p.m. UTC
RAWCLK_FREQ register has changed for platforms with CNP+.

[29:26] This field provides the denominator for the fractional
	part of the microsecond counter divider.  The numerator
	is fixed at 1. Program this field to the denominator of
	the fractional portion of reference frequency minus one.
	If the fraction is 0, program to 0.
	0100b = Fraction .2 MHz = Fraction 1/5.
	0000b = Fraction .0 MHz.

[25:16] This field provides the integer part of the microsecond
	counter divider. Program this field to the integer portion
	of the reference frequenct minus one.

Also this register tells us that proper raw clock should be read
from SFUSE_STRAP and programmed to this register. Up to this point
on other platforms we are reading instead of programming it so
probably relying on whatever BIOS had configured here.

Now on let's follow the spec and also program this register
fetching the right value from SFUSE_STRAP as Spec tells us to do.

v2: Read from SFUSE_STRAP and Program RAWCLK_FREQ instead of
    reading the value relying someone else will program that
    for us.
v3: Add missing else. (Jani)
v4: Addressing all Ville's catches:
    Use macro for shift bits instead of defining shift.
    Remove shift from the cleaning bits with mask that already
    has it.
    Add missing I915_WRITE to actually write the reg.
    Stop using useless DIV_ROUND_* on divider that is exact
    dividion and use DIV_ROUND_CLOSEST for the fraction part.
v5: Remove useless Read-Modify-Write on raclk_freq reg. (Ville).
v6: Change is per PCH instead of per platform.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h    |  5 +++++
 drivers/gpu/drm/i915/intel_cdclk.c | 29 ++++++++++++++++++++++++++++-
 2 files changed, 33 insertions(+), 1 deletion(-)

Comments

Ville Syrjälä April 7, 2017, 1:45 p.m. UTC | #1
On Thu, Apr 06, 2017 at 12:14:59PM -0700, Rodrigo Vivi wrote:
> RAWCLK_FREQ register has changed for platforms with CNP+.
> 
> [29:26] This field provides the denominator for the fractional
> 	part of the microsecond counter divider.  The numerator
> 	is fixed at 1. Program this field to the denominator of
> 	the fractional portion of reference frequency minus one.
> 	If the fraction is 0, program to 0.
> 	0100b = Fraction .2 MHz = Fraction 1/5.
> 	0000b = Fraction .0 MHz.
> 
> [25:16] This field provides the integer part of the microsecond
> 	counter divider. Program this field to the integer portion
> 	of the reference frequenct minus one.
> 
> Also this register tells us that proper raw clock should be read
> from SFUSE_STRAP and programmed to this register. Up to this point
> on other platforms we are reading instead of programming it so
> probably relying on whatever BIOS had configured here.
> 
> Now on let's follow the spec and also program this register
> fetching the right value from SFUSE_STRAP as Spec tells us to do.
> 
> v2: Read from SFUSE_STRAP and Program RAWCLK_FREQ instead of
>     reading the value relying someone else will program that
>     for us.
> v3: Add missing else. (Jani)
> v4: Addressing all Ville's catches:
>     Use macro for shift bits instead of defining shift.
>     Remove shift from the cleaning bits with mask that already
>     has it.
>     Add missing I915_WRITE to actually write the reg.
>     Stop using useless DIV_ROUND_* on divider that is exact
>     dividion and use DIV_ROUND_CLOSEST for the fraction part.
> v5: Remove useless Read-Modify-Write on raclk_freq reg. (Ville).
> v6: Change is per PCH instead of per platform.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/i915_reg.h    |  5 +++++
>  drivers/gpu/drm/i915/intel_cdclk.c | 29 ++++++++++++++++++++++++++++-
>  2 files changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 11b12f4..6826547 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6836,6 +6836,10 @@ enum {
>  #define  FDL_TP2_TIMER_SHIFT    10
>  #define  FDL_TP2_TIMER_MASK     (3<<10)
>  #define  RAWCLK_FREQ_MASK       0x3ff
> +#define  CNP_RAWCLK_DIV_MASK	(0x3ff << 16)
> +#define  CNP_RAWCLK_DIV(div)	((div) << 16)
> +#define  CNP_RAWCLK_FRAC_MASK	(0xf << 26)
> +#define  CNP_RAWCLK_FRAC(frac)	((frac) << 26)
>  
>  #define PCH_DPLL_TMR_CFG        _MMIO(0xc6208)
>  
> @@ -8146,6 +8150,7 @@ enum {
>  /* SFUSE_STRAP */
>  #define SFUSE_STRAP			_MMIO(0xc2014)
>  #define  SFUSE_STRAP_FUSE_LOCK		(1<<13)
> +#define  SFUSE_STRAP_RAW_FREQUENCY	(1<<8)
>  #define  SFUSE_STRAP_DISPLAY_DISABLED	(1<<7)
>  #define  SFUSE_STRAP_CRT_DISABLED	(1<<6)
>  #define  SFUSE_STRAP_DDIB_DETECTED	(1<<2)
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index 763010f..4745596 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -1780,6 +1780,30 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv)
>  			   DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000));
>  }
>  
> +static int cnp_rawclk(struct drm_i915_private *dev_priv)
> +{
> +	u32 rawclk;
> +	int divider, fraction;
> +
> +	if (I915_READ(SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) {
> +		/* 24 MHz */
> +		divider = 24000;
> +		fraction = 0;
> +	} else {
> +		/* 19.2 MHz */
> +		divider = 19000;
> +		fraction = 200;
> +	}
> +
> +	rawclk = CNP_RAWCLK_DIV((divider / 1000) - 1);
> +	if (fraction)
> +		rawclk |= CNP_RAWCLK_FRAC(DIV_ROUND_CLOSEST(1000,
> +							    fraction) - 1);
> +
> +	I915_WRITE(PCH_RAWCLK_FREQ, rawclk);
> +	return divider + fraction;
> +}
> +
>  static int pch_rawclk(struct drm_i915_private *dev_priv)
>  {
>  	return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
> @@ -1829,7 +1853,10 @@ static int g4x_hrawclk(struct drm_i915_private *dev_priv)
>   */
>  void intel_update_rawclk(struct drm_i915_private *dev_priv)
>  {
> -	if (HAS_PCH_SPLIT(dev_priv))
> +
> +	if (HAS_PCH_CNP(dev_priv))
> +		dev_priv->rawclk_freq = cnp_rawclk(dev_priv);
> +	else if (HAS_PCH_SPLIT(dev_priv))
>  		dev_priv->rawclk_freq = pch_rawclk(dev_priv);
>  	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
>  		dev_priv->rawclk_freq = vlv_hrawclk(dev_priv);
> -- 
> 1.9.1
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 11b12f4..6826547 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6836,6 +6836,10 @@  enum {
 #define  FDL_TP2_TIMER_SHIFT    10
 #define  FDL_TP2_TIMER_MASK     (3<<10)
 #define  RAWCLK_FREQ_MASK       0x3ff
+#define  CNP_RAWCLK_DIV_MASK	(0x3ff << 16)
+#define  CNP_RAWCLK_DIV(div)	((div) << 16)
+#define  CNP_RAWCLK_FRAC_MASK	(0xf << 26)
+#define  CNP_RAWCLK_FRAC(frac)	((frac) << 26)
 
 #define PCH_DPLL_TMR_CFG        _MMIO(0xc6208)
 
@@ -8146,6 +8150,7 @@  enum {
 /* SFUSE_STRAP */
 #define SFUSE_STRAP			_MMIO(0xc2014)
 #define  SFUSE_STRAP_FUSE_LOCK		(1<<13)
+#define  SFUSE_STRAP_RAW_FREQUENCY	(1<<8)
 #define  SFUSE_STRAP_DISPLAY_DISABLED	(1<<7)
 #define  SFUSE_STRAP_CRT_DISABLED	(1<<6)
 #define  SFUSE_STRAP_DDIB_DETECTED	(1<<2)
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 763010f..4745596 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1780,6 +1780,30 @@  void intel_update_cdclk(struct drm_i915_private *dev_priv)
 			   DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000));
 }
 
+static int cnp_rawclk(struct drm_i915_private *dev_priv)
+{
+	u32 rawclk;
+	int divider, fraction;
+
+	if (I915_READ(SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) {
+		/* 24 MHz */
+		divider = 24000;
+		fraction = 0;
+	} else {
+		/* 19.2 MHz */
+		divider = 19000;
+		fraction = 200;
+	}
+
+	rawclk = CNP_RAWCLK_DIV((divider / 1000) - 1);
+	if (fraction)
+		rawclk |= CNP_RAWCLK_FRAC(DIV_ROUND_CLOSEST(1000,
+							    fraction) - 1);
+
+	I915_WRITE(PCH_RAWCLK_FREQ, rawclk);
+	return divider + fraction;
+}
+
 static int pch_rawclk(struct drm_i915_private *dev_priv)
 {
 	return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
@@ -1829,7 +1853,10 @@  static int g4x_hrawclk(struct drm_i915_private *dev_priv)
  */
 void intel_update_rawclk(struct drm_i915_private *dev_priv)
 {
-	if (HAS_PCH_SPLIT(dev_priv))
+
+	if (HAS_PCH_CNP(dev_priv))
+		dev_priv->rawclk_freq = cnp_rawclk(dev_priv);
+	else if (HAS_PCH_SPLIT(dev_priv))
 		dev_priv->rawclk_freq = pch_rawclk(dev_priv);
 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
 		dev_priv->rawclk_freq = vlv_hrawclk(dev_priv);