From: Ville Syrjälä <ville.syrj...@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.syrj...@linux.intel.com>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to