diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 223 |
1 files changed, 111 insertions, 112 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5fff2870a17b..5908580d7c15 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -138,6 +138,8 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */ | |||
138 | POSTING_READ(type##IMR); \ | 138 | POSTING_READ(type##IMR); \ |
139 | } while (0) | 139 | } while (0) |
140 | 140 | ||
141 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); | ||
142 | |||
141 | /* For display hotplug interrupt */ | 143 | /* For display hotplug interrupt */ |
142 | void | 144 | void |
143 | ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask) | 145 | ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask) |
@@ -200,6 +202,21 @@ void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) | |||
200 | ilk_update_gt_irq(dev_priv, mask, 0); | 202 | ilk_update_gt_irq(dev_priv, mask, 0); |
201 | } | 203 | } |
202 | 204 | ||
205 | static u32 gen6_pm_iir(struct drm_i915_private *dev_priv) | ||
206 | { | ||
207 | return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; | ||
208 | } | ||
209 | |||
210 | static u32 gen6_pm_imr(struct drm_i915_private *dev_priv) | ||
211 | { | ||
212 | return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR; | ||
213 | } | ||
214 | |||
215 | static u32 gen6_pm_ier(struct drm_i915_private *dev_priv) | ||
216 | { | ||
217 | return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER; | ||
218 | } | ||
219 | |||
203 | /** | 220 | /** |
204 | * snb_update_pm_irq - update GEN6_PMIMR | 221 | * snb_update_pm_irq - update GEN6_PMIMR |
205 | * @dev_priv: driver private | 222 | * @dev_priv: driver private |
@@ -223,8 +240,8 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, | |||
223 | 240 | ||
224 | if (new_val != dev_priv->pm_irq_mask) { | 241 | if (new_val != dev_priv->pm_irq_mask) { |
225 | dev_priv->pm_irq_mask = new_val; | 242 | dev_priv->pm_irq_mask = new_val; |
226 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask); | 243 | I915_WRITE(gen6_pm_imr(dev_priv), dev_priv->pm_irq_mask); |
227 | POSTING_READ(GEN6_PMIMR); | 244 | POSTING_READ(gen6_pm_imr(dev_priv)); |
228 | } | 245 | } |
229 | } | 246 | } |
230 | 247 | ||
@@ -238,44 +255,50 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | |||
238 | snb_update_pm_irq(dev_priv, mask, 0); | 255 | snb_update_pm_irq(dev_priv, mask, 0); |
239 | } | 256 | } |
240 | 257 | ||
241 | /** | 258 | void gen6_reset_rps_interrupts(struct drm_device *dev) |
242 | * bdw_update_pm_irq - update GT interrupt 2 | ||
243 | * @dev_priv: driver private | ||
244 | * @interrupt_mask: mask of interrupt bits to update | ||
245 | * @enabled_irq_mask: mask of interrupt bits to enable | ||
246 | * | ||
247 | * Copied from the snb function, updated with relevant register offsets | ||
248 | */ | ||
249 | static void bdw_update_pm_irq(struct drm_i915_private *dev_priv, | ||
250 | uint32_t interrupt_mask, | ||
251 | uint32_t enabled_irq_mask) | ||
252 | { | 259 | { |
253 | uint32_t new_val; | 260 | struct drm_i915_private *dev_priv = dev->dev_private; |
254 | 261 | uint32_t reg = gen6_pm_iir(dev_priv); | |
255 | assert_spin_locked(&dev_priv->irq_lock); | ||
256 | |||
257 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) | ||
258 | return; | ||
259 | |||
260 | new_val = dev_priv->pm_irq_mask; | ||
261 | new_val &= ~interrupt_mask; | ||
262 | new_val |= (~enabled_irq_mask & interrupt_mask); | ||
263 | 262 | ||
264 | if (new_val != dev_priv->pm_irq_mask) { | 263 | spin_lock_irq(&dev_priv->irq_lock); |
265 | dev_priv->pm_irq_mask = new_val; | 264 | I915_WRITE(reg, dev_priv->pm_rps_events); |
266 | I915_WRITE(GEN8_GT_IMR(2), dev_priv->pm_irq_mask); | 265 | I915_WRITE(reg, dev_priv->pm_rps_events); |
267 | POSTING_READ(GEN8_GT_IMR(2)); | 266 | POSTING_READ(reg); |
268 | } | 267 | spin_unlock_irq(&dev_priv->irq_lock); |
269 | } | 268 | } |
270 | 269 | ||
271 | void gen8_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | 270 | void gen6_enable_rps_interrupts(struct drm_device *dev) |
272 | { | 271 | { |
273 | bdw_update_pm_irq(dev_priv, mask, mask); | 272 | struct drm_i915_private *dev_priv = dev->dev_private; |
273 | |||
274 | spin_lock_irq(&dev_priv->irq_lock); | ||
275 | WARN_ON(dev_priv->rps.pm_iir); | ||
276 | WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); | ||
277 | dev_priv->rps.interrupts_enabled = true; | ||
278 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); | ||
279 | spin_unlock_irq(&dev_priv->irq_lock); | ||
274 | } | 280 | } |
275 | 281 | ||
276 | void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | 282 | void gen6_disable_rps_interrupts(struct drm_device *dev) |
277 | { | 283 | { |
278 | bdw_update_pm_irq(dev_priv, mask, 0); | 284 | struct drm_i915_private *dev_priv = dev->dev_private; |
285 | |||
286 | spin_lock_irq(&dev_priv->irq_lock); | ||
287 | dev_priv->rps.interrupts_enabled = false; | ||
288 | spin_unlock_irq(&dev_priv->irq_lock); | ||
289 | |||
290 | cancel_work_sync(&dev_priv->rps.work); | ||
291 | |||
292 | I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? | ||
293 | ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); | ||
294 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & | ||
295 | ~dev_priv->pm_rps_events); | ||
296 | |||
297 | spin_lock_irq(&dev_priv->irq_lock); | ||
298 | dev_priv->rps.pm_iir = 0; | ||
299 | spin_unlock_irq(&dev_priv->irq_lock); | ||
300 | |||
301 | I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); | ||
279 | } | 302 | } |
280 | 303 | ||
281 | /** | 304 | /** |
@@ -980,7 +1003,6 @@ static void notify_ring(struct drm_device *dev, | |||
980 | trace_i915_gem_request_complete(ring); | 1003 | trace_i915_gem_request_complete(ring); |
981 | 1004 | ||
982 | wake_up_all(&ring->irq_queue); | 1005 | wake_up_all(&ring->irq_queue); |
983 | i915_queue_hangcheck(dev); | ||
984 | } | 1006 | } |
985 | 1007 | ||
986 | static u32 vlv_c0_residency(struct drm_i915_private *dev_priv, | 1008 | static u32 vlv_c0_residency(struct drm_i915_private *dev_priv, |
@@ -1116,14 +1138,15 @@ static void gen6_pm_rps_work(struct work_struct *work) | |||
1116 | int new_delay, adj; | 1138 | int new_delay, adj; |
1117 | 1139 | ||
1118 | spin_lock_irq(&dev_priv->irq_lock); | 1140 | spin_lock_irq(&dev_priv->irq_lock); |
1141 | /* Speed up work cancelation during disabling rps interrupts. */ | ||
1142 | if (!dev_priv->rps.interrupts_enabled) { | ||
1143 | spin_unlock_irq(&dev_priv->irq_lock); | ||
1144 | return; | ||
1145 | } | ||
1119 | pm_iir = dev_priv->rps.pm_iir; | 1146 | pm_iir = dev_priv->rps.pm_iir; |
1120 | dev_priv->rps.pm_iir = 0; | 1147 | dev_priv->rps.pm_iir = 0; |
1121 | if (INTEL_INFO(dev_priv->dev)->gen >= 8) | 1148 | /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ |
1122 | gen8_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 1149 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
1123 | else { | ||
1124 | /* Make sure not to corrupt PMIMR state used by ringbuffer */ | ||
1125 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); | ||
1126 | } | ||
1127 | spin_unlock_irq(&dev_priv->irq_lock); | 1150 | spin_unlock_irq(&dev_priv->irq_lock); |
1128 | 1151 | ||
1129 | /* Make sure we didn't queue anything we're not going to process. */ | 1152 | /* Make sure we didn't queue anything we're not going to process. */ |
@@ -1325,19 +1348,6 @@ static void snb_gt_irq_handler(struct drm_device *dev, | |||
1325 | ivybridge_parity_error_irq_handler(dev, gt_iir); | 1348 | ivybridge_parity_error_irq_handler(dev, gt_iir); |
1326 | } | 1349 | } |
1327 | 1350 | ||
1328 | static void gen8_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | ||
1329 | { | ||
1330 | if ((pm_iir & dev_priv->pm_rps_events) == 0) | ||
1331 | return; | ||
1332 | |||
1333 | spin_lock(&dev_priv->irq_lock); | ||
1334 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; | ||
1335 | gen8_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); | ||
1336 | spin_unlock(&dev_priv->irq_lock); | ||
1337 | |||
1338 | queue_work(dev_priv->wq, &dev_priv->rps.work); | ||
1339 | } | ||
1340 | |||
1341 | static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, | 1351 | static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, |
1342 | struct drm_i915_private *dev_priv, | 1352 | struct drm_i915_private *dev_priv, |
1343 | u32 master_ctl) | 1353 | u32 master_ctl) |
@@ -1399,7 +1409,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, | |||
1399 | I915_WRITE(GEN8_GT_IIR(2), | 1409 | I915_WRITE(GEN8_GT_IIR(2), |
1400 | tmp & dev_priv->pm_rps_events); | 1410 | tmp & dev_priv->pm_rps_events); |
1401 | ret = IRQ_HANDLED; | 1411 | ret = IRQ_HANDLED; |
1402 | gen8_rps_irq_handler(dev_priv, tmp); | 1412 | gen6_rps_irq_handler(dev_priv, tmp); |
1403 | } else | 1413 | } else |
1404 | DRM_ERROR("The master control interrupt lied (PM)!\n"); | 1414 | DRM_ERROR("The master control interrupt lied (PM)!\n"); |
1405 | } | 1415 | } |
@@ -1699,15 +1709,24 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe) | |||
1699 | * the work queue. */ | 1709 | * the work queue. */ |
1700 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | 1710 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) |
1701 | { | 1711 | { |
1712 | /* TODO: RPS on GEN9+ is not supported yet. */ | ||
1713 | if (WARN_ONCE(INTEL_INFO(dev_priv)->gen >= 9, | ||
1714 | "GEN9+: unexpected RPS IRQ\n")) | ||
1715 | return; | ||
1716 | |||
1702 | if (pm_iir & dev_priv->pm_rps_events) { | 1717 | if (pm_iir & dev_priv->pm_rps_events) { |
1703 | spin_lock(&dev_priv->irq_lock); | 1718 | spin_lock(&dev_priv->irq_lock); |
1704 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; | ||
1705 | gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); | 1719 | gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); |
1720 | if (dev_priv->rps.interrupts_enabled) { | ||
1721 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; | ||
1722 | queue_work(dev_priv->wq, &dev_priv->rps.work); | ||
1723 | } | ||
1706 | spin_unlock(&dev_priv->irq_lock); | 1724 | spin_unlock(&dev_priv->irq_lock); |
1707 | |||
1708 | queue_work(dev_priv->wq, &dev_priv->rps.work); | ||
1709 | } | 1725 | } |
1710 | 1726 | ||
1727 | if (INTEL_INFO(dev_priv)->gen >= 8) | ||
1728 | return; | ||
1729 | |||
1711 | if (HAS_VEBOX(dev_priv->dev)) { | 1730 | if (HAS_VEBOX(dev_priv->dev)) { |
1712 | if (pm_iir & PM_VEBOX_USER_INTERRUPT) | 1731 | if (pm_iir & PM_VEBOX_USER_INTERRUPT) |
1713 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); | 1732 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); |
@@ -2222,6 +2241,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) | |||
2222 | irqreturn_t ret = IRQ_NONE; | 2241 | irqreturn_t ret = IRQ_NONE; |
2223 | uint32_t tmp = 0; | 2242 | uint32_t tmp = 0; |
2224 | enum pipe pipe; | 2243 | enum pipe pipe; |
2244 | u32 aux_mask = GEN8_AUX_CHANNEL_A; | ||
2245 | |||
2246 | if (IS_GEN9(dev)) | ||
2247 | aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | | ||
2248 | GEN9_AUX_CHANNEL_D; | ||
2225 | 2249 | ||
2226 | master_ctl = I915_READ(GEN8_MASTER_IRQ); | 2250 | master_ctl = I915_READ(GEN8_MASTER_IRQ); |
2227 | master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; | 2251 | master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; |
@@ -2254,7 +2278,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) | |||
2254 | if (tmp) { | 2278 | if (tmp) { |
2255 | I915_WRITE(GEN8_DE_PORT_IIR, tmp); | 2279 | I915_WRITE(GEN8_DE_PORT_IIR, tmp); |
2256 | ret = IRQ_HANDLED; | 2280 | ret = IRQ_HANDLED; |
2257 | if (tmp & GEN8_AUX_CHANNEL_A) | 2281 | |
2282 | if (tmp & aux_mask) | ||
2258 | dp_aux_irq_handler(dev); | 2283 | dp_aux_irq_handler(dev); |
2259 | else | 2284 | else |
2260 | DRM_ERROR("Unexpected DE Port interrupt\n"); | 2285 | DRM_ERROR("Unexpected DE Port interrupt\n"); |
@@ -3036,10 +3061,15 @@ static void i915_hangcheck_elapsed(unsigned long data) | |||
3036 | void i915_queue_hangcheck(struct drm_device *dev) | 3061 | void i915_queue_hangcheck(struct drm_device *dev) |
3037 | { | 3062 | { |
3038 | struct drm_i915_private *dev_priv = dev->dev_private; | 3063 | struct drm_i915_private *dev_priv = dev->dev_private; |
3064 | struct timer_list *timer = &dev_priv->gpu_error.hangcheck_timer; | ||
3065 | |||
3039 | if (!i915.enable_hangcheck) | 3066 | if (!i915.enable_hangcheck) |
3040 | return; | 3067 | return; |
3041 | 3068 | ||
3042 | mod_timer(&dev_priv->gpu_error.hangcheck_timer, | 3069 | /* Don't continually defer the hangcheck, but make sure it is active */ |
3070 | if (timer_pending(timer)) | ||
3071 | return; | ||
3072 | mod_timer(timer, | ||
3043 | round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); | 3073 | round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); |
3044 | } | 3074 | } |
3045 | 3075 | ||
@@ -3488,11 +3518,14 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) | |||
3488 | uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; | 3518 | uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; |
3489 | uint32_t de_pipe_enables; | 3519 | uint32_t de_pipe_enables; |
3490 | int pipe; | 3520 | int pipe; |
3521 | u32 aux_en = GEN8_AUX_CHANNEL_A; | ||
3491 | 3522 | ||
3492 | if (IS_GEN9(dev_priv)) | 3523 | if (IS_GEN9(dev_priv)) { |
3493 | de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE | | 3524 | de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE | |
3494 | GEN9_DE_PIPE_IRQ_FAULT_ERRORS; | 3525 | GEN9_DE_PIPE_IRQ_FAULT_ERRORS; |
3495 | else | 3526 | aux_en |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | |
3527 | GEN9_AUX_CHANNEL_D; | ||
3528 | } else | ||
3496 | de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE | | 3529 | de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE | |
3497 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | 3530 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
3498 | 3531 | ||
@@ -3510,7 +3543,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) | |||
3510 | dev_priv->de_irq_mask[pipe], | 3543 | dev_priv->de_irq_mask[pipe], |
3511 | de_pipe_enables); | 3544 | de_pipe_enables); |
3512 | 3545 | ||
3513 | GEN5_IRQ_INIT(GEN8_DE_PORT_, ~GEN8_AUX_CHANNEL_A, GEN8_AUX_CHANNEL_A); | 3546 | GEN5_IRQ_INIT(GEN8_DE_PORT_, ~aux_en, aux_en); |
3514 | } | 3547 | } |
3515 | 3548 | ||
3516 | static int gen8_irq_postinstall(struct drm_device *dev) | 3549 | static int gen8_irq_postinstall(struct drm_device *dev) |
@@ -3533,34 +3566,8 @@ static int gen8_irq_postinstall(struct drm_device *dev) | |||
3533 | static int cherryview_irq_postinstall(struct drm_device *dev) | 3566 | static int cherryview_irq_postinstall(struct drm_device *dev) |
3534 | { | 3567 | { |
3535 | struct drm_i915_private *dev_priv = dev->dev_private; | 3568 | struct drm_i915_private *dev_priv = dev->dev_private; |
3536 | u32 enable_mask = I915_DISPLAY_PORT_INTERRUPT | | ||
3537 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | | ||
3538 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | | ||
3539 | I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; | ||
3540 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV | | ||
3541 | PIPE_CRC_DONE_INTERRUPT_STATUS; | ||
3542 | int pipe; | ||
3543 | |||
3544 | /* | ||
3545 | * Leave vblank interrupts masked initially. enable/disable will | ||
3546 | * toggle them based on usage. | ||
3547 | */ | ||
3548 | dev_priv->irq_mask = ~enable_mask; | ||
3549 | 3569 | ||
3550 | for_each_pipe(dev_priv, pipe) | 3570 | vlv_display_irq_postinstall(dev_priv); |
3551 | I915_WRITE(PIPESTAT(pipe), 0xffff); | ||
3552 | |||
3553 | spin_lock_irq(&dev_priv->irq_lock); | ||
3554 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); | ||
3555 | for_each_pipe(dev_priv, pipe) | ||
3556 | i915_enable_pipestat(dev_priv, pipe, pipestat_enable); | ||
3557 | spin_unlock_irq(&dev_priv->irq_lock); | ||
3558 | |||
3559 | I915_WRITE(VLV_IIR, 0xffffffff); | ||
3560 | I915_WRITE(VLV_IIR, 0xffffffff); | ||
3561 | I915_WRITE(VLV_IER, enable_mask); | ||
3562 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); | ||
3563 | POSTING_READ(VLV_IMR); | ||
3564 | 3571 | ||
3565 | gen8_gt_irq_postinstall(dev_priv); | 3572 | gen8_gt_irq_postinstall(dev_priv); |
3566 | 3573 | ||
@@ -3580,6 +3587,20 @@ static void gen8_irq_uninstall(struct drm_device *dev) | |||
3580 | gen8_irq_reset(dev); | 3587 | gen8_irq_reset(dev); |
3581 | } | 3588 | } |
3582 | 3589 | ||
3590 | static void vlv_display_irq_uninstall(struct drm_i915_private *dev_priv) | ||
3591 | { | ||
3592 | /* Interrupt setup is already guaranteed to be single-threaded, this is | ||
3593 | * just to make the assert_spin_locked check happy. */ | ||
3594 | spin_lock_irq(&dev_priv->irq_lock); | ||
3595 | if (dev_priv->display_irqs_enabled) | ||
3596 | valleyview_display_irqs_uninstall(dev_priv); | ||
3597 | spin_unlock_irq(&dev_priv->irq_lock); | ||
3598 | |||
3599 | vlv_display_irq_reset(dev_priv); | ||
3600 | |||
3601 | dev_priv->irq_mask = 0; | ||
3602 | } | ||
3603 | |||
3583 | static void valleyview_irq_uninstall(struct drm_device *dev) | 3604 | static void valleyview_irq_uninstall(struct drm_device *dev) |
3584 | { | 3605 | { |
3585 | struct drm_i915_private *dev_priv = dev->dev_private; | 3606 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -3593,22 +3614,12 @@ static void valleyview_irq_uninstall(struct drm_device *dev) | |||
3593 | 3614 | ||
3594 | I915_WRITE(HWSTAM, 0xffffffff); | 3615 | I915_WRITE(HWSTAM, 0xffffffff); |
3595 | 3616 | ||
3596 | /* Interrupt setup is already guaranteed to be single-threaded, this is | 3617 | vlv_display_irq_uninstall(dev_priv); |
3597 | * just to make the assert_spin_locked check happy. */ | ||
3598 | spin_lock_irq(&dev_priv->irq_lock); | ||
3599 | if (dev_priv->display_irqs_enabled) | ||
3600 | valleyview_display_irqs_uninstall(dev_priv); | ||
3601 | spin_unlock_irq(&dev_priv->irq_lock); | ||
3602 | |||
3603 | vlv_display_irq_reset(dev_priv); | ||
3604 | |||
3605 | dev_priv->irq_mask = 0; | ||
3606 | } | 3618 | } |
3607 | 3619 | ||
3608 | static void cherryview_irq_uninstall(struct drm_device *dev) | 3620 | static void cherryview_irq_uninstall(struct drm_device *dev) |
3609 | { | 3621 | { |
3610 | struct drm_i915_private *dev_priv = dev->dev_private; | 3622 | struct drm_i915_private *dev_priv = dev->dev_private; |
3611 | int pipe; | ||
3612 | 3623 | ||
3613 | if (!dev_priv) | 3624 | if (!dev_priv) |
3614 | return; | 3625 | return; |
@@ -3620,13 +3631,7 @@ static void cherryview_irq_uninstall(struct drm_device *dev) | |||
3620 | 3631 | ||
3621 | GEN5_IRQ_RESET(GEN8_PCU_); | 3632 | GEN5_IRQ_RESET(GEN8_PCU_); |
3622 | 3633 | ||
3623 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 3634 | vlv_display_irq_uninstall(dev_priv); |
3624 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | ||
3625 | |||
3626 | for_each_pipe(dev_priv, pipe) | ||
3627 | I915_WRITE(PIPESTAT(pipe), 0xffff); | ||
3628 | |||
3629 | GEN5_IRQ_RESET(VLV_); | ||
3630 | } | 3635 | } |
3631 | 3636 | ||
3632 | static void ironlake_irq_uninstall(struct drm_device *dev) | 3637 | static void ironlake_irq_uninstall(struct drm_device *dev) |
@@ -3760,8 +3765,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) | |||
3760 | I915_WRITE16(IIR, iir & ~flip_mask); | 3765 | I915_WRITE16(IIR, iir & ~flip_mask); |
3761 | new_iir = I915_READ16(IIR); /* Flush posted writes */ | 3766 | new_iir = I915_READ16(IIR); /* Flush posted writes */ |
3762 | 3767 | ||
3763 | i915_update_dri1_breadcrumb(dev); | ||
3764 | |||
3765 | if (iir & I915_USER_INTERRUPT) | 3768 | if (iir & I915_USER_INTERRUPT) |
3766 | notify_ring(dev, &dev_priv->ring[RCS]); | 3769 | notify_ring(dev, &dev_priv->ring[RCS]); |
3767 | 3770 | ||
@@ -3998,8 +4001,6 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) | |||
3998 | iir = new_iir; | 4001 | iir = new_iir; |
3999 | } while (iir & ~flip_mask); | 4002 | } while (iir & ~flip_mask); |
4000 | 4003 | ||
4001 | i915_update_dri1_breadcrumb(dev); | ||
4002 | |||
4003 | return ret; | 4004 | return ret; |
4004 | } | 4005 | } |
4005 | 4006 | ||
@@ -4227,8 +4228,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) | |||
4227 | iir = new_iir; | 4228 | iir = new_iir; |
4228 | } | 4229 | } |
4229 | 4230 | ||
4230 | i915_update_dri1_breadcrumb(dev); | ||
4231 | |||
4232 | return ret; | 4231 | return ret; |
4233 | } | 4232 | } |
4234 | 4233 | ||