diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 96 |
1 files changed, 48 insertions, 48 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85f4c5de97e..89a071a3e6f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -274,7 +274,6 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
274 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 274 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
275 | int ret = IRQ_NONE; | 275 | int ret = IRQ_NONE; |
276 | u32 de_iir, gt_iir, de_ier, pch_iir; | 276 | u32 de_iir, gt_iir, de_ier, pch_iir; |
277 | u32 new_de_iir, new_gt_iir, new_pch_iir; | ||
278 | struct drm_i915_master_private *master_priv; | 277 | struct drm_i915_master_private *master_priv; |
279 | 278 | ||
280 | /* disable master interrupt before clearing iir */ | 279 | /* disable master interrupt before clearing iir */ |
@@ -286,49 +285,42 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
286 | gt_iir = I915_READ(GTIIR); | 285 | gt_iir = I915_READ(GTIIR); |
287 | pch_iir = I915_READ(SDEIIR); | 286 | pch_iir = I915_READ(SDEIIR); |
288 | 287 | ||
289 | for (;;) { | 288 | if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) |
290 | if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) | 289 | goto done; |
291 | break; | ||
292 | |||
293 | ret = IRQ_HANDLED; | ||
294 | 290 | ||
295 | /* should clear PCH hotplug event before clear CPU irq */ | 291 | ret = IRQ_HANDLED; |
296 | I915_WRITE(SDEIIR, pch_iir); | ||
297 | new_pch_iir = I915_READ(SDEIIR); | ||
298 | |||
299 | I915_WRITE(DEIIR, de_iir); | ||
300 | new_de_iir = I915_READ(DEIIR); | ||
301 | I915_WRITE(GTIIR, gt_iir); | ||
302 | new_gt_iir = I915_READ(GTIIR); | ||
303 | |||
304 | if (dev->primary->master) { | ||
305 | master_priv = dev->primary->master->driver_priv; | ||
306 | if (master_priv->sarea_priv) | ||
307 | master_priv->sarea_priv->last_dispatch = | ||
308 | READ_BREADCRUMB(dev_priv); | ||
309 | } | ||
310 | 292 | ||
311 | if (gt_iir & GT_USER_INTERRUPT) { | 293 | if (dev->primary->master) { |
312 | u32 seqno = i915_get_gem_seqno(dev); | 294 | master_priv = dev->primary->master->driver_priv; |
313 | dev_priv->mm.irq_gem_seqno = seqno; | 295 | if (master_priv->sarea_priv) |
314 | trace_i915_gem_request_complete(dev, seqno); | 296 | master_priv->sarea_priv->last_dispatch = |
315 | DRM_WAKEUP(&dev_priv->irq_queue); | 297 | READ_BREADCRUMB(dev_priv); |
316 | } | 298 | } |
317 | 299 | ||
318 | if (de_iir & DE_GSE) | 300 | if (gt_iir & GT_USER_INTERRUPT) { |
319 | ironlake_opregion_gse_intr(dev); | 301 | u32 seqno = i915_get_gem_seqno(dev); |
302 | dev_priv->mm.irq_gem_seqno = seqno; | ||
303 | trace_i915_gem_request_complete(dev, seqno); | ||
304 | DRM_WAKEUP(&dev_priv->irq_queue); | ||
305 | dev_priv->hangcheck_count = 0; | ||
306 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | ||
307 | } | ||
320 | 308 | ||
321 | /* check event from PCH */ | 309 | if (de_iir & DE_GSE) |
322 | if ((de_iir & DE_PCH_EVENT) && | 310 | ironlake_opregion_gse_intr(dev); |
323 | (pch_iir & SDE_HOTPLUG_MASK)) { | ||
324 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | ||
325 | } | ||
326 | 311 | ||
327 | de_iir = new_de_iir; | 312 | /* check event from PCH */ |
328 | gt_iir = new_gt_iir; | 313 | if ((de_iir & DE_PCH_EVENT) && |
329 | pch_iir = new_pch_iir; | 314 | (pch_iir & SDE_HOTPLUG_MASK)) { |
315 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | ||
330 | } | 316 | } |
331 | 317 | ||
318 | /* should clear PCH hotplug event before clear CPU irq */ | ||
319 | I915_WRITE(SDEIIR, pch_iir); | ||
320 | I915_WRITE(GTIIR, gt_iir); | ||
321 | I915_WRITE(DEIIR, de_iir); | ||
322 | |||
323 | done: | ||
332 | I915_WRITE(DEIER, de_ier); | 324 | I915_WRITE(DEIER, de_ier); |
333 | (void)I915_READ(DEIER); | 325 | (void)I915_READ(DEIER); |
334 | 326 | ||
@@ -1084,6 +1076,10 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
1084 | (void) I915_READ(IER); | 1076 | (void) I915_READ(IER); |
1085 | } | 1077 | } |
1086 | 1078 | ||
1079 | /* | ||
1080 | * Must be called after intel_modeset_init or hotplug interrupts won't be | ||
1081 | * enabled correctly. | ||
1082 | */ | ||
1087 | int i915_driver_irq_postinstall(struct drm_device *dev) | 1083 | int i915_driver_irq_postinstall(struct drm_device *dev) |
1088 | { | 1084 | { |
1089 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1085 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -1106,19 +1102,23 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1106 | if (I915_HAS_HOTPLUG(dev)) { | 1102 | if (I915_HAS_HOTPLUG(dev)) { |
1107 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 1103 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
1108 | 1104 | ||
1109 | /* Leave other bits alone */ | 1105 | /* Note HDMI and DP share bits */ |
1110 | hotplug_en |= HOTPLUG_EN_MASK; | 1106 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) |
1107 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | ||
1108 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | ||
1109 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | ||
1110 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | ||
1111 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | ||
1112 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
1113 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
1114 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | ||
1115 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
1116 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) | ||
1117 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
1118 | /* Ignore TV since it's buggy */ | ||
1119 | |||
1111 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 1120 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
1112 | 1121 | ||
1113 | dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS | | ||
1114 | TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS | | ||
1115 | SDVOB_HOTPLUG_INT_STATUS; | ||
1116 | if (IS_G4X(dev)) { | ||
1117 | dev_priv->hotplug_supported_mask |= | ||
1118 | HDMIB_HOTPLUG_INT_STATUS | | ||
1119 | HDMIC_HOTPLUG_INT_STATUS | | ||
1120 | HDMID_HOTPLUG_INT_STATUS; | ||
1121 | } | ||
1122 | /* Enable in IER... */ | 1122 | /* Enable in IER... */ |
1123 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | 1123 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; |
1124 | /* and unmask in IMR */ | 1124 | /* and unmask in IMR */ |