aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c104
1 files changed, 56 insertions, 48 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7cd8110051b6..a17d6bdfe63e 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,51 +285,58 @@ 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 290
293 ret = IRQ_HANDLED; 291 ret = IRQ_HANDLED;
294 292
295 /* should clear PCH hotplug event before clear CPU irq */ 293 if (dev->primary->master) {
296 I915_WRITE(SDEIIR, pch_iir); 294 master_priv = dev->primary->master->driver_priv;
297 new_pch_iir = I915_READ(SDEIIR); 295 if (master_priv->sarea_priv)
296 master_priv->sarea_priv->last_dispatch =
297 READ_BREADCRUMB(dev_priv);
298 }
298 299
299 I915_WRITE(DEIIR, de_iir); 300 if (gt_iir & GT_USER_INTERRUPT) {
300 new_de_iir = I915_READ(DEIIR); 301 u32 seqno = i915_get_gem_seqno(dev);
301 I915_WRITE(GTIIR, gt_iir); 302 dev_priv->mm.irq_gem_seqno = seqno;
302 new_gt_iir = I915_READ(GTIIR); 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 }
303 308
304 if (dev->primary->master) { 309 if (de_iir & DE_GSE)
305 master_priv = dev->primary->master->driver_priv; 310 ironlake_opregion_gse_intr(dev);
306 if (master_priv->sarea_priv)
307 master_priv->sarea_priv->last_dispatch =
308 READ_BREADCRUMB(dev_priv);
309 }
310 311
311 if (gt_iir & GT_USER_INTERRUPT) { 312 if (de_iir & DE_PLANEA_FLIP_DONE) {
312 u32 seqno = i915_get_gem_seqno(dev); 313 intel_prepare_page_flip(dev, 0);
313 dev_priv->mm.irq_gem_seqno = seqno; 314 intel_finish_page_flip(dev, 0);
314 trace_i915_gem_request_complete(dev, seqno); 315 }
315 DRM_WAKEUP(&dev_priv->irq_queue);
316 dev_priv->hangcheck_count = 0;
317 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
318 }
319 316
320 if (de_iir & DE_GSE) 317 if (de_iir & DE_PLANEB_FLIP_DONE) {
321 ironlake_opregion_gse_intr(dev); 318 intel_prepare_page_flip(dev, 1);
319 intel_finish_page_flip(dev, 1);
320 }
322 321
323 /* check event from PCH */ 322 if (de_iir & DE_PIPEA_VBLANK)
324 if ((de_iir & DE_PCH_EVENT) && 323 drm_handle_vblank(dev, 0);
325 (pch_iir & SDE_HOTPLUG_MASK)) { 324
326 queue_work(dev_priv->wq, &dev_priv->hotplug_work); 325 if (de_iir & DE_PIPEB_VBLANK)
327 } 326 drm_handle_vblank(dev, 1);
328 327
329 de_iir = new_de_iir; 328 /* check event from PCH */
330 gt_iir = new_gt_iir; 329 if ((de_iir & DE_PCH_EVENT) &&
331 pch_iir = new_pch_iir; 330 (pch_iir & SDE_HOTPLUG_MASK)) {
331 queue_work(dev_priv->wq, &dev_priv->hotplug_work);
332 } 332 }
333 333
334 /* should clear PCH hotplug event before clear CPU irq */
335 I915_WRITE(SDEIIR, pch_iir);
336 I915_WRITE(GTIIR, gt_iir);
337 I915_WRITE(DEIIR, de_iir);
338
339done:
334 I915_WRITE(DEIER, de_ier); 340 I915_WRITE(DEIER, de_ier);
335 (void)I915_READ(DEIER); 341 (void)I915_READ(DEIER);
336 342
@@ -854,11 +860,11 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
854 if (!(pipeconf & PIPEACONF_ENABLE)) 860 if (!(pipeconf & PIPEACONF_ENABLE))
855 return -EINVAL; 861 return -EINVAL;
856 862
857 if (IS_IRONLAKE(dev))
858 return 0;
859
860 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 863 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
861 if (IS_I965G(dev)) 864 if (IS_IRONLAKE(dev))
865 ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
866 DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
867 else if (IS_I965G(dev))
862 i915_enable_pipestat(dev_priv, pipe, 868 i915_enable_pipestat(dev_priv, pipe,
863 PIPE_START_VBLANK_INTERRUPT_ENABLE); 869 PIPE_START_VBLANK_INTERRUPT_ENABLE);
864 else 870 else
@@ -876,13 +882,14 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
876 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 882 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
877 unsigned long irqflags; 883 unsigned long irqflags;
878 884
879 if (IS_IRONLAKE(dev))
880 return;
881
882 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 885 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
883 i915_disable_pipestat(dev_priv, pipe, 886 if (IS_IRONLAKE(dev))
884 PIPE_VBLANK_INTERRUPT_ENABLE | 887 ironlake_disable_display_irq(dev_priv, (pipe == 0) ?
885 PIPE_START_VBLANK_INTERRUPT_ENABLE); 888 DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
889 else
890 i915_disable_pipestat(dev_priv, pipe,
891 PIPE_VBLANK_INTERRUPT_ENABLE |
892 PIPE_START_VBLANK_INTERRUPT_ENABLE);
886 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 893 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
887} 894}
888 895
@@ -1025,13 +1032,14 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1025{ 1032{
1026 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 1033 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1027 /* enable kind of interrupts always enabled */ 1034 /* enable kind of interrupts always enabled */
1028 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT; 1035 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
1036 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
1029 u32 render_mask = GT_USER_INTERRUPT; 1037 u32 render_mask = GT_USER_INTERRUPT;
1030 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | 1038 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
1031 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; 1039 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
1032 1040
1033 dev_priv->irq_mask_reg = ~display_mask; 1041 dev_priv->irq_mask_reg = ~display_mask;
1034 dev_priv->de_irq_enable_reg = display_mask; 1042 dev_priv->de_irq_enable_reg = display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK;
1035 1043
1036 /* should always can generate irq */ 1044 /* should always can generate irq */
1037 I915_WRITE(DEIIR, I915_READ(DEIIR)); 1045 I915_WRITE(DEIIR, I915_READ(DEIIR));