aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-07-09 16:59:16 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-07-11 08:35:48 -0400
commit7336df6512440a494d3a705dfc6a883a42733c8f (patch)
treee95abefd980931b4c952751e0f62c7edc193a3b3 /drivers/gpu/drm/i915/i915_irq.c
parent1dd246fb165819d31119e988c2887934c255fadc (diff)
drm/i915: improve GEN7_ERR_INT clearing for fifo underrun reporting
Same treatment as for SERR_INT: If we clear only the bit for the pipe we're enabling (but unconditionally) then we can always check for possible underruns after having disabled the interrupt. That way pipe underruns won't be lost, but at worst only get reported in a delayed fashion. v2: The same logic bug as in the SERR handling change also existed here. The same bugfix of only reporting missed underruns when the error interrupt was masked applies, too. v3: Do the same fixes as for the SERR handling that Paulo suggested in his review: - s/%i/%c/ fix in the debug output - move the DE_ERR_INT_IVB read into the respective if block Cc: Paulo Zanoni <przanoni@gmail.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> [danvet: Fix up the checkpatch bikeshed Paulo noticed.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index dd9d9997e90b..76e977b0070e 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -154,21 +154,27 @@ static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
154} 154}
155 155
156static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, 156static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
157 bool enable) 157 enum pipe pipe, bool enable)
158{ 158{
159 struct drm_i915_private *dev_priv = dev->dev_private; 159 struct drm_i915_private *dev_priv = dev->dev_private;
160
161 if (enable) { 160 if (enable) {
161 I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
162
162 if (!ivb_can_enable_err_int(dev)) 163 if (!ivb_can_enable_err_int(dev))
163 return; 164 return;
164 165
165 I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN_A |
166 ERR_INT_FIFO_UNDERRUN_B |
167 ERR_INT_FIFO_UNDERRUN_C);
168
169 ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); 166 ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
170 } else { 167 } else {
168 bool was_enabled = !(I915_READ(DEIMR) & DE_ERR_INT_IVB);
169
170 /* Change the state _after_ we've read out the current one. */
171 ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); 171 ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
172
173 if (!was_enabled &&
174 (I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe))) {
175 DRM_DEBUG_KMS("uncleared fifo underrun on pipe %c\n",
176 pipe_name(pipe));
177 }
172 } 178 }
173} 179}
174 180
@@ -274,7 +280,7 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
274 if (IS_GEN5(dev) || IS_GEN6(dev)) 280 if (IS_GEN5(dev) || IS_GEN6(dev))
275 ironlake_set_fifo_underrun_reporting(dev, pipe, enable); 281 ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
276 else if (IS_GEN7(dev)) 282 else if (IS_GEN7(dev))
277 ivybridge_set_fifo_underrun_reporting(dev, enable); 283 ivybridge_set_fifo_underrun_reporting(dev, pipe, enable);
278 284
279done: 285done:
280 spin_unlock_irqrestore(&dev_priv->irq_lock, flags); 286 spin_unlock_irqrestore(&dev_priv->irq_lock, flags);