]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/gpu/drm/i915/i915_irq.c
spi: cadence: Init HW after reading devicetree attributes
[mirror_ubuntu-artful-kernel.git] / drivers / gpu / drm / i915 / i915_irq.c
index 0050ee9470f196748621b96ffd001cd3e4cd85d8..3201986bf25ebaf6a5b2a31089bd2e2b1871e09d 100644 (file)
@@ -151,7 +151,7 @@ ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
 {
        assert_spin_locked(&dev_priv->irq_lock);
 
-       if (!intel_irqs_enabled(dev_priv))
+       if (WARN_ON(!intel_irqs_enabled(dev_priv)))
                return;
 
        if ((dev_priv->irq_mask & mask) != mask) {
@@ -238,7 +238,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev)
 
        assert_spin_locked(&dev_priv->irq_lock);
 
-       for_each_pipe(pipe) {
+       for_each_pipe(dev_priv, pipe) {
                crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
 
                if (crtc->cpu_fifo_underrun_disabled)
@@ -296,7 +296,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev)
 
        assert_spin_locked(&dev_priv->irq_lock);
 
-       for_each_pipe(pipe) {
+       for_each_pipe(dev_priv, pipe) {
                crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
 
                if (crtc->pch_fifo_underrun_disabled)
@@ -497,7 +497,7 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
        old = !intel_crtc->cpu_fifo_underrun_disabled;
        intel_crtc->cpu_fifo_underrun_disabled = !enable;
 
-       if (INTEL_INFO(dev)->gen < 5 || IS_VALLEYVIEW(dev))
+       if (HAS_GMCH_DISPLAY(dev))
                i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
        else if (IS_GEN5(dev) || IS_GEN6(dev))
                ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
@@ -1020,7 +1020,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
 
        /* In vblank? */
        if (in_vbl)
-               ret |= DRM_SCANOUTPOS_INVBL;
+               ret |= DRM_SCANOUTPOS_IN_VBLANK;
 
        return ret;
 }
@@ -1322,10 +1322,10 @@ static u32 vlv_c0_residency(struct drm_i915_private *dev_priv,
  * @dev_priv: DRM device private
  *
  */
-static u32 vlv_calc_delay_from_C0_counters(struct drm_i915_private *dev_priv)
+static int vlv_calc_delay_from_C0_counters(struct drm_i915_private *dev_priv)
 {
        u32 residency_C0_up = 0, residency_C0_down = 0;
-       u8 new_delay, adj;
+       int new_delay, adj;
 
        dev_priv->rps.ei_interrupt_count++;
 
@@ -1627,6 +1627,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
                                       struct drm_i915_private *dev_priv,
                                       u32 master_ctl)
 {
+       struct intel_engine_cs *ring;
        u32 rcs, bcs, vcs;
        uint32_t tmp = 0;
        irqreturn_t ret = IRQ_NONE;
@@ -1636,12 +1637,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
                if (tmp) {
                        I915_WRITE(GEN8_GT_IIR(0), tmp);
                        ret = IRQ_HANDLED;
+
                        rcs = tmp >> GEN8_RCS_IRQ_SHIFT;
-                       bcs = tmp >> GEN8_BCS_IRQ_SHIFT;
+                       ring = &dev_priv->ring[RCS];
                        if (rcs & GT_RENDER_USER_INTERRUPT)
-                               notify_ring(dev, &dev_priv->ring[RCS]);
+                               notify_ring(dev, ring);
+                       if (rcs & GT_CONTEXT_SWITCH_INTERRUPT)
+                               intel_execlists_handle_ctx_events(ring);
+
+                       bcs = tmp >> GEN8_BCS_IRQ_SHIFT;
+                       ring = &dev_priv->ring[BCS];
                        if (bcs & GT_RENDER_USER_INTERRUPT)
-                               notify_ring(dev, &dev_priv->ring[BCS]);
+                               notify_ring(dev, ring);
+                       if (bcs & GT_CONTEXT_SWITCH_INTERRUPT)
+                               intel_execlists_handle_ctx_events(ring);
                } else
                        DRM_ERROR("The master control interrupt lied (GT0)!\n");
        }
@@ -1651,12 +1660,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
                if (tmp) {
                        I915_WRITE(GEN8_GT_IIR(1), tmp);
                        ret = IRQ_HANDLED;
+
                        vcs = tmp >> GEN8_VCS1_IRQ_SHIFT;
+                       ring = &dev_priv->ring[VCS];
                        if (vcs & GT_RENDER_USER_INTERRUPT)
-                               notify_ring(dev, &dev_priv->ring[VCS]);
+                               notify_ring(dev, ring);
+                       if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
+                               intel_execlists_handle_ctx_events(ring);
+
                        vcs = tmp >> GEN8_VCS2_IRQ_SHIFT;
+                       ring = &dev_priv->ring[VCS2];
                        if (vcs & GT_RENDER_USER_INTERRUPT)
-                               notify_ring(dev, &dev_priv->ring[VCS2]);
+                               notify_ring(dev, ring);
+                       if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
+                               intel_execlists_handle_ctx_events(ring);
                } else
                        DRM_ERROR("The master control interrupt lied (GT1)!\n");
        }
@@ -1677,9 +1694,13 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
                if (tmp) {
                        I915_WRITE(GEN8_GT_IIR(3), tmp);
                        ret = IRQ_HANDLED;
+
                        vcs = tmp >> GEN8_VECS_IRQ_SHIFT;
+                       ring = &dev_priv->ring[VECS];
                        if (vcs & GT_RENDER_USER_INTERRUPT)
-                               notify_ring(dev, &dev_priv->ring[VECS]);
+                               notify_ring(dev, ring);
+                       if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
+                               intel_execlists_handle_ctx_events(ring);
                } else
                        DRM_ERROR("The master control interrupt lied (GT3)!\n");
        }
@@ -1772,7 +1793,9 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
                                long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT;
                        }
 
-                       DRM_DEBUG_DRIVER("digital hpd port %d %d\n", port, long_hpd);
+                       DRM_DEBUG_DRIVER("digital hpd port %c - %s\n",
+                                        port_name(port),
+                                        long_hpd ? "long" : "short");
                        /* for long HPD pulses we want to have the digital queue happen,
                           but we still want HPD storm detection to function. */
                        if (long_hpd) {
@@ -1984,14 +2007,9 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
 
 static bool intel_pipe_handle_vblank(struct drm_device *dev, enum pipe pipe)
 {
-       struct intel_crtc *crtc;
-
        if (!drm_handle_vblank(dev, pipe))
                return false;
 
-       crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
-       wake_up(&crtc->vbl_wait);
-
        return true;
 }
 
@@ -2002,7 +2020,7 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
        int pipe;
 
        spin_lock(&dev_priv->irq_lock);
-       for_each_pipe(pipe) {
+       for_each_pipe(dev_priv, pipe) {
                int reg;
                u32 mask, iir_bit = 0;
 
@@ -2047,9 +2065,10 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
        }
        spin_unlock(&dev_priv->irq_lock);
 
-       for_each_pipe(pipe) {
-               if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
-                       intel_pipe_handle_vblank(dev, pipe);
+       for_each_pipe(dev_priv, pipe) {
+               if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
+                   intel_pipe_handle_vblank(dev, pipe))
+                       intel_check_page_flip(dev, pipe);
 
                if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV) {
                        intel_prepare_page_flip(dev, pipe);
@@ -2216,7 +2235,7 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
                DRM_ERROR("PCH poison interrupt\n");
 
        if (pch_iir & SDE_FDI_MASK)
-               for_each_pipe(pipe)
+               for_each_pipe(dev_priv, pipe)
                        DRM_DEBUG_DRIVER("  pipe %c FDI IIR: 0x%08x\n",
                                         pipe_name(pipe),
                                         I915_READ(FDI_RX_IIR(pipe)));
@@ -2247,7 +2266,7 @@ static void ivb_err_int_handler(struct drm_device *dev)
        if (err_int & ERR_INT_POISON)
                DRM_ERROR("Poison interrupt\n");
 
-       for_each_pipe(pipe) {
+       for_each_pipe(dev_priv, pipe) {
                if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) {
                        if (intel_set_cpu_fifo_underrun_reporting(dev, pipe,
                                                                  false))
@@ -2324,7 +2343,7 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
                DRM_DEBUG_DRIVER("Audio CP change interrupt\n");
 
        if (pch_iir & SDE_FDI_MASK_CPT)
-               for_each_pipe(pipe)
+               for_each_pipe(dev_priv, pipe)
                        DRM_DEBUG_DRIVER("  pipe %c FDI IIR: 0x%08x\n",
                                         pipe_name(pipe),
                                         I915_READ(FDI_RX_IIR(pipe)));
@@ -2347,9 +2366,10 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir)
        if (de_iir & DE_POISON)
                DRM_ERROR("Poison interrupt\n");
 
-       for_each_pipe(pipe) {
-               if (de_iir & DE_PIPE_VBLANK(pipe))
-                       intel_pipe_handle_vblank(dev, pipe);
+       for_each_pipe(dev_priv, pipe) {
+               if (de_iir & DE_PIPE_VBLANK(pipe) &&
+                   intel_pipe_handle_vblank(dev, pipe))
+                       intel_check_page_flip(dev, pipe);
 
                if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
                        if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, false))
@@ -2397,9 +2417,10 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
        if (de_iir & DE_GSE_IVB)
                intel_opregion_asle_intr(dev);
 
-       for_each_pipe(pipe) {
-               if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)))
-                       intel_pipe_handle_vblank(dev, pipe);
+       for_each_pipe(dev_priv, pipe) {
+               if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)) &&
+                   intel_pipe_handle_vblank(dev, pipe))
+                       intel_check_page_flip(dev, pipe);
 
                /* plane/pipes map 1:1 on ilk+ */
                if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe)) {
@@ -2544,7 +2565,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
                        DRM_ERROR("The master control interrupt lied (DE PORT)!\n");
        }
 
-       for_each_pipe(pipe) {
+       for_each_pipe(dev_priv, pipe) {
                uint32_t pipe_iir;
 
                if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
@@ -2554,8 +2575,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
                if (pipe_iir) {
                        ret = IRQ_HANDLED;
                        I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir);
-                       if (pipe_iir & GEN8_PIPE_VBLANK)
-                               intel_pipe_handle_vblank(dev, pipe);
+                       if (pipe_iir & GEN8_PIPE_VBLANK &&
+                           intel_pipe_handle_vblank(dev, pipe))
+                               intel_check_page_flip(dev, pipe);
 
                        if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) {
                                intel_prepare_page_flip(dev, pipe);
@@ -2763,7 +2785,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
 
        if (eir & I915_ERROR_MEMORY_REFRESH) {
                pr_err("memory refresh error:\n");
-               for_each_pipe(pipe)
+               for_each_pipe(dev_priv, pipe)
                        pr_err("pipe %c stat: 0x%08x\n",
                               pipe_name(pipe), I915_READ(PIPESTAT(pipe)));
                /* pipestat has already been acked */
@@ -2860,52 +2882,6 @@ void i915_handle_error(struct drm_device *dev, bool wedged,
        schedule_work(&dev_priv->gpu_error.work);
 }
 
-static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct drm_i915_gem_object *obj;
-       struct intel_unpin_work *work;
-       unsigned long flags;
-       bool stall_detected;
-
-       /* Ignore early vblank irqs */
-       if (intel_crtc == NULL)
-               return;
-
-       spin_lock_irqsave(&dev->event_lock, flags);
-       work = intel_crtc->unpin_work;
-
-       if (work == NULL ||
-           atomic_read(&work->pending) >= INTEL_FLIP_COMPLETE ||
-           !work->enable_stall_check) {
-               /* Either the pending flip IRQ arrived, or we're too early. Don't check */
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-               return;
-       }
-
-       /* Potential stall - if we see that the flip has happened, assume a missed interrupt */
-       obj = work->pending_flip_obj;
-       if (INTEL_INFO(dev)->gen >= 4) {
-               int dspsurf = DSPSURF(intel_crtc->plane);
-               stall_detected = I915_HI_DISPBASE(I915_READ(dspsurf)) ==
-                                       i915_gem_obj_ggtt_offset(obj);
-       } else {
-               int dspaddr = DSPADDR(intel_crtc->plane);
-               stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) +
-                                                       crtc->y * crtc->primary->fb->pitches[0] +
-                                                       crtc->x * crtc->primary->fb->bits_per_pixel/8);
-       }
-
-       spin_unlock_irqrestore(&dev->event_lock, flags);
-
-       if (stall_detected) {
-               DRM_DEBUG_DRIVER("Pageflip stall detected\n");
-               intel_prepare_page_flip(dev, intel_crtc->plane);
-       }
-}
-
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
@@ -3441,7 +3417,7 @@ static void valleyview_irq_preinstall(struct drm_device *dev)
 
        I915_WRITE(PORT_HOTPLUG_EN, 0);
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0xffff);
        I915_WRITE(VLV_IIR, 0xffffffff);
        I915_WRITE(VLV_IMR, 0xffffffff);
@@ -3467,7 +3443,7 @@ static void gen8_irq_reset(struct drm_device *dev)
 
        gen8_gt_irq_reset(dev_priv);
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                if (intel_display_power_enabled(dev_priv,
                                                POWER_DOMAIN_PIPE(pipe)))
                        GEN8_IRQ_RESET_NDX(DE_PIPE, pipe);
@@ -3510,7 +3486,7 @@ static void cherryview_irq_preinstall(struct drm_device *dev)
        I915_WRITE(PORT_HOTPLUG_EN, 0);
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0xffff);
 
        I915_WRITE(VLV_IMR, 0xffffffff);
@@ -3522,18 +3498,17 @@ static void cherryview_irq_preinstall(struct drm_device *dev)
 static void ibx_hpd_irq_setup(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_mode_config *mode_config = &dev->mode_config;
        struct intel_encoder *intel_encoder;
        u32 hotplug_irqs, hotplug, enabled_irqs = 0;
 
        if (HAS_PCH_IBX(dev)) {
                hotplug_irqs = SDE_HOTPLUG_MASK;
-               list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
+               for_each_intel_encoder(dev, intel_encoder)
                        if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED)
                                enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin];
        } else {
                hotplug_irqs = SDE_HOTPLUG_MASK_CPT;
-               list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
+               for_each_intel_encoder(dev, intel_encoder)
                        if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED)
                                enabled_irqs |= hpd_cpt[intel_encoder->hpd_pin];
        }
@@ -3782,28 +3757,31 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
 
 static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
 {
-       int i;
-
        /* These are interrupts we'll toggle with the ring mask register */
        uint32_t gt_interrupts[] = {
                GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
+                       GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
                        GT_RENDER_L3_PARITY_ERROR_INTERRUPT |
-                       GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT,
+                       GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT |
+                       GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT,
                GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT |
-                       GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT,
+                       GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT |
+                       GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT |
+                       GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT,
                0,
-               GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT
+               GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT |
+                       GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT
                };
 
-       for (i = 0; i < ARRAY_SIZE(gt_interrupts); i++)
-               GEN8_IRQ_INIT_NDX(GT, i, ~gt_interrupts[i], gt_interrupts[i]);
-
        dev_priv->pm_irq_mask = 0xffffffff;
+       GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]);
+       GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]);
+       GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, dev_priv->pm_rps_events);
+       GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]);
 }
 
 static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = dev_priv->dev;
        uint32_t de_pipe_masked = GEN8_PIPE_PRIMARY_FLIP_DONE |
                GEN8_PIPE_CDCLK_CRC_DONE |
                GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
@@ -3814,7 +3792,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
        dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
        dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                if (intel_display_power_enabled(dev_priv,
                                POWER_DOMAIN_PIPE(pipe)))
                        GEN8_IRQ_INIT_NDX(DE_PIPE, pipe,
@@ -3859,12 +3837,12 @@ static int cherryview_irq_postinstall(struct drm_device *dev)
         */
        dev_priv->irq_mask = ~enable_mask;
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0xffff);
 
        spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
        i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                i915_enable_pipestat(dev_priv, pipe, pipestat_enable);
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 
@@ -3901,7 +3879,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
 
        I915_WRITE(VLV_MASTER_IER, 0);
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0xffff);
 
        I915_WRITE(HWSTAM, 0xffffffff);
@@ -3963,7 +3941,7 @@ do {                                                      \
        I915_WRITE(PORT_HOTPLUG_EN, 0);
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0xffff);
 
        I915_WRITE(VLV_IMR, 0xffffffff);
@@ -3987,7 +3965,7 @@ static void i8xx_irq_preinstall(struct drm_device * dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0);
        I915_WRITE16(IMR, 0xffff);
        I915_WRITE16(IER, 0x0);
@@ -4041,7 +4019,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
                return false;
 
        if ((iir & flip_pending) == 0)
-               return false;
+               goto check_page_flip;
 
        intel_prepare_page_flip(dev, plane);
 
@@ -4052,11 +4030,14 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
         * an interrupt per se, we watch for the change at vblank.
         */
        if (I915_READ16(ISR) & flip_pending)
-               return false;
+               goto check_page_flip;
 
        intel_finish_page_flip(dev, pipe);
-
        return true;
+
+check_page_flip:
+       intel_check_page_flip(dev, pipe);
+       return false;
 }
 
 static irqreturn_t i8xx_irq_handler(int irq, void *arg)
@@ -4087,7 +4068,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
                                          "Command parser error, iir 0x%08x",
                                          iir);
 
-               for_each_pipe(pipe) {
+               for_each_pipe(dev_priv, pipe) {
                        int reg = PIPESTAT(pipe);
                        pipe_stats[pipe] = I915_READ(reg);
 
@@ -4107,7 +4088,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
                if (iir & I915_USER_INTERRUPT)
                        notify_ring(dev, &dev_priv->ring[RCS]);
 
-               for_each_pipe(pipe) {
+               for_each_pipe(dev_priv, pipe) {
                        int plane = pipe;
                        if (HAS_FBC(dev))
                                plane = !plane;
@@ -4135,7 +4116,7 @@ static void i8xx_irq_uninstall(struct drm_device * dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
-       for_each_pipe(pipe) {
+       for_each_pipe(dev_priv, pipe) {
                /* Clear enable bits; then clear status bits */
                I915_WRITE(PIPESTAT(pipe), 0);
                I915_WRITE(PIPESTAT(pipe), I915_READ(PIPESTAT(pipe)));
@@ -4156,7 +4137,7 @@ static void i915_irq_preinstall(struct drm_device * dev)
        }
 
        I915_WRITE16(HWSTAM, 0xeffe);
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0);
        I915_WRITE(IMR, 0xffffffff);
        I915_WRITE(IER, 0x0);
@@ -4226,7 +4207,7 @@ static bool i915_handle_vblank(struct drm_device *dev,
                return false;
 
        if ((iir & flip_pending) == 0)
-               return false;
+               goto check_page_flip;
 
        intel_prepare_page_flip(dev, plane);
 
@@ -4237,11 +4218,14 @@ static bool i915_handle_vblank(struct drm_device *dev,
         * an interrupt per se, we watch for the change at vblank.
         */
        if (I915_READ(ISR) & flip_pending)
-               return false;
+               goto check_page_flip;
 
        intel_finish_page_flip(dev, pipe);
-
        return true;
+
+check_page_flip:
+       intel_check_page_flip(dev, pipe);
+       return false;
 }
 
 static irqreturn_t i915_irq_handler(int irq, void *arg)
@@ -4271,7 +4255,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
                                          "Command parser error, iir 0x%08x",
                                          iir);
 
-               for_each_pipe(pipe) {
+               for_each_pipe(dev_priv, pipe) {
                        int reg = PIPESTAT(pipe);
                        pipe_stats[pipe] = I915_READ(reg);
 
@@ -4297,7 +4281,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
                if (iir & I915_USER_INTERRUPT)
                        notify_ring(dev, &dev_priv->ring[RCS]);
 
-               for_each_pipe(pipe) {
+               for_each_pipe(dev_priv, pipe) {
                        int plane = pipe;
                        if (HAS_FBC(dev))
                                plane = !plane;
@@ -4355,7 +4339,7 @@ static void i915_irq_uninstall(struct drm_device * dev)
        }
 
        I915_WRITE16(HWSTAM, 0xffff);
-       for_each_pipe(pipe) {
+       for_each_pipe(dev_priv, pipe) {
                /* Clear enable bits; then clear status bits */
                I915_WRITE(PIPESTAT(pipe), 0);
                I915_WRITE(PIPESTAT(pipe), I915_READ(PIPESTAT(pipe)));
@@ -4375,7 +4359,7 @@ static void i965_irq_preinstall(struct drm_device * dev)
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
 
        I915_WRITE(HWSTAM, 0xeffe);
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0);
        I915_WRITE(IMR, 0xffffffff);
        I915_WRITE(IER, 0x0);
@@ -4444,7 +4428,6 @@ static int i965_irq_postinstall(struct drm_device *dev)
 static void i915_hpd_irq_setup(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_mode_config *mode_config = &dev->mode_config;
        struct intel_encoder *intel_encoder;
        u32 hotplug_en;
 
@@ -4455,7 +4438,7 @@ static void i915_hpd_irq_setup(struct drm_device *dev)
                hotplug_en &= ~HOTPLUG_INT_EN_MASK;
                /* Note HDMI and DP share hotplug bits */
                /* enable bits are the same for all generations */
-               list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
+               for_each_intel_encoder(dev, intel_encoder)
                        if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED)
                                hotplug_en |= hpd_mask_i915[intel_encoder->hpd_pin];
                /* Programming the CRT detection parameters tends
@@ -4501,7 +4484,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
                                          "Command parser error, iir 0x%08x",
                                          iir);
 
-               for_each_pipe(pipe) {
+               for_each_pipe(dev_priv, pipe) {
                        int reg = PIPESTAT(pipe);
                        pipe_stats[pipe] = I915_READ(reg);
 
@@ -4532,7 +4515,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
                if (iir & I915_BSD_USER_INTERRUPT)
                        notify_ring(dev, &dev_priv->ring[VCS]);
 
-               for_each_pipe(pipe) {
+               for_each_pipe(dev_priv, pipe) {
                        if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
                            i915_handle_vblank(dev, pipe, pipe, iir))
                                flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
@@ -4589,12 +4572,12 @@ static void i965_irq_uninstall(struct drm_device * dev)
        I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
 
        I915_WRITE(HWSTAM, 0xffffffff);
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe), 0);
        I915_WRITE(IMR, 0xffffffff);
        I915_WRITE(IER, 0x0);
 
-       for_each_pipe(pipe)
+       for_each_pipe(dev_priv, pipe)
                I915_WRITE(PIPESTAT(pipe),
                           I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
        I915_WRITE(IIR, I915_READ(IIR));
@@ -4652,8 +4635,8 @@ void intel_irq_init(struct drm_device *dev)
        INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
 
        /* Let's track the enabled rps events */
-       if (IS_VALLEYVIEW(dev))
-               /* WaGsvRC0ResidenncyMethod:VLV */
+       if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev))
+               /* WaGsvRC0ResidencyMethod:vlv */
                dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED;
        else
                dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
@@ -4680,6 +4663,14 @@ void intel_irq_init(struct drm_device *dev)
                dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
        }
 
+       /*
+        * Opt out of the vblank disable timer on everything except gen2.
+        * Gen2 doesn't have a hardware frame counter and so depends on
+        * vblank interrupts to produce sane vblank seuquence numbers.
+        */
+       if (!IS_GEN2(dev))
+               dev->vblank_disable_immediate = true;
+
        if (drm_core_check_feature(dev, DRIVER_MODESET)) {
                dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
                dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;