diff mbox series

[2/5] drm/i915: Read actual GPU frequency from MEMSTAT_ILK on ILK

Message ID 20201021131443.25616-2-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series [1/5] drm/i915: Restore ILK-M RPS support | expand

Commit Message

Ville Syrjälä Oct. 21, 2020, 1:14 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

There is no GEN6_RPSTAT1 on ILK. Instead of reading that let's
try to get the same information from MEMSTAT_ILK. At least it
seems to track MEMSWCTL frequency request perfectly on my ILK.
It needs the same invert trick as the request value.

We don't want to put the invert thing into intel_gpu_freq()
and intel_freq_opcode() because that would incorrectly invert
the min/max/etc frequencies also.

One day someone might want to reverse engineer the formula for
converting these numvers to Hz, but for now we'll just report
them raw.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/gt/intel_rps.c | 31 +++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

Comments

Chris Wilson Oct. 21, 2020, 5:36 p.m. UTC | #1
Quoting Ville Syrjala (2020-10-21 14:14:40)
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> There is no GEN6_RPSTAT1 on ILK. Instead of reading that let's
> try to get the same information from MEMSTAT_ILK. At least it
> seems to track MEMSWCTL frequency request perfectly on my ILK.
> It needs the same invert trick as the request value.
> 
> We don't want to put the invert thing into intel_gpu_freq()
> and intel_freq_opcode() because that would incorrectly invert
> the min/max/etc frequencies also.
> 
> One day someone might want to reverse engineer the formula for
> converting these numvers to Hz, but for now we'll just report
> them raw.

Raw. That'll be a nuisance, but a step forward.
 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gt/intel_rps.c | 31 +++++++++++++++++++++++------
>  1 file changed, 25 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c
> index a53928363b86..e0db7541dbfa 100644
> --- a/drivers/gpu/drm/i915/gt/intel_rps.c
> +++ b/drivers/gpu/drm/i915/gt/intel_rps.c
> @@ -390,6 +390,16 @@ static void gen5_rps_update(struct intel_rps *rps)
>         spin_unlock_irq(&mchdev_lock);
>  }
>  
> +static unsigned int gen5_invert_freq(struct intel_rps *rps,
> +                                    unsigned int val)
> +{
> +       /* Invert the frequency bin into an ips delay */
> +       val = rps->max_freq - val;
> +       val = rps->min_freq + val;
> +
> +       return val;
> +}
> +
>  static bool gen5_rps_set(struct intel_rps *rps, u8 val)
>  {
>         struct intel_uncore *uncore = rps_to_uncore(rps);
> @@ -404,8 +414,7 @@ static bool gen5_rps_set(struct intel_rps *rps, u8 val)
>         }
>  
>         /* Invert the frequency bin into an ips delay */
> -       val = rps->max_freq - val;
> -       val = rps->min_freq + val;
> +       val = gen5_invert_freq(rps, val);
>  
>         rgvswctl =
>                 (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
> @@ -1432,8 +1441,10 @@ int intel_gpu_freq(struct intel_rps *rps, int val)
>                 return chv_gpu_freq(rps, val);
>         else if (IS_VALLEYVIEW(i915))
>                 return byt_gpu_freq(rps, val);
> -       else
> +       else if (INTEL_GEN(i915) >= 6)
>                 return val * GT_FREQUENCY_MULTIPLIER;
> +       else
> +               return val;
>  }
>  
>  int intel_freq_opcode(struct intel_rps *rps, int val)
> @@ -1447,8 +1458,10 @@ int intel_freq_opcode(struct intel_rps *rps, int val)
>                 return chv_freq_opcode(rps, val);
>         else if (IS_VALLEYVIEW(i915))
>                 return byt_freq_opcode(rps, val);
> -       else
> +       else if (INTEL_GEN(i915) >= 6)
>                 return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER);
> +       else
> +               return val;
>  }
>  
>  static void vlv_init_gpll_ref_freq(struct intel_rps *rps)
> @@ -1864,8 +1877,11 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
>                 cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
>         else if (IS_HASWELL(i915) || IS_BROADWELL(i915))
>                 cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
> -       else
> +       else if (INTEL_GEN(i915) >= 6)
>                 cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
> +       else
> +               cagf = gen5_invert_freq(rps, (rpstat & MEMSTAT_PSTATE_MASK) >>
> +                                       MEMSTAT_PSTATE_SHIFT);
>  
>         return cagf;
>  }
> @@ -1873,14 +1889,17 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
>  static u32 read_cagf(struct intel_rps *rps)
>  {
>         struct drm_i915_private *i915 = rps_to_i915(rps);
> +       struct intel_uncore *uncore = rps_to_uncore(rps);
>         u32 freq;
>  
>         if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
>                 vlv_punit_get(i915);
>                 freq = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
>                 vlv_punit_put(i915);
> +       } else if (INTEL_GEN(i915) >= 6) {
> +               freq = intel_uncore_read(uncore, GEN6_RPSTAT1);
>         } else {
> -               freq = intel_uncore_read(rps_to_uncore(rps), GEN6_RPSTAT1);
> +               freq = intel_uncore_read(uncore, MEMSTAT_ILK);
>         }

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
Chris Wilson Oct. 21, 2020, 8:44 p.m. UTC | #2
Quoting Chris Wilson (2020-10-21 18:36:00)
> Quoting Ville Syrjala (2020-10-21 14:14:40)
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > There is no GEN6_RPSTAT1 on ILK. Instead of reading that let's
> > try to get the same information from MEMSTAT_ILK. At least it
> > seems to track MEMSWCTL frequency request perfectly on my ILK.
> > It needs the same invert trick as the request value.
> > 
> > We don't want to put the invert thing into intel_gpu_freq()
> > and intel_freq_opcode() because that would incorrectly invert
> > the min/max/etc frequencies also.
> > 
> > One day someone might want to reverse engineer the formula for
> > converting these numvers to Hz, but for now we'll just report
> > them raw.
> 
> Raw. That'll be a nuisance, but a step forward.

I should note that currently these are only hooked up to the debug
interfaces, and not sysfs, so raw is "good enough" and should not be
user visible.
-Chris
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c
index a53928363b86..e0db7541dbfa 100644
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -390,6 +390,16 @@  static void gen5_rps_update(struct intel_rps *rps)
 	spin_unlock_irq(&mchdev_lock);
 }
 
+static unsigned int gen5_invert_freq(struct intel_rps *rps,
+				     unsigned int val)
+{
+	/* Invert the frequency bin into an ips delay */
+	val = rps->max_freq - val;
+	val = rps->min_freq + val;
+
+	return val;
+}
+
 static bool gen5_rps_set(struct intel_rps *rps, u8 val)
 {
 	struct intel_uncore *uncore = rps_to_uncore(rps);
@@ -404,8 +414,7 @@  static bool gen5_rps_set(struct intel_rps *rps, u8 val)
 	}
 
 	/* Invert the frequency bin into an ips delay */
-	val = rps->max_freq - val;
-	val = rps->min_freq + val;
+	val = gen5_invert_freq(rps, val);
 
 	rgvswctl =
 		(MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
@@ -1432,8 +1441,10 @@  int intel_gpu_freq(struct intel_rps *rps, int val)
 		return chv_gpu_freq(rps, val);
 	else if (IS_VALLEYVIEW(i915))
 		return byt_gpu_freq(rps, val);
-	else
+	else if (INTEL_GEN(i915) >= 6)
 		return val * GT_FREQUENCY_MULTIPLIER;
+	else
+		return val;
 }
 
 int intel_freq_opcode(struct intel_rps *rps, int val)
@@ -1447,8 +1458,10 @@  int intel_freq_opcode(struct intel_rps *rps, int val)
 		return chv_freq_opcode(rps, val);
 	else if (IS_VALLEYVIEW(i915))
 		return byt_freq_opcode(rps, val);
-	else
+	else if (INTEL_GEN(i915) >= 6)
 		return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER);
+	else
+		return val;
 }
 
 static void vlv_init_gpll_ref_freq(struct intel_rps *rps)
@@ -1864,8 +1877,11 @@  u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
 		cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
 	else if (IS_HASWELL(i915) || IS_BROADWELL(i915))
 		cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
-	else
+	else if (INTEL_GEN(i915) >= 6)
 		cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
+	else
+		cagf = gen5_invert_freq(rps, (rpstat & MEMSTAT_PSTATE_MASK) >>
+					MEMSTAT_PSTATE_SHIFT);
 
 	return cagf;
 }
@@ -1873,14 +1889,17 @@  u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
 static u32 read_cagf(struct intel_rps *rps)
 {
 	struct drm_i915_private *i915 = rps_to_i915(rps);
+	struct intel_uncore *uncore = rps_to_uncore(rps);
 	u32 freq;
 
 	if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
 		vlv_punit_get(i915);
 		freq = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
 		vlv_punit_put(i915);
+	} else if (INTEL_GEN(i915) >= 6) {
+		freq = intel_uncore_read(uncore, GEN6_RPSTAT1);
 	} else {
-		freq = intel_uncore_read(rps_to_uncore(rps), GEN6_RPSTAT1);
+		freq = intel_uncore_read(uncore, MEMSTAT_ILK);
 	}
 
 	return intel_rps_get_cagf(rps, freq);