drm/i915: ILK, SNB and IVB don't have linetime watermarks
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / intel_display.c
index b9d5711c595cb3feb5317ca4463267471ac0291a..c7bdbcb6a6750ac846ee40d75c3808be0517208b 100644 (file)
@@ -651,12 +651,6 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
        found = false;
 
        if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-               int lvds_reg;
-
-               if (HAS_PCH_SPLIT(dev))
-                       lvds_reg = PCH_LVDS;
-               else
-                       lvds_reg = LVDS;
                if (intel_is_dual_link_lvds(dev))
                        clock.p2 = limit->p2.p2_fast;
                else
@@ -1110,8 +1104,8 @@ void assert_pipe(struct drm_i915_private *dev_priv,
        if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
                state = true;
 
-       if (!intel_using_power_well(dev_priv->dev) &&
-           cpu_transcoder != TRANSCODER_EDP) {
+       if (!intel_display_power_enabled(dev_priv->dev,
+                               POWER_DOMAIN_TRANSCODER(cpu_transcoder))) {
                cur_state = false;
        } else {
                reg = PIPECONF(cpu_transcoder);
@@ -3416,6 +3410,21 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
        intel_wait_for_vblank(dev, intel_crtc->pipe);
 }
 
+static void ironlake_pfit_disable(struct intel_crtc *crtc)
+{
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int pipe = crtc->pipe;
+
+       /* To avoid upsetting the power well on haswell only disable the pfit if
+        * it's in use. The hw state code will make sure we get this right. */
+       if (crtc->config.pch_pfit.size) {
+               I915_WRITE(PF_CTL(pipe), 0);
+               I915_WRITE(PF_WIN_POS(pipe), 0);
+               I915_WRITE(PF_WIN_SZ(pipe), 0);
+       }
+}
+
 static void ironlake_crtc_disable(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -3445,9 +3454,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
        intel_set_pch_fifo_underrun_reporting(dev, pipe, false);
        intel_disable_pipe(dev_priv, pipe);
 
-       /* Disable PF */
-       I915_WRITE(PF_CTL(pipe), 0);
-       I915_WRITE(PF_WIN_SZ(pipe), 0);
+       ironlake_pfit_disable(intel_crtc);
 
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->post_disable)
@@ -3518,24 +3525,19 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
        drm_vblank_off(dev, pipe);
        intel_crtc_update_cursor(crtc, false);
 
-       intel_disable_plane(dev_priv, plane, pipe);
-
+       /* FBC must be disabled before disabling the plane on HSW. */
        if (dev_priv->cfb_plane == plane)
                intel_disable_fbc(dev);
 
+       intel_disable_plane(dev_priv, plane, pipe);
+
        if (intel_crtc->config.has_pch_encoder)
                intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false);
        intel_disable_pipe(dev_priv, pipe);
 
        intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
-       /* XXX: Once we have proper panel fitter state tracking implemented with
-        * hardware state read/check support we should switch to only disable
-        * the panel fitter when we know it's used. */
-       if (intel_using_power_well(dev)) {
-               I915_WRITE(PF_CTL(pipe), 0);
-               I915_WRITE(PF_WIN_SZ(pipe), 0);
-       }
+       ironlake_pfit_disable(intel_crtc);
 
        intel_ddi_disable_pipe_clock(intel_crtc);
 
@@ -3622,8 +3624,7 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc_config *pipe_config = &crtc->config;
 
-       if (!(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) ||
-             intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)))
+       if (!crtc->config.gmch_pfit.control)
                return;
 
        WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE);
@@ -3742,20 +3743,15 @@ static void i9xx_pfit_disable(struct intel_crtc *crtc)
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       enum pipe pipe;
-       uint32_t pctl = I915_READ(PFIT_CONTROL);
 
-       assert_pipe_disabled(dev_priv, crtc->pipe);
+       if (!crtc->config.gmch_pfit.control)
+               return;
 
-       if (INTEL_INFO(dev)->gen >= 4)
-               pipe = (pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT;
-       else
-               pipe = PIPE_B;
+       assert_pipe_disabled(dev_priv, crtc->pipe);
 
-       if (pipe == crtc->pipe) {
-               DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n", pctl);
-               I915_WRITE(PFIT_CONTROL, 0);
-       }
+       DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
+                        I915_READ(PFIT_CONTROL));
+       I915_WRITE(PFIT_CONTROL, 0);
 }
 
 static void i9xx_crtc_disable(struct drm_crtc *crtc)
@@ -3863,8 +3859,8 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
        /* crtc should still be enabled when we disable it. */
        WARN_ON(!crtc->enabled);
 
-       intel_crtc->eld_vld = false;
        dev_priv->display.crtc_disable(crtc);
+       intel_crtc->eld_vld = false;
        intel_crtc_update_sarea(crtc, false);
        dev_priv->display.off(crtc);
 
@@ -4124,8 +4120,8 @@ static int intel_crtc_compute_config(struct drm_crtc *crtc,
        if (!pipe_config->timings_set)
                drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-       /* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
-        * with a hsync front porch of 0.
+       /* Cantiga+ cannot handle modes with a hsync front porch of 0.
+        * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
         */
        if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) &&
                adjusted_mode->hsync_start == adjusted_mode->hdisplay)
@@ -4215,33 +4211,43 @@ static int i830_get_display_clock_speed(struct drm_device *dev)
 }
 
 static void
-intel_reduce_ratio(uint32_t *num, uint32_t *den)
+intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
 {
-       while (*num > 0xffffff || *den > 0xffffff) {
+       while (*num > DATA_LINK_M_N_MASK ||
+              *den > DATA_LINK_M_N_MASK) {
                *num >>= 1;
                *den >>= 1;
        }
 }
 
+static void compute_m_n(unsigned int m, unsigned int n,
+                       uint32_t *ret_m, uint32_t *ret_n)
+{
+       *ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
+       *ret_m = div_u64((uint64_t) m * *ret_n, n);
+       intel_reduce_m_n_ratio(ret_m, ret_n);
+}
+
 void
 intel_link_compute_m_n(int bits_per_pixel, int nlanes,
                       int pixel_clock, int link_clock,
                       struct intel_link_m_n *m_n)
 {
        m_n->tu = 64;
-       m_n->gmch_m = bits_per_pixel * pixel_clock;
-       m_n->gmch_n = link_clock * nlanes * 8;
-       intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
-       m_n->link_m = pixel_clock;
-       m_n->link_n = link_clock;
-       intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
+
+       compute_m_n(bits_per_pixel * pixel_clock,
+                   link_clock * nlanes * 8,
+                   &m_n->gmch_m, &m_n->gmch_n);
+
+       compute_m_n(pixel_clock, link_clock,
+                   &m_n->link_m, &m_n->link_n);
 }
 
 static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
 {
        if (i915_panel_use_ssc >= 0)
                return i915_panel_use_ssc != 0;
-       return dev_priv->lvds_use_ssc
+       return dev_priv->vbt.lvds_use_ssc
                && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
 }
 
@@ -4277,7 +4283,7 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
                refclk = vlv_get_refclk(crtc);
        } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
            intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
-               refclk = dev_priv->lvds_ssc_freq * 1000;
+               refclk = dev_priv->vbt.lvds_ssc_freq * 1000;
                DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
                              refclk / 1000);
        } else if (!IS_GEN2(dev)) {
@@ -4289,30 +4295,6 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
        return refclk;
 }
 
-static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc *crtc)
-{
-       unsigned dotclock = crtc->config.adjusted_mode.clock;
-       struct dpll *clock = &crtc->config.dpll;
-
-       /* SDVO TV has fixed PLL values depend on its clock range,
-          this mirrors vbios setting. */
-       if (dotclock >= 100000 && dotclock < 140500) {
-               clock->p1 = 2;
-               clock->p2 = 10;
-               clock->n = 3;
-               clock->m1 = 16;
-               clock->m2 = 8;
-       } else if (dotclock >= 140500 && dotclock <= 200000) {
-               clock->p1 = 1;
-               clock->p2 = 10;
-               clock->n = 6;
-               clock->m1 = 12;
-               clock->m2 = 8;
-       }
-
-       crtc->config.clock_set = true;
-}
-
 static uint32_t pnv_dpll_compute_fp(struct dpll *dpll)
 {
        return (1 << dpll->n) << 16 | dpll->m1 << 8 | dpll->m2;
@@ -4610,12 +4592,8 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
        if (INTEL_INFO(dev)->gen >= 4)
                dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
 
-       if (is_sdvo && intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_TVOUT))
+       if (crtc->config.sdvo_tv_clock)
                dpll |= PLL_REF_INPUT_TVCLKINBC;
-       else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_TVOUT))
-               /* XXX: just matching BIOS for now */
-               /*      dpll |= PLL_REF_INPUT_TVCLKINBC; */
-               dpll |= 3;
        else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
                 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
@@ -4906,8 +4884,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
        int refclk, num_connectors = 0;
        intel_clock_t clock, reduced_clock;
        u32 dspcntr;
-       bool ok, has_reduced_clock = false, is_sdvo = false;
-       bool is_lvds = false, is_tv = false;
+       bool ok, has_reduced_clock = false;
+       bool is_lvds = false;
        struct intel_encoder *encoder;
        const intel_limit_t *limit;
        int ret;
@@ -4917,15 +4895,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
                case INTEL_OUTPUT_LVDS:
                        is_lvds = true;
                        break;
-               case INTEL_OUTPUT_SDVO:
-               case INTEL_OUTPUT_HDMI:
-                       is_sdvo = true;
-                       if (encoder->needs_tv_clock)
-                               is_tv = true;
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       is_tv = true;
-                       break;
                }
 
                num_connectors++;
@@ -4971,9 +4940,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
                intel_crtc->config.dpll.p2 = clock.p2;
        }
 
-       if (is_sdvo && is_tv)
-               i9xx_adjust_sdvo_tv_clock(intel_crtc);
-
        if (IS_GEN2(dev))
                i8xx_update_pll(intel_crtc, adjusted_mode,
                                has_reduced_clock ? &reduced_clock : NULL,
@@ -5020,6 +4986,36 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
        return ret;
 }
 
+static void i9xx_get_pfit_config(struct intel_crtc *crtc,
+                                struct intel_crtc_config *pipe_config)
+{
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       uint32_t tmp;
+
+       tmp = I915_READ(PFIT_CONTROL);
+
+       if (INTEL_INFO(dev)->gen < 4) {
+               if (crtc->pipe != PIPE_B)
+                       return;
+
+               /* gen2/3 store dither state in pfit control, needs to match */
+               pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE;
+       } else {
+               if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
+                       return;
+       }
+
+       if (!(tmp & PFIT_ENABLE))
+               return;
+
+       pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL);
+       pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
+       if (INTEL_INFO(dev)->gen < 5)
+               pipe_config->gmch_pfit.lvds_border_bits =
+                       I915_READ(LVDS) & LVDS_BORDER_ENABLE;
+}
+
 static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
                                 struct intel_crtc_config *pipe_config)
 {
@@ -5033,6 +5029,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 
        intel_get_pipe_timings(crtc, pipe_config);
 
+       i9xx_get_pfit_config(crtc, pipe_config);
+
        return true;
 }
 
@@ -5044,7 +5042,6 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
        u32 val, final;
        bool has_lvds = false;
        bool has_cpu_edp = false;
-       bool has_pch_edp = false;
        bool has_panel = false;
        bool has_ck505 = false;
        bool can_ssc = false;
@@ -5059,25 +5056,22 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
                        break;
                case INTEL_OUTPUT_EDP:
                        has_panel = true;
-                       if (intel_encoder_is_pch_edp(&encoder->base))
-                               has_pch_edp = true;
-                       else
+                       if (enc_to_dig_port(&encoder->base)->port == PORT_A)
                                has_cpu_edp = true;
                        break;
                }
        }
 
        if (HAS_PCH_IBX(dev)) {
-               has_ck505 = dev_priv->display_clock_mode;
+               has_ck505 = dev_priv->vbt.display_clock_mode;
                can_ssc = has_ck505;
        } else {
                has_ck505 = false;
                can_ssc = true;
        }
 
-       DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n",
-                     has_panel, has_lvds, has_pch_edp, has_cpu_edp,
-                     has_ck505);
+       DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
+                     has_panel, has_lvds, has_ck505);
 
        /* Ironlake: try to setup display ref clock before DPLL
         * enabling. This is only under driver's control after
@@ -5367,7 +5361,6 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *encoder;
-       struct intel_encoder *edp_encoder = NULL;
        int num_connectors = 0;
        bool is_lvds = false;
 
@@ -5376,17 +5369,14 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
                case INTEL_OUTPUT_LVDS:
                        is_lvds = true;
                        break;
-               case INTEL_OUTPUT_EDP:
-                       edp_encoder = encoder;
-                       break;
                }
                num_connectors++;
        }
 
        if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
                DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
-                             dev_priv->lvds_ssc_freq);
-               return dev_priv->lvds_ssc_freq * 1000;
+                             dev_priv->vbt.lvds_ssc_freq);
+               return dev_priv->vbt.lvds_ssc_freq * 1000;
        }
 
        return 120000;
@@ -5537,22 +5527,13 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
        struct intel_encoder *intel_encoder;
        int refclk;
        const intel_limit_t *limit;
-       bool ret, is_sdvo = false, is_tv = false, is_lvds = false;
+       bool ret, is_lvds = false;
 
        for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
                switch (intel_encoder->type) {
                case INTEL_OUTPUT_LVDS:
                        is_lvds = true;
                        break;
-               case INTEL_OUTPUT_SDVO:
-               case INTEL_OUTPUT_HDMI:
-                       is_sdvo = true;
-                       if (intel_encoder->needs_tv_clock)
-                               is_tv = true;
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       is_tv = true;
-                       break;
                }
        }
 
@@ -5583,9 +5564,6 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
                                                     reduced_clock);
        }
 
-       if (is_sdvo && is_tv)
-               i9xx_adjust_sdvo_tv_clock(to_intel_crtc(crtc));
-
        return true;
 }
 
@@ -5657,7 +5635,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
        struct intel_encoder *intel_encoder;
        uint32_t dpll;
        int factor, num_connectors = 0;
-       bool is_lvds = false, is_sdvo = false, is_tv = false;
+       bool is_lvds = false, is_sdvo = false;
 
        for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
                switch (intel_encoder->type) {
@@ -5667,11 +5645,6 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
                case INTEL_OUTPUT_SDVO:
                case INTEL_OUTPUT_HDMI:
                        is_sdvo = true;
-                       if (intel_encoder->needs_tv_clock)
-                               is_tv = true;
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       is_tv = true;
                        break;
                }
 
@@ -5682,10 +5655,10 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
        factor = 21;
        if (is_lvds) {
                if ((intel_panel_use_ssc(dev_priv) &&
-                    dev_priv->lvds_ssc_freq == 100) ||
+                    dev_priv->vbt.lvds_ssc_freq == 100) ||
                    (HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev)))
                        factor = 25;
-       } else if (is_sdvo && is_tv)
+       } else if (intel_crtc->config.sdvo_tv_clock)
                factor = 20;
 
        if (ironlake_needs_fb_cb_tune(&intel_crtc->config.dpll, factor))
@@ -5731,13 +5704,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
                break;
        }
 
-       if (is_sdvo && is_tv)
-               dpll |= PLL_REF_INPUT_TVCLKINBC;
-       else if (is_tv)
-               /* XXX: just matching BIOS for now */
-               /*      dpll |= PLL_REF_INPUT_TVCLKINBC; */
-               dpll |= 3;
-       else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
+       if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
        else
                dpll |= PLL_REF_INPUT_DREFCLK;
@@ -5874,8 +5841,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 
        intel_update_watermarks(dev);
 
-       intel_update_linetime_watermarks(dev, pipe, adjusted_mode);
-
        return ret;
 }
 
@@ -5895,6 +5860,21 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
                                   & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
 }
 
+static void ironlake_get_pfit_config(struct intel_crtc *crtc,
+                                    struct intel_crtc_config *pipe_config)
+{
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       uint32_t tmp;
+
+       tmp = I915_READ(PF_CTL(crtc->pipe));
+
+       if (tmp & PF_ENABLE) {
+               pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe));
+               pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe));
+       }
+}
+
 static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
                                     struct intel_crtc_config *pipe_config)
 {
@@ -5918,6 +5898,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
 
        intel_get_pipe_timings(crtc, pipe_config);
 
+       ironlake_get_pfit_config(crtc, pipe_config);
+
        return true;
 }
 
@@ -5968,7 +5950,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
        for_each_encoder_on_crtc(dev, crtc, encoder) {
                switch (encoder->type) {
                case INTEL_OUTPUT_EDP:
-                       if (!intel_encoder_is_pch_edp(&encoder->base))
+                       if (enc_to_dig_port(&encoder->base)->port == PORT_A)
                                is_cpu_edp = true;
                        break;
                }
@@ -6037,10 +6019,11 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+       enum intel_display_power_domain pfit_domain;
        uint32_t tmp;
 
-       if (!intel_using_power_well(dev_priv->dev) &&
-           cpu_transcoder != TRANSCODER_EDP)
+       if (!intel_display_power_enabled(dev,
+                       POWER_DOMAIN_TRANSCODER(cpu_transcoder)))
                return false;
 
        tmp = I915_READ(PIPECONF(cpu_transcoder));
@@ -6066,6 +6049,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 
        intel_get_pipe_timings(crtc, pipe_config);
 
+       pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
+       if (intel_display_power_enabled(dev, pfit_domain))
+               ironlake_get_pfit_config(crtc, pipe_config);
+
        return true;
 }
 
@@ -8031,7 +8018,8 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
                if (mask & (1 <<(intel_crtc)->pipe))
 
 static bool
-intel_pipe_config_compare(struct intel_crtc_config *current_config,
+intel_pipe_config_compare(struct drm_device *dev,
+                         struct intel_crtc_config *current_config,
                          struct intel_crtc_config *pipe_config)
 {
 #define PIPE_CONF_CHECK_I(name)        \
@@ -8077,9 +8065,26 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config,
        PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
                              DRM_MODE_FLAG_INTERLACE);
 
+       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+                             DRM_MODE_FLAG_PHSYNC);
+       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+                             DRM_MODE_FLAG_NHSYNC);
+       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+                             DRM_MODE_FLAG_PVSYNC);
+       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+                             DRM_MODE_FLAG_NVSYNC);
+
        PIPE_CONF_CHECK_I(requested_mode.hdisplay);
        PIPE_CONF_CHECK_I(requested_mode.vdisplay);
 
+       PIPE_CONF_CHECK_I(gmch_pfit.control);
+       /* pfit ratios are autocomputed by the hw on gen4+ */
+       if (INTEL_INFO(dev)->gen < 4)
+               PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
+       PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
+       PIPE_CONF_CHECK_I(pch_pfit.pos);
+       PIPE_CONF_CHECK_I(pch_pfit.size);
+
 #undef PIPE_CONF_CHECK_I
 #undef PIPE_CONF_CHECK_FLAGS
 
@@ -8161,6 +8166,8 @@ intel_modeset_check_state(struct drm_device *dev)
                bool enabled = false;
                bool active = false;
 
+               memset(&pipe_config, 0, sizeof(pipe_config));
+
                DRM_DEBUG_KMS("[CRTC:%d]\n",
                              crtc->base.base.id);
 
@@ -8174,6 +8181,8 @@ intel_modeset_check_state(struct drm_device *dev)
                        enabled = true;
                        if (encoder->connectors_active)
                                active = true;
+                       if (encoder->get_config)
+                               encoder->get_config(encoder, &pipe_config);
                }
                WARN(active != crtc->active,
                     "crtc's computed active state doesn't match tracked active state "
@@ -8182,7 +8191,6 @@ intel_modeset_check_state(struct drm_device *dev)
                     "crtc's computed enabled state doesn't match tracked enabled state "
                     "(expected %i, found %i)\n", enabled, crtc->base.enabled);
 
-               memset(&pipe_config, 0, sizeof(pipe_config));
                pipe_config.cpu_transcoder = crtc->config.cpu_transcoder;
                active = dev_priv->display.get_pipe_config(crtc,
                                                           &pipe_config);
@@ -8191,7 +8199,7 @@ intel_modeset_check_state(struct drm_device *dev)
                     "(expected %i, found %i)\n", crtc->active, active);
 
                WARN(active &&
-                    !intel_pipe_config_compare(&crtc->config, &pipe_config),
+                    !intel_pipe_config_compare(dev, &crtc->config, &pipe_config),
                     "pipe state doesn't match!\n");
        }
 }
@@ -8824,10 +8832,8 @@ static void intel_setup_outputs(struct drm_device *dev)
                                intel_hdmi_init(dev, GEN4_HDMIB, PORT_B);
                        }
 
-                       if (!found && SUPPORTS_INTEGRATED_DP(dev)) {
-                               DRM_DEBUG_KMS("probing DP_B\n");
+                       if (!found && SUPPORTS_INTEGRATED_DP(dev))
                                intel_dp_init(dev, DP_B, PORT_B);
-                       }
                }
 
                /* Before G4X SDVOC doesn't have its own detect register */
@@ -8843,17 +8849,13 @@ static void intel_setup_outputs(struct drm_device *dev)
                                DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
                                intel_hdmi_init(dev, GEN4_HDMIC, PORT_C);
                        }
-                       if (SUPPORTS_INTEGRATED_DP(dev)) {
-                               DRM_DEBUG_KMS("probing DP_C\n");
+                       if (SUPPORTS_INTEGRATED_DP(dev))
                                intel_dp_init(dev, DP_C, PORT_C);
-                       }
                }
 
                if (SUPPORTS_INTEGRATED_DP(dev) &&
-                   (I915_READ(DP_D) & DP_DETECTED)) {
-                       DRM_DEBUG_KMS("probing DP_D\n");
+                   (I915_READ(DP_D) & DP_DETECTED))
                        intel_dp_init(dev, DP_D, PORT_D);
-               }
        } else if (IS_GEN2(dev))
                intel_dvo_init(dev);
 
@@ -9270,6 +9272,11 @@ void intel_modeset_init_hw(struct drm_device *dev)
        mutex_unlock(&dev->struct_mutex);
 }
 
+void intel_modeset_suspend_hw(struct drm_device *dev)
+{
+       intel_suspend_hw(dev);
+}
+
 void intel_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -9592,8 +9599,10 @@ setup_pipes:
                pipe = 0;
 
                if (encoder->get_hw_state(encoder, &pipe)) {
-                       encoder->base.crtc =
-                               dev_priv->pipe_to_crtc_mapping[pipe];
+                       crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+                       encoder->base.crtc = &crtc->base;
+                       if (encoder->get_config)
+                               encoder->get_config(encoder, &crtc->config);
                } else {
                        encoder->base.crtc = NULL;
                }
@@ -9755,6 +9764,9 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
 #include <linux/seq_file.h>
 
 struct intel_display_error_state {
+
+       u32 power_well_driver;
+
        struct intel_cursor_error_state {
                u32 control;
                u32 position;
@@ -9763,6 +9775,7 @@ struct intel_display_error_state {
        } cursor[I915_MAX_PIPES];
 
        struct intel_pipe_error_state {
+               enum transcoder cpu_transcoder;
                u32 conf;
                u32 source;
 
@@ -9797,8 +9810,12 @@ intel_display_capture_error_state(struct drm_device *dev)
        if (error == NULL)
                return NULL;
 
+       if (HAS_POWER_WELL(dev))
+               error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
+
        for_each_pipe(i) {
                cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i);
+               error->pipe[i].cpu_transcoder = cpu_transcoder;
 
                if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) {
                        error->cursor[i].control = I915_READ(CURCNTR(i));
@@ -9833,6 +9850,13 @@ intel_display_capture_error_state(struct drm_device *dev)
                error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder));
        }
 
+       /* In the code above we read the registers without checking if the power
+        * well was on, so here we have to clear the FPGA_DBG_RM_NOCLAIM bit to
+        * prevent the next I915_WRITE from detecting it and printing an error
+        * message. */
+       if (HAS_POWER_WELL(dev))
+               I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
+
        return error;
 }
 
@@ -9844,8 +9868,13 @@ intel_display_print_error_state(struct seq_file *m,
        int i;
 
        seq_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes);
+       if (HAS_POWER_WELL(dev))
+               seq_printf(m, "PWR_WELL_CTL2: %08x\n",
+                          error->power_well_driver);
        for_each_pipe(i) {
                seq_printf(m, "Pipe [%d]:\n", i);
+               seq_printf(m, "  CPU transcoder: %c\n",
+                          transcoder_name(error->pipe[i].cpu_transcoder));
                seq_printf(m, "  CONF: %08x\n", error->pipe[i].conf);
                seq_printf(m, "  SRC: %08x\n", error->pipe[i].source);
                seq_printf(m, "  HTOTAL: %08x\n", error->pipe[i].htotal);