[Intel-gfx] [PATCH] drm/i915: Stop using RP_DOWN_EI on Baytrail

Chris Wilson chris at chris-wilson.co.uk
Wed Feb 22 12:05:30 UTC 2017


On Tue, Feb 21, 2017 at 06:22:02PM +0000, Chris Wilson wrote:
> On Baytrail, we manually calculate busyness over the evaluation interval
> to avoid issues with miscaluations with RC6 enabled. However, it turns
> out that the DOWN_EI interrupt generator is completely bust - it
> operates in two modes, continuous or never. Neither of which are
> conducive to good behaviour. Stop unmask the DOWN_EI interrupt and just
> compute everything from the UP_EI which does seem to correspond to the
> desired interval.
> 
> Fixes: 43cf3bf084ba ("drm/i915: Improved w/a for rps on Baytrail")
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Cc: <stable at vger.kernel.org> # v4.1+
> ---
>  drivers/gpu/drm/i915/i915_drv.h |  2 +-
>  drivers/gpu/drm/i915/i915_irq.c | 28 +++++++++-------------------
>  drivers/gpu/drm/i915/intel_pm.c |  2 +-
>  3 files changed, 11 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4e7046df1b5e..8190ab500e03 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1359,7 +1359,7 @@ struct intel_gen6_power_mgmt {
>  	unsigned boosts;
>  
>  	/* manual wa residency calculations */
> -	struct intel_rps_ei up_ei, down_ei;
> +	struct intel_rps_ei ei;
>  
>  	/*
>  	 * Protects RPS/RC6 register access and PCU communication.
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 57fa1bf78a85..09f6a190d363 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1048,10 +1048,10 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv,
>  }
>  
>  static bool vlv_c0_above(struct drm_i915_private *dev_priv,
> -			 const struct intel_rps_ei *old,
>  			 const struct intel_rps_ei *now,
>  			 int threshold)
>  {
> +	const struct intel_rps_ei *old = &dev_priv->rps.ei;
>  	u64 time, c0;
>  	unsigned int mul = 100;
>  
> @@ -1077,8 +1077,7 @@ static bool vlv_c0_above(struct drm_i915_private *dev_priv,
>  
>  void gen6_rps_reset_ei(struct drm_i915_private *dev_priv)
>  {
> -	vlv_c0_read(dev_priv, &dev_priv->rps.down_ei);
> -	dev_priv->rps.up_ei = dev_priv->rps.down_ei;
> +	memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei));
>  }
>  
>  static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
> @@ -1086,28 +1085,19 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
>  	struct intel_rps_ei now;
>  	u32 events = 0;
>  
> -	if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0)
> +	if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0)
>  		return 0;
>  
>  	vlv_c0_read(dev_priv, &now);
>  	if (now.cz_clock == 0)
>  		return 0;
>  
> -	if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) {
> -		if (!vlv_c0_above(dev_priv,
> -				  &dev_priv->rps.down_ei, &now,
> -				  dev_priv->rps.down_threshold))
> -			events |= GEN6_PM_RP_DOWN_THRESHOLD;
> -		dev_priv->rps.down_ei = now;
> -	}
> +	if (vlv_c0_above(dev_priv, &now, dev_priv->rps.up_threshold))
> +		events |= GEN6_PM_RP_UP_THRESHOLD;
> +	else if (!vlv_c0_above(dev_priv, &now, dev_priv->rps.down_threshold))
> +		events |= GEN6_PM_RP_DOWN_THRESHOLD;
>  
> -	if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) {
> -		if (vlv_c0_above(dev_priv,
> -				 &dev_priv->rps.up_ei, &now,
> -				 dev_priv->rps.up_threshold))
> -			events |= GEN6_PM_RP_UP_THRESHOLD;
> -		dev_priv->rps.up_ei = now;
> -	}
> +	dev_priv->rps.ei = now;
>  
>  	return events;
>  }
> @@ -4248,7 +4238,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
>  	/* Let's track the enabled rps events */
>  	if (IS_VALLEYVIEW(dev_priv))
>  		/* WaGsvRC0ResidencyMethod:vlv */
> -		dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED;
> +		dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED;
>  	else
>  		dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;

We also need to adjust gen6_rps_pm_mask() otherwise if we are at maxfreq
we disable GEN6_PM_RP_UP_EI_EXPIRED and rely on
GEN6_PM_RP_DOWN_EI_EXPIRED, which is not now used.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the Intel-gfx mailing list