]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/i915_irq.c
Merge tag 'drm-intel-fixes-2014-04-04' of git://anongit.freedesktop.org/drm-intel...
[karo-tx-linux.git] / drivers / gpu / drm / i915 / i915_irq.c
index acebe511e4efa04f409e45b0bd83c0e54ee00ab3..7753249b3a959cce7f31b8c9cf1ba0b36c18dce8 100644 (file)
@@ -82,7 +82,7 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
 
 /* For display hotplug interrupt */
 static void
-ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
 {
        assert_spin_locked(&dev_priv->irq_lock);
 
@@ -100,7 +100,7 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
 }
 
 static void
-ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
 {
        assert_spin_locked(&dev_priv->irq_lock);
 
@@ -596,7 +596,7 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
  */
 static void i915_enable_asle_pipestat(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
        if (!dev_priv->opregion.asle || !IS_MOBILE(dev))
@@ -624,7 +624,7 @@ static void i915_enable_asle_pipestat(struct drm_device *dev)
 static int
 i915_pipe_enabled(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
        if (drm_core_check_feature(dev, DRIVER_MODESET)) {
                /* Locking is horribly broken here, but whatever. */
@@ -648,7 +648,7 @@ static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe)
  */
 static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long high_frame;
        unsigned long low_frame;
        u32 high1, high2, low, pixel, vbl_start;
@@ -704,7 +704,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 
 static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int reg = PIPE_FRMCOUNT_GM45(pipe);
 
        if (!i915_pipe_enabled(dev, pipe)) {
@@ -718,33 +718,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
 
 /* raw reads, only for fast reads of display block, no need for forcewake etc. */
 #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
-#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))
 
 static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t status;
-
-       if (INTEL_INFO(dev)->gen < 7) {
-               status = pipe == PIPE_A ?
-                       DE_PIPEA_VBLANK :
-                       DE_PIPEB_VBLANK;
+       int reg;
+
+       if (INTEL_INFO(dev)->gen >= 8) {
+               status = GEN8_PIPE_VBLANK;
+               reg = GEN8_DE_PIPE_ISR(pipe);
+       } else if (INTEL_INFO(dev)->gen >= 7) {
+               status = DE_PIPE_VBLANK_IVB(pipe);
+               reg = DEISR;
        } else {
-               switch (pipe) {
-               default:
-               case PIPE_A:
-                       status = DE_PIPEA_VBLANK_IVB;
-                       break;
-               case PIPE_B:
-                       status = DE_PIPEB_VBLANK_IVB;
-                       break;
-               case PIPE_C:
-                       status = DE_PIPEC_VBLANK_IVB;
-                       break;
-               }
+               status = DE_PIPE_VBLANK(pipe);
+               reg = DEISR;
        }
 
-       return __raw_i915_read32(dev_priv, DEISR) & status;
+       return __raw_i915_read32(dev_priv, reg) & status;
 }
 
 static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
@@ -802,7 +794,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
                else
                        position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
 
-               if (HAS_PCH_SPLIT(dev)) {
+               if (HAS_DDI(dev)) {
+                       /*
+                        * On HSW HDMI outputs there seems to be a 2 line
+                        * difference, whereas eDP has the normal 1 line
+                        * difference that earlier platforms have. External
+                        * DP is unknown. For now just check for the 2 line
+                        * difference case on all output types on HSW+.
+                        *
+                        * This might misinterpret the scanline counter being
+                        * one line too far along on eDP, but that's less
+                        * dangerous than the alternative since that would lead
+                        * the vblank timestamp code astray when it sees a
+                        * scanline count before vblank_start during a vblank
+                        * interrupt.
+                        */
+                       in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
+                       if ((in_vbl && (position == vbl_start - 2 ||
+                                       position == vbl_start - 1)) ||
+                           (!in_vbl && (position == vbl_end - 2 ||
+                                        position == vbl_end - 1)))
+                               position = (position + 2) % vtotal;
+               } else if (HAS_PCH_SPLIT(dev)) {
                        /*
                         * The scanline counter increments at the leading edge
                         * of hsync, ie. it completely misses the active portion
@@ -946,8 +959,8 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
 
 static void i915_hotplug_work_func(struct work_struct *work)
 {
-       drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
-                                                   hotplug_work);
+       struct drm_i915_private *dev_priv =
+               container_of(work, struct drm_i915_private, hotplug_work);
        struct drm_device *dev = dev_priv->dev;
        struct drm_mode_config *mode_config = &dev->mode_config;
        struct intel_connector *intel_connector;
@@ -1022,7 +1035,7 @@ static void intel_hpd_irq_uninstall(struct drm_i915_private *dev_priv)
 
 static void ironlake_rps_change_irq_handler(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 busy_up, busy_down, max_avg, min_avg;
        u8 new_delay;
 
@@ -1071,47 +1084,10 @@ static void notify_ring(struct drm_device *dev,
        i915_queue_hangcheck(dev);
 }
 
-void gen6_set_pm_mask(struct drm_i915_private *dev_priv,
-                            u32 pm_iir, int new_delay)
-{
-       if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
-               if (new_delay >= dev_priv->rps.max_freq_softlimit) {
-                       /* Mask UP THRESHOLD Interrupts */
-                       I915_WRITE(GEN6_PMINTRMSK,
-                                  I915_READ(GEN6_PMINTRMSK) |
-                                  GEN6_PM_RP_UP_THRESHOLD);
-                       dev_priv->rps.rp_up_masked = true;
-               }
-               if (dev_priv->rps.rp_down_masked) {
-                       /* UnMask DOWN THRESHOLD Interrupts */
-                       I915_WRITE(GEN6_PMINTRMSK,
-                                  I915_READ(GEN6_PMINTRMSK) &
-                                  ~GEN6_PM_RP_DOWN_THRESHOLD);
-                       dev_priv->rps.rp_down_masked = false;
-               }
-       } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
-               if (new_delay <= dev_priv->rps.min_freq_softlimit) {
-                       /* Mask DOWN THRESHOLD Interrupts */
-                       I915_WRITE(GEN6_PMINTRMSK,
-                                  I915_READ(GEN6_PMINTRMSK) |
-                                  GEN6_PM_RP_DOWN_THRESHOLD);
-                       dev_priv->rps.rp_down_masked = true;
-               }
-
-               if (dev_priv->rps.rp_up_masked) {
-                       /* UnMask UP THRESHOLD Interrupts */
-                       I915_WRITE(GEN6_PMINTRMSK,
-                                  I915_READ(GEN6_PMINTRMSK) &
-                                  ~GEN6_PM_RP_UP_THRESHOLD);
-                       dev_priv->rps.rp_up_masked = false;
-               }
-       }
-}
-
 static void gen6_pm_rps_work(struct work_struct *work)
 {
-       drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
-                                                   rps.work);
+       struct drm_i915_private *dev_priv =
+               container_of(work, struct drm_i915_private, rps.work);
        u32 pm_iir;
        int new_delay, adj;
 
@@ -1119,13 +1095,13 @@ static void gen6_pm_rps_work(struct work_struct *work)
        pm_iir = dev_priv->rps.pm_iir;
        dev_priv->rps.pm_iir = 0;
        /* Make sure not to corrupt PMIMR state used by ringbuffer code */
-       snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
+       snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
        spin_unlock_irq(&dev_priv->irq_lock);
 
        /* Make sure we didn't queue anything we're not going to process. */
-       WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS);
+       WARN_ON(pm_iir & ~dev_priv->pm_rps_events);
 
-       if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0)
+       if ((pm_iir & dev_priv->pm_rps_events) == 0)
                return;
 
        mutex_lock(&dev_priv->rps.hw_lock);
@@ -1167,7 +1143,6 @@ static void gen6_pm_rps_work(struct work_struct *work)
                            dev_priv->rps.min_freq_softlimit,
                            dev_priv->rps.max_freq_softlimit);
 
-       gen6_set_pm_mask(dev_priv, pm_iir, new_delay);
        dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_freq;
 
        if (IS_VALLEYVIEW(dev_priv->dev))
@@ -1190,8 +1165,8 @@ static void gen6_pm_rps_work(struct work_struct *work)
  */
 static void ivybridge_parity_work(struct work_struct *work)
 {
-       drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
-                                                   l3_parity.error_work);
+       struct drm_i915_private *dev_priv =
+               container_of(work, struct drm_i915_private, l3_parity.error_work);
        u32 error_status, row, bank, subbank;
        char *parity_event[6];
        uint32_t misccpctl;
@@ -1263,7 +1238,7 @@ out:
 
 static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
        if (!HAS_L3_DPF(dev))
                return;
@@ -1374,7 +1349,7 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
                                         u32 hotplug_trigger,
                                         const u32 *hpd)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
        bool storm_detected = false;
 
@@ -1430,14 +1405,14 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
 
 static void gmbus_irq_handler(struct drm_device *dev)
 {
-       struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
        wake_up_all(&dev_priv->gmbus_wait_queue);
 }
 
 static void dp_aux_irq_handler(struct drm_device *dev)
 {
-       struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
        wake_up_all(&dev_priv->gmbus_wait_queue);
 }
@@ -1543,10 +1518,10 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
  * the work queue. */
 static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
 {
-       if (pm_iir & GEN6_PM_RPS_EVENTS) {
+       if (pm_iir & dev_priv->pm_rps_events) {
                spin_lock(&dev_priv->irq_lock);
-               dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS;
-               snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS);
+               dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events;
+               snb_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
                spin_unlock(&dev_priv->irq_lock);
 
                queue_work(dev_priv->wq, &dev_priv->rps.work);
@@ -1637,7 +1612,7 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
 static irqreturn_t valleyview_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 iir, gt_iir, pm_iir;
        irqreturn_t ret = IRQ_NONE;
 
@@ -1684,7 +1659,7 @@ out:
 
 static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
        u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK;
 
@@ -1791,7 +1766,7 @@ static void cpt_serr_int_handler(struct drm_device *dev)
 
 static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
        u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
 
@@ -1915,7 +1890,7 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
 static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 de_iir, gt_iir, de_ier, sde_ier = 0;
        irqreturn_t ret = IRQ_NONE;
 
@@ -2126,8 +2101,8 @@ static void i915_error_work_func(struct work_struct *work)
 {
        struct i915_gpu_error *error = container_of(work, struct i915_gpu_error,
                                                    work);
-       drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t,
-                                                   gpu_error);
+       struct drm_i915_private *dev_priv =
+               container_of(error, struct drm_i915_private, gpu_error);
        struct drm_device *dev = dev_priv->dev;
        char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
        char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
@@ -2336,7 +2311,7 @@ void i915_handle_error(struct drm_device *dev, bool wedged,
 
 static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       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;
@@ -2385,7 +2360,7 @@ static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, in
  */
 static int i915_enable_vblank(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
        if (!i915_pipe_enabled(dev, pipe))
@@ -2409,7 +2384,7 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe)
 
 static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
        uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
                                                     DE_PIPE_VBLANK(pipe);
@@ -2426,7 +2401,7 @@ static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
 
 static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
        if (!i915_pipe_enabled(dev, pipe))
@@ -2461,7 +2436,7 @@ static int gen8_enable_vblank(struct drm_device *dev, int pipe)
  */
 static void i915_disable_vblank(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
        spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
@@ -2476,7 +2451,7 @@ static void i915_disable_vblank(struct drm_device *dev, int pipe)
 
 static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
        uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
                                                     DE_PIPE_VBLANK(pipe);
@@ -2488,7 +2463,7 @@ static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
 
 static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
        spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
@@ -2530,29 +2505,43 @@ static struct intel_ring_buffer *
 semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno)
 {
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
-       u32 cmd, ipehr, acthd, acthd_min;
+       u32 cmd, ipehr, head;
+       int i;
 
        ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
        if ((ipehr & ~(0x3 << 16)) !=
            (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER))
                return NULL;
 
-       /* ACTHD is likely pointing to the dword after the actual command,
-        * so scan backwards until we find the MBOX.
+       /*
+        * HEAD is likely pointing to the dword after the actual command,
+        * so scan backwards until we find the MBOX. But limit it to just 3
+        * dwords. Note that we don't care about ACTHD here since that might
+        * point at at batch, and semaphores are always emitted into the
+        * ringbuffer itself.
         */
-       acthd = intel_ring_get_active_head(ring) & HEAD_ADDR;
-       acthd_min = max((int)acthd - 3 * 4, 0);
-       do {
-               cmd = ioread32(ring->virtual_start + acthd);
+       head = I915_READ_HEAD(ring) & HEAD_ADDR;
+
+       for (i = 4; i; --i) {
+               /*
+                * Be paranoid and presume the hw has gone off into the wild -
+                * our ring is smaller than what the hardware (and hence
+                * HEAD_ADDR) allows. Also handles wrap-around.
+                */
+               head &= ring->size - 1;
+
+               /* This here seems to blow up */
+               cmd = ioread32(ring->virtual_start + head);
                if (cmd == ipehr)
                        break;
 
-               acthd -= 4;
-               if (acthd < acthd_min)
-                       return NULL;
-       } while (1);
+               head -= 4;
+       }
 
-       *seqno = ioread32(ring->virtual_start+acthd+4)+1;
+       if (!i)
+               return NULL;
+
+       *seqno = ioread32(ring->virtual_start + head + 4) + 1;
        return &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3];
 }
 
@@ -2586,7 +2575,7 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
 }
 
 static enum intel_ring_hangcheck_action
-ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
+ring_stuck(struct intel_ring_buffer *ring, u64 acthd)
 {
        struct drm_device *dev = ring->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2641,7 +2630,7 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
 static void i915_hangcheck_elapsed(unsigned long data)
 {
        struct drm_device *dev = (struct drm_device *)data;
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring;
        int i;
        int busy_count = 0, rings_hung = 0;
@@ -2654,7 +2643,8 @@ static void i915_hangcheck_elapsed(unsigned long data)
                return;
 
        for_each_ring(ring, dev_priv, i) {
-               u32 seqno, acthd;
+               u64 acthd;
+               u32 seqno;
                bool busy = true;
 
                semaphore_clear_deadlocks(dev_priv);
@@ -2799,7 +2789,7 @@ static void gen5_gt_irq_preinstall(struct drm_device *dev)
 */
 static void ironlake_irq_preinstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
        I915_WRITE(HWSTAM, 0xeffe);
 
@@ -2814,7 +2804,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
 
 static void valleyview_irq_preinstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
        /* VLV magic */
@@ -2890,7 +2880,7 @@ static void gen8_irq_preinstall(struct drm_device *dev)
 
 static void ibx_hpd_irq_setup(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       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;
@@ -2925,17 +2915,16 @@ static void ibx_hpd_irq_setup(struct drm_device *dev)
 
 static void ibx_irq_postinstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 mask;
 
        if (HAS_PCH_NOP(dev))
                return;
 
        if (HAS_PCH_IBX(dev)) {
-               mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER |
-                      SDE_TRANSA_FIFO_UNDER | SDE_POISON;
+               mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
        } else {
-               mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT;
+               mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
 
                I915_WRITE(SERR_INT, I915_READ(SERR_INT));
        }
@@ -2972,7 +2961,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
        POSTING_READ(GTIER);
 
        if (INTEL_INFO(dev)->gen >= 6) {
-               pm_irqs |= GEN6_PM_RPS_EVENTS;
+               pm_irqs |= dev_priv->pm_rps_events;
 
                if (HAS_VEBOX(dev))
                        pm_irqs |= PM_VEBOX_USER_INTERRUPT;
@@ -2988,27 +2977,26 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
 static int ironlake_irq_postinstall(struct drm_device *dev)
 {
        unsigned long irqflags;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 display_mask, extra_mask;
 
        if (INTEL_INFO(dev)->gen >= 7) {
                display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
                                DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
                                DE_PLANEB_FLIP_DONE_IVB |
-                               DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB |
-                               DE_ERR_INT_IVB);
+                               DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
                extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
-                             DE_PIPEA_VBLANK_IVB);
+                             DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);
 
                I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
        } else {
                display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
                                DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
                                DE_AUX_CHANNEL_A |
-                               DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
                                DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
                                DE_POISON);
-               extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT;
+               extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
+                               DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
        }
 
        dev_priv->irq_mask = ~display_mask;
@@ -3126,7 +3114,7 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv)
 
 static int valleyview_irq_postinstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
        dev_priv->irq_mask = ~0;
@@ -3193,9 +3181,9 @@ 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_FLIP_DONE |
                GEN8_PIPE_CDCLK_CRC_DONE |
-               GEN8_PIPE_FIFO_UNDERRUN |
                GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
-       uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK;
+       uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
+               GEN8_PIPE_FIFO_UNDERRUN;
        int pipe;
        dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
        dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
@@ -3273,7 +3261,7 @@ static void gen8_irq_uninstall(struct drm_device *dev)
 
 static void valleyview_irq_uninstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
        int pipe;
 
@@ -3304,7 +3292,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
 
 static void ironlake_irq_uninstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
        if (!dev_priv)
                return;
@@ -3335,7 +3323,7 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
 
 static void i8xx_irq_preinstall(struct drm_device * dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
        for_each_pipe(pipe)
@@ -3347,7 +3335,7 @@ static void i8xx_irq_preinstall(struct drm_device * dev)
 
 static int i8xx_irq_postinstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
 
        I915_WRITE16(EMR,
@@ -3385,7 +3373,7 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
 static bool i8xx_handle_vblank(struct drm_device *dev,
                               int plane, int pipe, u32 iir)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
 
        if (!drm_handle_vblank(dev, pipe))
@@ -3413,7 +3401,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
 static irqreturn_t i8xx_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u16 iir, new_iir;
        u32 pipe_stats[2];
        unsigned long irqflags;
@@ -3483,7 +3471,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
 
 static void i8xx_irq_uninstall(struct drm_device * dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
        for_each_pipe(pipe) {
@@ -3498,7 +3486,7 @@ static void i8xx_irq_uninstall(struct drm_device * dev)
 
 static void i915_irq_preinstall(struct drm_device * dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
        if (I915_HAS_HOTPLUG(dev)) {
@@ -3516,7 +3504,7 @@ static void i915_irq_preinstall(struct drm_device * dev)
 
 static int i915_irq_postinstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 enable_mask;
        unsigned long irqflags;
 
@@ -3570,7 +3558,7 @@ static int i915_irq_postinstall(struct drm_device *dev)
 static bool i915_handle_vblank(struct drm_device *dev,
                               int plane, int pipe, u32 iir)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
 
        if (!drm_handle_vblank(dev, pipe))
@@ -3598,7 +3586,7 @@ static bool i915_handle_vblank(struct drm_device *dev,
 static irqreturn_t i915_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 iir, new_iir, pipe_stats[I915_MAX_PIPES];
        unsigned long irqflags;
        u32 flip_mask =
@@ -3704,7 +3692,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
 
 static void i915_irq_uninstall(struct drm_device * dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
        intel_hpd_irq_uninstall(dev_priv);
@@ -3728,7 +3716,7 @@ static void i915_irq_uninstall(struct drm_device * dev)
 
 static void i965_irq_preinstall(struct drm_device * dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
        I915_WRITE(PORT_HOTPLUG_EN, 0);
@@ -3744,7 +3732,7 @@ static void i965_irq_preinstall(struct drm_device * dev)
 
 static int i965_irq_postinstall(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 enable_mask;
        u32 error_mask;
        unsigned long irqflags;
@@ -3803,7 +3791,7 @@ static int i965_irq_postinstall(struct drm_device *dev)
 
 static void i915_hpd_irq_setup(struct drm_device *dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       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;
@@ -3835,7 +3823,7 @@ static void i915_hpd_irq_setup(struct drm_device *dev)
 static irqreturn_t i965_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 iir, new_iir;
        u32 pipe_stats[I915_MAX_PIPES];
        unsigned long irqflags;
@@ -3953,7 +3941,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
 
 static void i965_irq_uninstall(struct drm_device * dev)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
 
        if (!dev_priv)
@@ -3978,7 +3966,7 @@ static void i965_irq_uninstall(struct drm_device * dev)
 
 static void intel_hpd_irq_reenable(unsigned long data)
 {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *)data;
+       struct drm_i915_private *dev_priv = (struct drm_i915_private *)data;
        struct drm_device *dev = dev_priv->dev;
        struct drm_mode_config *mode_config = &dev->mode_config;
        unsigned long irqflags;
@@ -4020,6 +4008,9 @@ void intel_irq_init(struct drm_device *dev)
        INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
        INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
 
+       /* Let's track the enabled rps events */
+       dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
+
        setup_timer(&dev_priv->gpu_error.hangcheck_timer,
                    i915_hangcheck_elapsed,
                    (unsigned long) dev);