Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / drivers / gpu / drm / i915 / intel_display.c
index d809b03..c7b5428 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/cpufreq.h>
+#include <linux/dmi.h>
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
@@ -138,8 +139,8 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
        .vco = { .min = 1400000, .max = 2800000 },
        .n = { .min = 1, .max = 6 },
        .m = { .min = 70, .max = 120 },
-       .m1 = { .min = 10, .max = 22 },
-       .m2 = { .min = 5, .max = 9 },
+       .m1 = { .min = 8, .max = 18 },
+       .m2 = { .min = 3, .max = 7 },
        .p = { .min = 5, .max = 80 },
        .p1 = { .min = 1, .max = 8 },
        .p2 = { .dot_limit = 200000,
@@ -356,6 +357,27 @@ static const intel_limit_t intel_limits_ironlake_display_port = {
        .find_pll = intel_find_pll_ironlake_dp,
 };
 
+static bool is_dual_link_lvds(struct drm_i915_private *dev_priv,
+                             unsigned int reg)
+{
+       unsigned int val;
+
+       if (dev_priv->lvds_val)
+               val = dev_priv->lvds_val;
+       else {
+               /* BIOS should set the proper LVDS register value at boot, but
+                * in reality, it doesn't set the value when the lid is closed;
+                * we need to check "the value to be set" in VBT when LVDS
+                * register is uninitialized.
+                */
+               val = I915_READ(reg);
+               if (!(val & ~LVDS_DETECTED))
+                       val = dev_priv->bios_lvds_val;
+               dev_priv->lvds_val = val;
+       }
+       return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
+}
+
 static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
                                                int refclk)
 {
@@ -364,8 +386,7 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
        const intel_limit_t *limit;
 
        if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-               if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
-                   LVDS_CLKB_POWER_UP) {
+               if (is_dual_link_lvds(dev_priv, PCH_LVDS)) {
                        /* LVDS dual channel */
                        if (refclk == 100000)
                                limit = &intel_limits_ironlake_dual_lvds_100m;
@@ -393,8 +414,7 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
        const intel_limit_t *limit;
 
        if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-               if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-                   LVDS_CLKB_POWER_UP)
+               if (is_dual_link_lvds(dev_priv, LVDS))
                        /* LVDS with dual channel */
                        limit = &intel_limits_g4x_dual_channel_lvds;
                else
@@ -531,8 +551,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
                 * reliably set up different single/dual channel state, if we
                 * even can.
                 */
-               if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-                   LVDS_CLKB_POWER_UP)
+               if (is_dual_link_lvds(dev_priv, LVDS))
                        clock.p2 = limit->p2.p2_fast;
                else
                        clock.p2 = limit->p2.p2_slow;
@@ -1072,8 +1091,8 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
                                     enum pipe pipe, int reg)
 {
        u32 val = I915_READ(reg);
-       WARN(hdmi_pipe_enabled(dev_priv, val, pipe),
-            "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
+       WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
+            "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
             reg, pipe_name(pipe));
 }
 
@@ -1089,13 +1108,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
 
        reg = PCH_ADPA;
        val = I915_READ(reg);
-       WARN(adpa_pipe_enabled(dev_priv, val, pipe),
+       WARN(adpa_pipe_enabled(dev_priv, pipe, val),
             "PCH VGA enabled on transcoder %c, should be disabled\n",
             pipe_name(pipe));
 
        reg = PCH_LVDS;
        val = I915_READ(reg);
-       WARN(lvds_pipe_enabled(dev_priv, val, pipe),
+       WARN(lvds_pipe_enabled(dev_priv, pipe, val),
             "PCH LVDS enabled on transcoder %c, should be disabled\n",
             pipe_name(pipe));
 
@@ -1437,7 +1456,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
                             enum pipe pipe, int reg)
 {
        u32 val = I915_READ(reg);
-       if (hdmi_pipe_enabled(dev_priv, val, pipe)) {
+       if (hdmi_pipe_enabled(dev_priv, pipe, val)) {
                DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",
                              reg, pipe);
                I915_WRITE(reg, val & ~PORT_ENABLE);
@@ -1459,12 +1478,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
 
        reg = PCH_ADPA;
        val = I915_READ(reg);
-       if (adpa_pipe_enabled(dev_priv, val, pipe))
+       if (adpa_pipe_enabled(dev_priv, pipe, val))
                I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
 
        reg = PCH_LVDS;
        val = I915_READ(reg);
-       if (lvds_pipe_enabled(dev_priv, val, pipe)) {
+       if (lvds_pipe_enabled(dev_priv, pipe, val)) {
                DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);
                I915_WRITE(reg, val & ~LVDS_PORT_EN);
                POSTING_READ(reg);
@@ -1864,7 +1883,7 @@ static void intel_update_fbc(struct drm_device *dev)
        if (enable_fbc < 0) {
                DRM_DEBUG_KMS("fbc set to per-chip default\n");
                enable_fbc = 1;
-               if (INTEL_INFO(dev)->gen <= 5)
+               if (INTEL_INFO(dev)->gen <= 6)
                        enable_fbc = 0;
        }
        if (!enable_fbc) {
@@ -2186,6 +2205,33 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        return 0;
 }
 
+static int
+intel_finish_fb(struct drm_framebuffer *old_fb)
+{
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
+       struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+       bool was_interruptible = dev_priv->mm.interruptible;
+       int ret;
+
+       wait_event(dev_priv->pending_flip_queue,
+                  atomic_read(&dev_priv->mm.wedged) ||
+                  atomic_read(&obj->pending_flip) == 0);
+
+       /* Big Hammer, we also need to ensure that any pending
+        * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+        * current scanout is retired before unpinning the old
+        * framebuffer.
+        *
+        * This should only fail upon a hung GPU, in which case we
+        * can safely continue.
+        */
+       dev_priv->mm.interruptible = false;
+       ret = i915_gem_object_finish_gpu(obj);
+       dev_priv->mm.interruptible = was_interruptible;
+
+       return ret;
+}
+
 static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                    struct drm_framebuffer *old_fb)
@@ -2224,25 +2270,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                return ret;
        }
 
-       if (old_fb) {
-               struct drm_i915_private *dev_priv = dev->dev_private;
-               struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
-
-               wait_event(dev_priv->pending_flip_queue,
-                          atomic_read(&dev_priv->mm.wedged) ||
-                          atomic_read(&obj->pending_flip) == 0);
-
-               /* Big Hammer, we also need to ensure that any pending
-                * MI_WAIT_FOR_EVENT inside a user batch buffer on the
-                * current scanout is retired before unpinning the old
-                * framebuffer.
-                *
-                * This should only fail upon a hung GPU, in which case we
-                * can safely continue.
-                */
-               ret = i915_gem_object_finish_gpu(obj);
-               (void) ret;
-       }
+       if (old_fb)
+               intel_finish_fb(old_fb);
 
        ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
                                         LEAVE_ATOMIC_MODE_SET);
@@ -2356,18 +2385,6 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
                           FDI_FE_ERRC_ENABLE);
 }
 
-static void cpt_phase_pointer_enable(struct drm_device *dev, int pipe)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 flags = I915_READ(SOUTH_CHICKEN1);
-
-       flags |= FDI_PHASE_SYNC_OVR(pipe);
-       I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
-       flags |= FDI_PHASE_SYNC_EN(pipe);
-       I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
-       POSTING_READ(SOUTH_CHICKEN1);
-}
-
 /* The FDI link training functions for ILK/Ibexpeak. */
 static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 {
@@ -2411,11 +2428,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
        udelay(150);
 
        /* Ironlake workaround, enable clock pointer after FDI enable*/
-       if (HAS_PCH_IBX(dev)) {
-               I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
-               I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR |
-                          FDI_RX_PHASE_SYNC_POINTER_EN);
-       }
+       I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
+       I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR |
+                  FDI_RX_PHASE_SYNC_POINTER_EN);
 
        reg = FDI_RX_IIR(pipe);
        for (tries = 0; tries < 5; tries++) {
@@ -2518,9 +2533,6 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
        POSTING_READ(reg);
        udelay(150);
 
-       if (HAS_PCH_CPT(dev))
-               cpt_phase_pointer_enable(dev, pipe);
-
        for (i = 0; i < 4; i++) {
                reg = FDI_TX_CTL(pipe);
                temp = I915_READ(reg);
@@ -2639,9 +2651,6 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
        POSTING_READ(reg);
        udelay(150);
 
-       if (HAS_PCH_CPT(dev))
-               cpt_phase_pointer_enable(dev, pipe);
-
        for (i = 0; i < 4; i++) {
                reg = FDI_TX_CTL(pipe);
                temp = I915_READ(reg);
@@ -2751,17 +2760,6 @@ static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
        }
 }
 
-static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 flags = I915_READ(SOUTH_CHICKEN1);
-
-       flags &= ~(FDI_PHASE_SYNC_EN(pipe));
-       I915_WRITE(SOUTH_CHICKEN1, flags); /* once to disable... */
-       flags &= ~(FDI_PHASE_SYNC_OVR(pipe));
-       I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to lock */
-       POSTING_READ(SOUTH_CHICKEN1);
-}
 static void ironlake_fdi_disable(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -2791,8 +2789,6 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
                I915_WRITE(FDI_RX_CHICKEN(pipe),
                           I915_READ(FDI_RX_CHICKEN(pipe) &
                                     ~FDI_RX_PHASE_SYNC_POINTER_EN));
-       } else if (HAS_PCH_CPT(dev)) {
-               cpt_phase_pointer_disable(dev, pipe);
        }
 
        /* still set train pattern 1 */
@@ -2840,18 +2836,37 @@ static void intel_clear_scanline_wait(struct drm_device *dev)
                I915_WRITE_CTL(ring, tmp);
 }
 
+static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       unsigned long flags;
+       bool pending;
+
+       if (atomic_read(&dev_priv->mm.wedged))
+               return false;
+
+       spin_lock_irqsave(&dev->event_lock, flags);
+       pending = to_intel_crtc(crtc)->unpin_work != NULL;
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+
+       return pending;
+}
+
 static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 {
-       struct drm_i915_gem_object *obj;
-       struct drm_i915_private *dev_priv;
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
        if (crtc->fb == NULL)
                return;
 
-       obj = to_intel_framebuffer(crtc->fb)->obj;
-       dev_priv = crtc->dev->dev_private;
        wait_event(dev_priv->pending_flip_queue,
-                  atomic_read(&obj->pending_flip) == 0);
+                  !intel_crtc_has_pending_flip(crtc));
+
+       mutex_lock(&dev->struct_mutex);
+       intel_finish_fb(crtc->fb);
+       mutex_unlock(&dev->struct_mutex);
 }
 
 static bool intel_crtc_driving_pch(struct drm_crtc *crtc)
@@ -3026,7 +3041,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
                 * as some pre-programmed values are broken,
                 * e.g. x201.
                 */
-               I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
+               if (IS_IVYBRIDGE(dev))
+                       I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 |
+                                                PF_PIPE_SEL_IVB(pipe));
+               else
+                       I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
                I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos);
                I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size);
        }
@@ -3224,6 +3243,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
        int plane = intel_crtc->plane;
+       u32 pctl;
 
        if (!intel_crtc->active)
                return;
@@ -3239,6 +3259,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 
        intel_disable_plane(dev_priv, plane, pipe);
        intel_disable_pipe(dev_priv, pipe);
+
+       /* Disable pannel fitter if it is on this pipe. */
+       pctl = I915_READ(PFIT_CONTROL);
+       if ((pctl & PFIT_ENABLE) &&
+           ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe)
+               I915_WRITE(PFIT_CONTROL, 0);
+
        intel_disable_pll(dev_priv, pipe);
 
        intel_crtc->active = false;
@@ -4721,17 +4748,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        continue;
                }
 
-               if (intel_encoder->type == INTEL_OUTPUT_EDP) {
-                       /* Use VBT settings if we have an eDP panel */
-                       unsigned int edp_bpc = dev_priv->edp.bpp / 3;
-
-                       if (edp_bpc < display_bpc) {
-                               DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
-                               display_bpc = edp_bpc;
-                       }
-                       continue;
-               }
-
                /* Not one of the known troublemakers, check the EDID */
                list_for_each_entry(connector, &dev->mode_config.connector_list,
                                    head) {
@@ -4746,6 +4762,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        }
                }
 
+               if (intel_encoder->type == INTEL_OUTPUT_EDP) {
+                       /* Use VBT settings if we have an eDP panel */
+                       unsigned int edp_bpc = dev_priv->edp.bpp / 3;
+
+                       if (edp_bpc && edp_bpc < display_bpc) {
+                               DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
+                               display_bpc = edp_bpc;
+                       }
+                       continue;
+               }
+
                /*
                 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
                 * through, clamp it down.  (Note: >12bpc will be caught below.)
@@ -5030,7 +5057,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
        /* default to 8bpc */
        pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN);
        if (is_dp) {
-               if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
+               if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
                        pipeconf |= PIPECONF_BPP_6 |
                                    PIPECONF_DITHER_EN |
                                    PIPECONF_DITHER_TYPE_SP;
@@ -5498,7 +5525,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
        /* determine panel color depth */
        temp = I915_READ(PIPECONF(pipe));
        temp &= ~PIPE_BPC_MASK;
-       dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, mode);
+       dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, adjusted_mode);
        switch (pipe_bpp) {
        case 18:
                temp |= PIPE_6BPC;
@@ -5646,12 +5673,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
        if (is_lvds) {
                temp = I915_READ(PCH_LVDS);
                temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
-               if (HAS_PCH_CPT(dev))
+               if (HAS_PCH_CPT(dev)) {
+                       temp &= ~PORT_TRANS_SEL_MASK;
                        temp |= PORT_TRANS_SEL_CPT(pipe);
-               else if (pipe == 1)
-                       temp |= LVDS_PIPEB_SELECT;
-               else
-                       temp &= ~LVDS_PIPEB_SELECT;
+               } else {
+                       if (pipe == 1)
+                               temp |= LVDS_PIPEB_SELECT;
+                       else
+                               temp &= ~LVDS_PIPEB_SELECT;
+               }
 
                /* set the corresponsding LVDS_BORDER bit */
                temp |= dev_priv->lvds_border_bits;
@@ -5876,14 +5906,14 @@ static void ironlake_write_eld(struct drm_connector *connector,
        int aud_cntl_st;
        int aud_cntrl_st2;
 
-       if (IS_IVYBRIDGE(connector->dev)) {
-               hdmiw_hdmiedid = GEN7_HDMIW_HDMIEDID_A;
-               aud_cntl_st = GEN7_AUD_CNTRL_ST_A;
-               aud_cntrl_st2 = GEN7_AUD_CNTRL_ST2;
-       } else {
+       if (HAS_PCH_IBX(connector->dev)) {
                hdmiw_hdmiedid = GEN5_HDMIW_HDMIEDID_A;
                aud_cntl_st = GEN5_AUD_CNTL_ST_A;
                aud_cntrl_st2 = GEN5_AUD_CNTL_ST2;
+       } else {
+               hdmiw_hdmiedid = GEN7_HDMIW_HDMIEDID_A;
+               aud_cntl_st = GEN7_AUD_CNTRL_ST_A;
+               aud_cntrl_st2 = GEN7_AUD_CNTRL_ST2;
        }
 
        i = to_intel_crtc(crtc)->pipe;
@@ -5965,7 +5995,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
        int i;
 
        /* The clocks have to be on to load the palette. */
-       if (!crtc->enabled)
+       if (!crtc->enabled || !intel_crtc->active)
                return;
 
        /* use legacy palette for Ironlake */
@@ -6033,7 +6063,9 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
                intel_crtc->cursor_visible = visible;
        }
        /* and commit changes on next vblank */
+       POSTING_READ(CURCNTR(pipe));
        I915_WRITE(CURBASE(pipe), base);
+       POSTING_READ(CURBASE(pipe));
 }
 
 static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
@@ -6058,7 +6090,9 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
                intel_crtc->cursor_visible = visible;
        }
        /* and commit changes on next vblank */
+       POSTING_READ(CURCNTR_IVB(pipe));
        I915_WRITE(CURBASE_IVB(pipe), base);
+       POSTING_READ(CURBASE_IVB(pipe));
 }
 
 /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
@@ -6906,11 +6940,18 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
 
        spin_lock_irqsave(&dev->event_lock, flags);
        work = intel_crtc->unpin_work;
-       if (work == NULL || !work->pending) {
+
+       /* Ensure we don't miss a work->pending update ... */
+       smp_rmb();
+
+       if (work == NULL || atomic_read(&work->pending) < INTEL_FLIP_COMPLETE) {
                spin_unlock_irqrestore(&dev->event_lock, flags);
                return;
        }
 
+       /* and that the unpin work is consistent wrt ->pending. */
+       smp_rmb();
+
        intel_crtc->unpin_work = NULL;
 
        if (work->event) {
@@ -6952,12 +6993,11 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
 
        atomic_clear_mask(1 << intel_crtc->plane,
                          &obj->pending_flip.counter);
-       if (atomic_read(&obj->pending_flip) == 0)
-               wake_up(&dev_priv->pending_flip_queue);
-
-       schedule_work(&work->work);
 
+       wake_up(&dev_priv->pending_flip_queue);
        trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
+
+       schedule_work(&work->work);
 }
 
 void intel_finish_page_flip(struct drm_device *dev, int pipe)
@@ -6983,16 +7023,25 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
                to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
        unsigned long flags;
 
+       /* NB: An MMIO update of the plane base pointer will also
+        * generate a page-flip completion irq, i.e. every modeset
+        * is also accompanied by a spurious intel_prepare_page_flip().
+        */
        spin_lock_irqsave(&dev->event_lock, flags);
-       if (intel_crtc->unpin_work) {
-               if ((++intel_crtc->unpin_work->pending) > 1)
-                       DRM_ERROR("Prepared flip multiple times\n");
-       } else {
-               DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
-       }
+       if (intel_crtc->unpin_work)
+               atomic_inc_not_zero(&intel_crtc->unpin_work->pending);
        spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
+inline static void intel_mark_page_flip_active(struct intel_crtc *intel_crtc)
+{
+       /* Ensure that the work item is consistent when activating it ... */
+       smp_wmb();
+       atomic_set(&intel_crtc->unpin_work->pending, INTEL_FLIP_PENDING);
+       /* and that it is marked active as soon as the irq could fire. */
+       smp_wmb();
+}
+
 static int intel_gen2_queue_flip(struct drm_device *dev,
                                 struct drm_crtc *crtc,
                                 struct drm_framebuffer *fb,
@@ -7006,14 +7055,14 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
 
        ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
        if (ret)
-               goto out;
+               goto err;
 
        /* Offset into the new buffer for cases of shared fbs between CRTCs */
        offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
 
        ret = BEGIN_LP_RING(6);
        if (ret)
-               goto out;
+               goto err_unpin;
 
        /* Can't queue multiple flips, so wait for the previous
         * one to finish before executing the next.
@@ -7029,8 +7078,14 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
        OUT_RING(fb->pitch);
        OUT_RING(obj->gtt_offset + offset);
        OUT_RING(MI_NOOP);
+
+       intel_mark_page_flip_active(intel_crtc);
        ADVANCE_LP_RING();
-out:
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err:
        return ret;
 }
 
@@ -7047,14 +7102,14 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
 
        ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
        if (ret)
-               goto out;
+               goto err;
 
        /* Offset into the new buffer for cases of shared fbs between CRTCs */
        offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
 
        ret = BEGIN_LP_RING(6);
        if (ret)
-               goto out;
+               goto err_unpin;
 
        if (intel_crtc->plane)
                flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
@@ -7068,8 +7123,13 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
        OUT_RING(obj->gtt_offset + offset);
        OUT_RING(MI_NOOP);
 
+       intel_mark_page_flip_active(intel_crtc);
        ADVANCE_LP_RING();
-out:
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err:
        return ret;
 }
 
@@ -7085,11 +7145,11 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
 
        ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
        if (ret)
-               goto out;
+               goto err;
 
        ret = BEGIN_LP_RING(4);
        if (ret)
-               goto out;
+               goto err_unpin;
 
        /* i965+ uses the linear or tiled offsets from the
         * Display Registers (which do not change across a page-flip)
@@ -7107,8 +7167,14 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
        pf = 0;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
        OUT_RING(pf | pipesrc);
+
+       intel_mark_page_flip_active(intel_crtc);
        ADVANCE_LP_RING();
-out:
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err:
        return ret;
 }
 
@@ -7124,11 +7190,11 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
 
        ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
        if (ret)
-               goto out;
+               goto err;
 
        ret = BEGIN_LP_RING(4);
        if (ret)
-               goto out;
+               goto err_unpin;
 
        OUT_RING(MI_DISPLAY_FLIP |
                 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
@@ -7138,8 +7204,14 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
        pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
        OUT_RING(pf | pipesrc);
+
+       intel_mark_page_flip_active(intel_crtc);
        ADVANCE_LP_RING();
-out:
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err:
        return ret;
 }
 
@@ -7157,22 +7229,59 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_ring_buffer *ring = &dev_priv->ring[BCS];
+       uint32_t plane_bit = 0;
        int ret;
 
        ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
        if (ret)
-               goto out;
+               goto err;
+
+       switch(intel_crtc->plane) {
+       case PLANE_A:
+               plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
+               break;
+       case PLANE_B:
+               plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
+               break;
+       case PLANE_C:
+               plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
+               break;
+       default:
+               WARN_ONCE(1, "unknown plane in flip command\n");
+               ret = -ENODEV;
+               goto err_unpin;
+       }
+
+       /*
+        * BSpec MI_DISPLAY_FLIP for IVB:
+        * "The full packet must be contained within the same cache line."
+        *
+        * Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same
+        * cacheline, if we ever start emitting more commands before
+        * the MI_DISPLAY_FLIP we may need to first emit everything else,
+        * then do the cacheline alignment, and finally emit the
+        * MI_DISPLAY_FLIP.
+        */
+       ret = intel_ring_cacheline_align(ring);
+       if (ret)
+               goto err_unpin;
 
        ret = intel_ring_begin(ring, 4);
        if (ret)
-               goto out;
+               goto err_unpin;
 
-       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19));
+       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
        intel_ring_emit(ring, (fb->pitch | obj->tiling_mode));
        intel_ring_emit(ring, (obj->gtt_offset));
        intel_ring_emit(ring, (MI_NOOP));
+
+       intel_mark_page_flip_active(intel_crtc);
        intel_ring_advance(ring);
-out:
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err:
        return ret;
 }
 
@@ -7190,8 +7299,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_framebuffer *intel_fb;
-       struct drm_i915_gem_object *obj;
+       struct drm_framebuffer *old_fb = crtc->fb;
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_unpin_work *work;
        unsigned long flags;
@@ -7203,8 +7312,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        work->event = event;
        work->dev = crtc->dev;
-       intel_fb = to_intel_framebuffer(crtc->fb);
-       work->old_fb_obj = intel_fb->obj;
+       work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
        INIT_WORK(&work->work, intel_unpin_work_fn);
 
        ret = drm_vblank_get(dev, intel_crtc->pipe);
@@ -7224,9 +7332,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        intel_crtc->unpin_work = work;
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
-       intel_fb = to_intel_framebuffer(fb);
-       obj = intel_fb->obj;
-
        mutex_lock(&dev->struct_mutex);
 
        /* Reference the objects for the scheduled work. */
@@ -7257,6 +7362,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
 cleanup_pending:
        atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
+       crtc->fb = old_fb;
        drm_gem_object_unreference(&work->old_fb_obj->base);
        drm_gem_object_unreference(&obj->base);
        mutex_unlock(&dev->struct_mutex);
@@ -7277,6 +7383,13 @@ static void intel_sanitize_modesetting(struct drm_device *dev,
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 reg, val;
+       int i;
+
+       /* Clear any frame start delays used for debugging left by the BIOS */
+       for_each_pipe(i) {
+               reg = PIPECONF(i);
+               I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+       }
 
        if (HAS_PCH_SPLIT(dev))
                return;
@@ -7922,13 +8035,11 @@ static bool intel_enable_rc6(struct drm_device *dev)
                return 0;
 
        /*
-        * Enable rc6 on Sandybridge if DMA remapping is disabled
+        * Disable rc6 on Sandybridge
         */
        if (INTEL_INFO(dev)->gen == 6) {
-               DRM_DEBUG_DRIVER("Sandybridge: intel_iommu_enabled %s -- RC6 %sabled\n",
-                                intel_iommu_enabled ? "true" : "false",
-                                !intel_iommu_enabled ? "en" : "dis");
-               return !intel_iommu_enabled;
+               DRM_DEBUG_DRIVER("Sandybridge: RC6 disabled\n");
+               return 0;
        }
        DRM_DEBUG_DRIVER("RC6 enabled\n");
        return 1;
@@ -7967,12 +8078,12 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN6_RC_SLEEP, 0);
        I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
        I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
-       I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
+       I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
        I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
        if (intel_enable_rc6(dev_priv->dev))
-               rc6_mask = GEN6_RC_CTL_RC6p_ENABLE |
-                       GEN6_RC_CTL_RC6_ENABLE;
+               rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
+                       ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0);
 
        I915_WRITE(GEN6_RC_CONTROL,
                   rc6_mask |
@@ -7997,7 +8108,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
        I915_WRITE(GEN6_RP_CONTROL,
                   GEN6_RP_MEDIA_TURBO |
-                  GEN6_RP_USE_NORMAL_FREQ |
+                  GEN6_RP_MEDIA_HW_NORMAL_MODE |
                   GEN6_RP_MEDIA_IS_GFX |
                   GEN6_RP_ENABLE |
                   GEN6_RP_UP_BUSY_AVG |
@@ -8192,6 +8303,10 @@ static void gen6_init_clock_gating(struct drm_device *dev)
                   I915_READ(ILK_DISPLAY_CHICKEN2) |
                   ILK_ELPIN_409_SELECT);
 
+       /* WaDisableHiZPlanesWhenMSAAEnabled */
+       I915_WRITE(_3D_CHICKEN,
+                  _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB));
+
        I915_WRITE(WM3_LP_ILK, 0);
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
@@ -8236,6 +8351,23 @@ static void gen6_init_clock_gating(struct drm_device *dev)
                           DISPPLANE_TRICKLE_FEED_DISABLE);
                intel_flush_display_plane(dev_priv, pipe);
        }
+
+       /* The default value should be 0x200 according to docs, but the two
+        * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */
+       I915_WRITE(GEN6_GT_MODE, 0xffff << 16);
+       I915_WRITE(GEN6_GT_MODE, GEN6_GT_MODE_HI << 16 | GEN6_GT_MODE_HI);
+}
+
+static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
+{
+       uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE);
+
+       reg &= ~GEN7_FF_SCHED_MASK;
+       reg |= GEN7_FF_TS_SCHED_HW;
+       reg |= GEN7_FF_VS_SCHED_HW;
+       reg |= GEN7_FF_DS_SCHED_HW;
+
+       I915_WRITE(GEN7_FF_THREAD_MODE, reg);
 }
 
 static void ivybridge_init_clock_gating(struct drm_device *dev)
@@ -8250,14 +8382,36 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
 
+       /* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
+        * This implements the WaDisableRCZUnitClockGating workaround.
+        */
+       I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
+
        I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
 
+       /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
+       I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
+                  GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
+
+       /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
+       I915_WRITE(GEN7_L3CNTLREG1,
+                       GEN7_WA_FOR_GEN7_L3_CONTROL);
+       I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
+                       GEN7_WA_L3_CHICKEN_MODE);
+
+       /* This is required by WaCatErrorRejectionIssue */
+       I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
+                       I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+                       GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
+
        for_each_pipe(pipe) {
                I915_WRITE(DSPCNTR(pipe),
                           I915_READ(DSPCNTR(pipe)) |
                           DISPPLANE_TRICKLE_FEED_DISABLE);
                intel_flush_display_plane(dev_priv, pipe);
        }
+
+       gen7_setup_fixed_func_scheduler(dev_priv);
 }
 
 static void g4x_init_clock_gating(struct drm_device *dev)
@@ -8696,6 +8850,27 @@ static void quirk_ssc_force_disable(struct drm_device *dev)
        dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE;
 }
 
+/*
+ * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight
+ * brightness value
+ */
+static void quirk_invert_brightness(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS;
+}
+
+/*
+ * Some machines (Dell XPS13) suffer broken backlight controls if
+ * BLM_PCH_PWM_ENABLE is set.
+ */
+static void quirk_no_pcm_pwm_enable(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE;
+       DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n");
+}
+
 struct intel_quirk {
        int device;
        int subsystem_vendor;
@@ -8703,6 +8878,34 @@ struct intel_quirk {
        void (*hook)(struct drm_device *dev);
 };
 
+/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
+struct intel_dmi_quirk {
+       void (*hook)(struct drm_device *dev);
+       const struct dmi_system_id (*dmi_id_list)[];
+};
+
+static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
+{
+       DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
+       return 1;
+}
+
+static const struct intel_dmi_quirk intel_dmi_quirks[] = {
+       {
+               .dmi_id_list = &(const struct dmi_system_id[]) {
+                       {
+                               .callback = intel_dmi_reverse_brightness,
+                               .ident = "NCR Corporation",
+                               .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
+                                           DMI_MATCH(DMI_PRODUCT_NAME, ""),
+                               },
+                       },
+                       { }  /* terminating entry */
+               },
+               .hook = quirk_invert_brightness,
+       },
+};
+
 struct intel_quirk intel_quirks[] = {
        /* HP Compaq 2730p needs pipe A force quirk (LP: #291555) */
        { 0x2a42, 0x103c, 0x30eb, quirk_pipea_force },
@@ -8730,6 +8933,29 @@ struct intel_quirk intel_quirks[] = {
 
        /* Sony Vaio Y cannot use SSC on LVDS */
        { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
+
+       /* Acer Aspire 5734Z must invert backlight brightness */
+       { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
+
+       /* Acer/eMachines G725 */
+       { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
+
+       /* Acer/eMachines e725 */
+       { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
+
+       /* Acer/Packard Bell NCL20 */
+       { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
+
+       /* Acer Aspire 4736Z */
+       { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
+
+       /* Acer Aspire 5336 */
+       { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
+
+       /* Dell XPS13 HD Sandy Bridge */
+       { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
+       /* Dell XPS13 HD and XPS13 FHD Ivy Bridge */
+       { 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable },
 };
 
 static void intel_init_quirks(struct drm_device *dev)
@@ -8747,6 +8973,10 @@ static void intel_init_quirks(struct drm_device *dev)
                     q->subsystem_device == PCI_ANY_ID))
                        q->hook(dev);
        }
+       for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
+               if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
+                       intel_dmi_quirks[i].hook(dev);
+       }
 }
 
 /* Disable the VGA plane that we never use */
@@ -8772,6 +9002,23 @@ static void i915_disable_vga(struct drm_device *dev)
        POSTING_READ(vga_reg);
 }
 
+void i915_redisable_vga(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 vga_reg;
+
+       if (HAS_PCH_SPLIT(dev))
+               vga_reg = CPU_VGACNTRL;
+       else
+               vga_reg = VGACNTRL;
+
+       if (I915_READ(vga_reg) != VGA_DISP_DISABLE) {
+               DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
+               I915_WRITE(vga_reg, VGA_DISP_DISABLE);
+               POSTING_READ(vga_reg);
+       }
+}
+
 void intel_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -8886,6 +9133,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
        del_timer_sync(&dev_priv->idle_timer);
        cancel_work_sync(&dev_priv->idle_work);
 
+       /* destroy backlight, if any, before the connectors */
+       intel_panel_destroy_backlight(dev);
+
        drm_mode_config_cleanup(dev);
 }
 
@@ -8911,14 +9161,15 @@ void intel_connector_attach_encoder(struct intel_connector *connector,
 int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
+       unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
        u16 gmch_ctrl;
 
-       pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl);
+       pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl);
        if (state)
                gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
        else
                gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
-       pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
+       pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl);
        return 0;
 }