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

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Fri Jan 17 10:44:33 CET 2014


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>
---
 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




More information about the Intel-gfx mailing list