diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-07-09 16:59:16 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-07-11 08:35:48 -0400 |
commit | 7336df6512440a494d3a705dfc6a883a42733c8f (patch) | |
tree | e95abefd980931b4c952751e0f62c7edc193a3b3 /drivers/gpu/drm/i915/i915_irq.c | |
parent | 1dd246fb165819d31119e988c2887934c255fadc (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.c | 20 |
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 | ||
156 | static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, | 156 | static 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 | ||
279 | done: | 285 | done: |
280 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | 286 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |