diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5908580d7c15..981834b0f9b6 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -231,9 +231,6 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, | |||
231 | 231 | ||
232 | assert_spin_locked(&dev_priv->irq_lock); | 232 | assert_spin_locked(&dev_priv->irq_lock); |
233 | 233 | ||
234 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) | ||
235 | return; | ||
236 | |||
237 | new_val = dev_priv->pm_irq_mask; | 234 | new_val = dev_priv->pm_irq_mask; |
238 | new_val &= ~interrupt_mask; | 235 | new_val &= ~interrupt_mask; |
239 | new_val |= (~enabled_irq_mask & interrupt_mask); | 236 | new_val |= (~enabled_irq_mask & interrupt_mask); |
@@ -247,14 +244,26 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, | |||
247 | 244 | ||
248 | void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | 245 | void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
249 | { | 246 | { |
247 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) | ||
248 | return; | ||
249 | |||
250 | snb_update_pm_irq(dev_priv, mask, mask); | 250 | snb_update_pm_irq(dev_priv, mask, mask); |
251 | } | 251 | } |
252 | 252 | ||
253 | void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | 253 | static void __gen6_disable_pm_irq(struct drm_i915_private *dev_priv, |
254 | uint32_t mask) | ||
254 | { | 255 | { |
255 | snb_update_pm_irq(dev_priv, mask, 0); | 256 | snb_update_pm_irq(dev_priv, mask, 0); |
256 | } | 257 | } |
257 | 258 | ||
259 | void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | ||
260 | { | ||
261 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) | ||
262 | return; | ||
263 | |||
264 | __gen6_disable_pm_irq(dev_priv, mask); | ||
265 | } | ||
266 | |||
258 | void gen6_reset_rps_interrupts(struct drm_device *dev) | 267 | void gen6_reset_rps_interrupts(struct drm_device *dev) |
259 | { | 268 | { |
260 | struct drm_i915_private *dev_priv = dev->dev_private; | 269 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -289,16 +298,20 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) | |||
289 | 298 | ||
290 | cancel_work_sync(&dev_priv->rps.work); | 299 | cancel_work_sync(&dev_priv->rps.work); |
291 | 300 | ||
301 | spin_lock_irq(&dev_priv->irq_lock); | ||
302 | |||
292 | I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? | 303 | I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? |
293 | ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); | 304 | ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); |
305 | |||
306 | __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); | ||
294 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & | 307 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & |
295 | ~dev_priv->pm_rps_events); | 308 | ~dev_priv->pm_rps_events); |
309 | I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); | ||
310 | I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); | ||
296 | 311 | ||
297 | spin_lock_irq(&dev_priv->irq_lock); | ||
298 | dev_priv->rps.pm_iir = 0; | 312 | dev_priv->rps.pm_iir = 0; |
299 | spin_unlock_irq(&dev_priv->irq_lock); | ||
300 | 313 | ||
301 | I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); | 314 | spin_unlock_irq(&dev_priv->irq_lock); |
302 | } | 315 | } |
303 | 316 | ||
304 | /** | 317 | /** |
@@ -1339,10 +1352,8 @@ static void snb_gt_irq_handler(struct drm_device *dev, | |||
1339 | 1352 | ||
1340 | if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | | 1353 | if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | |
1341 | GT_BSD_CS_ERROR_INTERRUPT | | 1354 | GT_BSD_CS_ERROR_INTERRUPT | |
1342 | GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) { | 1355 | GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) |
1343 | i915_handle_error(dev, false, "GT error interrupt 0x%08x", | 1356 | DRM_DEBUG("Command parser error, gt_iir 0x%08x\n", gt_iir); |
1344 | gt_iir); | ||
1345 | } | ||
1346 | 1357 | ||
1347 | if (gt_iir & GT_PARITY_ERROR(dev)) | 1358 | if (gt_iir & GT_PARITY_ERROR(dev)) |
1348 | ivybridge_parity_error_irq_handler(dev, gt_iir); | 1359 | ivybridge_parity_error_irq_handler(dev, gt_iir); |
@@ -1623,7 +1634,7 @@ static void display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe, | |||
1623 | 1634 | ||
1624 | if (!pipe_crc->entries) { | 1635 | if (!pipe_crc->entries) { |
1625 | spin_unlock(&pipe_crc->lock); | 1636 | spin_unlock(&pipe_crc->lock); |
1626 | DRM_ERROR("spurious interrupt\n"); | 1637 | DRM_DEBUG_KMS("spurious interrupt\n"); |
1627 | return; | 1638 | return; |
1628 | } | 1639 | } |
1629 | 1640 | ||
@@ -1731,11 +1742,8 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | |||
1731 | if (pm_iir & PM_VEBOX_USER_INTERRUPT) | 1742 | if (pm_iir & PM_VEBOX_USER_INTERRUPT) |
1732 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); | 1743 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); |
1733 | 1744 | ||
1734 | if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { | 1745 | if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) |
1735 | i915_handle_error(dev_priv->dev, false, | 1746 | DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir); |
1736 | "VEBOX CS error interrupt 0x%08x", | ||
1737 | pm_iir); | ||
1738 | } | ||
1739 | } | 1747 | } |
1740 | } | 1748 | } |
1741 | 1749 | ||
@@ -2428,6 +2436,9 @@ static void i915_error_work_func(struct work_struct *work) | |||
2428 | * simulated reset via debugs, so get an RPM reference. | 2436 | * simulated reset via debugs, so get an RPM reference. |
2429 | */ | 2437 | */ |
2430 | intel_runtime_pm_get(dev_priv); | 2438 | intel_runtime_pm_get(dev_priv); |
2439 | |||
2440 | intel_prepare_reset(dev); | ||
2441 | |||
2431 | /* | 2442 | /* |
2432 | * All state reset _must_ be completed before we update the | 2443 | * All state reset _must_ be completed before we update the |
2433 | * reset counter, for otherwise waiters might miss the reset | 2444 | * reset counter, for otherwise waiters might miss the reset |
@@ -2436,7 +2447,7 @@ static void i915_error_work_func(struct work_struct *work) | |||
2436 | */ | 2447 | */ |
2437 | ret = i915_reset(dev); | 2448 | ret = i915_reset(dev); |
2438 | 2449 | ||
2439 | intel_display_handle_reset(dev); | 2450 | intel_finish_reset(dev); |
2440 | 2451 | ||
2441 | intel_runtime_pm_put(dev_priv); | 2452 | intel_runtime_pm_put(dev_priv); |
2442 | 2453 | ||
@@ -3746,9 +3757,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) | |||
3746 | */ | 3757 | */ |
3747 | spin_lock(&dev_priv->irq_lock); | 3758 | spin_lock(&dev_priv->irq_lock); |
3748 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | 3759 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3749 | i915_handle_error(dev, false, | 3760 | DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); |
3750 | "Command parser error, iir 0x%08x", | ||
3751 | iir); | ||
3752 | 3761 | ||
3753 | for_each_pipe(dev_priv, pipe) { | 3762 | for_each_pipe(dev_priv, pipe) { |
3754 | int reg = PIPESTAT(pipe); | 3763 | int reg = PIPESTAT(pipe); |
@@ -3929,9 +3938,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) | |||
3929 | */ | 3938 | */ |
3930 | spin_lock(&dev_priv->irq_lock); | 3939 | spin_lock(&dev_priv->irq_lock); |
3931 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | 3940 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3932 | i915_handle_error(dev, false, | 3941 | DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); |
3933 | "Command parser error, iir 0x%08x", | ||
3934 | iir); | ||
3935 | 3942 | ||
3936 | for_each_pipe(dev_priv, pipe) { | 3943 | for_each_pipe(dev_priv, pipe) { |
3937 | int reg = PIPESTAT(pipe); | 3944 | int reg = PIPESTAT(pipe); |
@@ -4154,9 +4161,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) | |||
4154 | */ | 4161 | */ |
4155 | spin_lock(&dev_priv->irq_lock); | 4162 | spin_lock(&dev_priv->irq_lock); |
4156 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | 4163 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
4157 | i915_handle_error(dev, false, | 4164 | DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); |
4158 | "Command parser error, iir 0x%08x", | ||
4159 | iir); | ||
4160 | 4165 | ||
4161 | for_each_pipe(dev_priv, pipe) { | 4166 | for_each_pipe(dev_priv, pipe) { |
4162 | int reg = PIPESTAT(pipe); | 4167 | int reg = PIPESTAT(pipe); |