[Intel-gfx] [PATCH 3/3] drm/i915: Re-enable underrun reporting after 2 secs

Daniel Vetter daniel at ffwll.ch
Fri Jan 17 18:00:13 CET 2014


On Fri, Jan 17, 2014 at 11:44:33AM +0200, ville.syrjala at linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> I'm interested in underruns so having the totally off is not good. After
> disabling underruns, re-enable them after 2 seconds. I just added one
> timer for this, even though we should have one for each PCH and CPU,
> or maybe even per pipe/transcoder, but then we should track underrun
> disable also per pipe/transcoder.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>

The kernel has some neat ratelimiting stuff in ratelimit.h. You've looked
into that? Open coding timer code always freaks me out a bit because of
the bazillion ways you can screw up jiffy handling ;-)
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_drv.h |  1 +
>  drivers/gpu/drm/i915/i915_irq.c | 29 +++++++++++++++++++++++++++++
>  2 files changed, 30 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 283e875..0f4c346 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1419,6 +1419,7 @@ typedef struct drm_i915_private {
>  	} hpd_stats[HPD_NUM_PINS];
>  	u32 hpd_event_bits;
>  	struct timer_list hotplug_reenable_timer;
> +	struct timer_list underrun_reenable_timer;
>  
>  	int num_plane;
>  
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 391cacd..849f4a6 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -416,6 +416,10 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
>  
>  done:
>  	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
> +
> +	if (!enable && ret)
> +		mod_timer(&dev_priv->underrun_reenable_timer, jiffies + 2 * HZ);
> +
>  	return ret;
>  }
>  
> @@ -468,9 +472,24 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
>  
>  done:
>  	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
> +
> +	if (!enable && ret)
> +		mod_timer(&dev_priv->underrun_reenable_timer, jiffies + 2 * HZ);
> +
>  	return ret;
>  }
>  
> +static void i915_underrun_reenable(unsigned long data)
> +{
> +	struct drm_device *dev = (struct drm_device *)data;
> +	enum pipe pipe;
> +
> +	for_each_pipe(pipe) {
> +		if (HAS_PCH_SPLIT(dev))
> +			intel_set_pch_fifo_underrun_reporting(dev, pipe, true);
> +		intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
> +	}
> +}
>  
>  void
>  i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask)
> @@ -3003,6 +3022,7 @@ static void gen8_irq_uninstall(struct drm_device *dev)
>  	if (!dev_priv)
>  		return;
>  
> +	del_timer_sync(&dev_priv->underrun_reenable_timer);
>  	del_timer_sync(&dev_priv->hotplug_reenable_timer);
>  
>  	I915_WRITE(GEN8_MASTER_IRQ, 0);
> @@ -3045,6 +3065,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
>  	if (!dev_priv)
>  		return;
>  
> +	del_timer_sync(&dev_priv->underrun_reenable_timer);
>  	del_timer_sync(&dev_priv->hotplug_reenable_timer);
>  
>  	for_each_pipe(pipe)
> @@ -3068,6 +3089,7 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
>  	if (!dev_priv)
>  		return;
>  
> +	del_timer_sync(&dev_priv->underrun_reenable_timer);
>  	del_timer_sync(&dev_priv->hotplug_reenable_timer);
>  
>  	I915_WRITE(HWSTAM, 0xffffffff);
> @@ -3243,6 +3265,8 @@ static void i8xx_irq_uninstall(struct drm_device * dev)
>  	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>  	int pipe;
>  
> +	del_timer_sync(&dev_priv->underrun_reenable_timer);
> +
>  	for_each_pipe(pipe) {
>  		/* Clear enable bits; then clear status bits */
>  		I915_WRITE(PIPESTAT(pipe), 0);
> @@ -3465,6 +3489,7 @@ static void i915_irq_uninstall(struct drm_device * dev)
>  	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>  	int pipe;
>  
> +	del_timer_sync(&dev_priv->underrun_reenable_timer);
>  	del_timer_sync(&dev_priv->hotplug_reenable_timer);
>  
>  	if (I915_HAS_HOTPLUG(dev)) {
> @@ -3718,6 +3743,7 @@ static void i965_irq_uninstall(struct drm_device * dev)
>  	if (!dev_priv)
>  		return;
>  
> +	del_timer_sync(&dev_priv->underrun_reenable_timer);
>  	del_timer_sync(&dev_priv->hotplug_reenable_timer);
>  
>  	I915_WRITE(PORT_HOTPLUG_EN, 0);
> @@ -3779,6 +3805,9 @@ void intel_irq_init(struct drm_device *dev)
>  	INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
>  	INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
>  
> +	setup_timer(&dev_priv->underrun_reenable_timer,
> +		    i915_underrun_reenable,
> +		    (unsigned long) dev);
>  	setup_timer(&dev_priv->gpu_error.hangcheck_timer,
>  		    i915_hangcheck_elapsed,
>  		    (unsigned long) dev);
> -- 
> 1.8.3.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch



More information about the Intel-gfx mailing list