[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