]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_display.c
Merge tag 'drm-intel-next-2017-03-06' of git://anongit.freedesktop.org/git/drm-intel...
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_display.c
index a2fece5e9fb38c80051ba6cea8be8af790c9e94b..7369ee31ad914ac8726413bc3d1cec755ae08c2b 100644 (file)
@@ -37,6 +37,7 @@
 #include "intel_frontbuffer.h"
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
+#include "i915_gem_clflush.h"
 #include "intel_dsi.h"
 #include "i915_trace.h"
 #include <drm/drm_atomic.h>
@@ -96,10 +97,9 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
 static void ironlake_pch_clock_get(struct intel_crtc *crtc,
                                   struct intel_crtc_state *pipe_config);
 
-static int intel_framebuffer_init(struct drm_device *dev,
-                                 struct intel_framebuffer *ifb,
-                                 struct drm_mode_fb_cmd2 *mode_cmd,
-                                 struct drm_i915_gem_object *obj);
+static int intel_framebuffer_init(struct intel_framebuffer *ifb,
+                                 struct drm_i915_gem_object *obj,
+                                 struct drm_mode_fb_cmd2 *mode_cmd);
 static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc);
 static void intel_set_pipe_timings(struct intel_crtc *intel_crtc);
 static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc);
@@ -122,9 +122,6 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
 static void ironlake_pfit_enable(struct intel_crtc *crtc);
 static void intel_modeset_setup_hw_state(struct drm_device *dev);
 static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc);
-static int ilk_max_pixel_rate(struct drm_atomic_state *state);
-static int glk_calc_cdclk(int max_pixclk);
-static int bxt_calc_cdclk(int max_pixclk);
 
 struct intel_limit {
        struct {
@@ -138,7 +135,7 @@ struct intel_limit {
 };
 
 /* returns HPLL frequency in kHz */
-static int valleyview_get_vco(struct drm_i915_private *dev_priv)
+int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
 {
        int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
 
@@ -170,73 +167,16 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
        return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
 }
 
-static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
-                                 const char *name, u32 reg)
+int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
+                          const char *name, u32 reg)
 {
        if (dev_priv->hpll_freq == 0)
-               dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
+               dev_priv->hpll_freq = vlv_get_hpll_vco(dev_priv);
 
        return vlv_get_cck_clock(dev_priv, name, reg,
                                 dev_priv->hpll_freq);
 }
 
-static int
-intel_pch_rawclk(struct drm_i915_private *dev_priv)
-{
-       return (I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
-}
-
-static int
-intel_vlv_hrawclk(struct drm_i915_private *dev_priv)
-{
-       /* RAWCLK_FREQ_VLV register updated from power well code */
-       return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
-                                     CCK_DISPLAY_REF_CLOCK_CONTROL);
-}
-
-static int
-intel_g4x_hrawclk(struct drm_i915_private *dev_priv)
-{
-       uint32_t clkcfg;
-
-       /* hrawclock is 1/4 the FSB frequency */
-       clkcfg = I915_READ(CLKCFG);
-       switch (clkcfg & CLKCFG_FSB_MASK) {
-       case CLKCFG_FSB_400:
-               return 100000;
-       case CLKCFG_FSB_533:
-               return 133333;
-       case CLKCFG_FSB_667:
-               return 166667;
-       case CLKCFG_FSB_800:
-               return 200000;
-       case CLKCFG_FSB_1067:
-               return 266667;
-       case CLKCFG_FSB_1333:
-               return 333333;
-       /* these two are just a guess; one of them might be right */
-       case CLKCFG_FSB_1600:
-       case CLKCFG_FSB_1600_ALT:
-               return 400000;
-       default:
-               return 133333;
-       }
-}
-
-void intel_update_rawclk(struct drm_i915_private *dev_priv)
-{
-       if (HAS_PCH_SPLIT(dev_priv))
-               dev_priv->rawclk_freq = intel_pch_rawclk(dev_priv);
-       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-               dev_priv->rawclk_freq = intel_vlv_hrawclk(dev_priv);
-       else if (IS_G4X(dev_priv) || IS_PINEVIEW(dev_priv))
-               dev_priv->rawclk_freq = intel_g4x_hrawclk(dev_priv);
-       else
-               return; /* no rawclk on other platforms, or no need to know it */
-
-       DRM_DEBUG_DRIVER("rawclk rate: %d kHz\n", dev_priv->rawclk_freq);
-}
-
 static void intel_update_czclk(struct drm_i915_private *dev_priv)
 {
        if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)))
@@ -2112,11 +2052,13 @@ static void intel_tile_dims(const struct drm_i915_private *dev_priv,
 }
 
 unsigned int
-intel_fb_align_height(struct drm_device *dev, unsigned int height,
-                     uint32_t pixel_format, uint64_t fb_modifier)
+intel_fb_align_height(struct drm_i915_private *dev_priv,
+                     unsigned int height,
+                     uint32_t pixel_format,
+                     uint64_t fb_modifier)
 {
        unsigned int cpp = drm_format_plane_cpp(pixel_format, 0);
-       unsigned int tile_height = intel_tile_height(to_i915(dev), fb_modifier, cpp);
+       unsigned int tile_height = intel_tile_height(dev_priv, fb_modifier, cpp);
 
        return ALIGN(height, tile_height);
 }
@@ -2682,15 +2624,13 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
                return false;
 
        mutex_lock(&dev->struct_mutex);
-
        obj = i915_gem_object_create_stolen_for_preallocated(dev_priv,
                                                             base_aligned,
                                                             base_aligned,
                                                             size_aligned);
-       if (!obj) {
-               mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->struct_mutex);
+       if (!obj)
                return false;
-       }
 
        if (plane_config->tiling == I915_TILING_X)
                obj->tiling_and_stride = fb->pitches[0] | I915_TILING_X;
@@ -2702,20 +2642,17 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
        mode_cmd.modifier[0] = fb->modifier;
        mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
 
-       if (intel_framebuffer_init(dev, to_intel_framebuffer(fb),
-                                  &mode_cmd, obj)) {
+       if (intel_framebuffer_init(to_intel_framebuffer(fb), obj, &mode_cmd)) {
                DRM_DEBUG_KMS("intel fb init failed\n");
                goto out_unref_obj;
        }
 
-       mutex_unlock(&dev->struct_mutex);
 
        DRM_DEBUG_KMS("initial plane fb obj %p\n", obj);
        return true;
 
 out_unref_obj:
        i915_gem_object_put(obj);
-       mutex_unlock(&dev->struct_mutex);
        return false;
 }
 
@@ -2733,6 +2670,29 @@ update_state_fb(struct drm_plane *plane)
                drm_framebuffer_reference(plane->state->fb);
 }
 
+static void
+intel_set_plane_visible(struct intel_crtc_state *crtc_state,
+                       struct intel_plane_state *plane_state,
+                       bool visible)
+{
+       struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+
+       plane_state->base.visible = visible;
+
+       /* FIXME pre-g4x don't work like this */
+       if (visible) {
+               crtc_state->base.plane_mask |= BIT(drm_plane_index(&plane->base));
+               crtc_state->active_planes |= BIT(plane->id);
+       } else {
+               crtc_state->base.plane_mask &= ~BIT(drm_plane_index(&plane->base));
+               crtc_state->active_planes &= ~BIT(plane->id);
+       }
+
+       DRM_DEBUG_KMS("%s active planes 0x%x\n",
+                     crtc_state->base.crtc->name,
+                     crtc_state->active_planes);
+}
+
 static void
 intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
                             struct intel_initial_plane_config *plane_config)
@@ -2790,9 +2750,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
         * simplest solution is to just disable the primary plane now and
         * pretend the BIOS never had it enabled.
         */
-       plane_state->visible = false;
-       crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
+       intel_set_plane_visible(to_intel_crtc_state(crtc_state),
+                               to_intel_plane_state(plane_state),
+                               false);
        intel_pre_disable_primary_noatomic(&intel_crtc->base);
+       trace_intel_disable_plane(primary, intel_crtc);
        intel_plane->disable_plane(primary, &intel_crtc->base);
 
        return;
@@ -2831,7 +2793,11 @@ valid_fb:
        drm_framebuffer_reference(fb);
        primary->fb = primary->state->fb = fb;
        primary->crtc = primary->state->crtc = &intel_crtc->base;
-       intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
+
+       intel_set_plane_visible(to_intel_crtc_state(crtc_state),
+                               to_intel_plane_state(plane_state),
+                               true);
+
        atomic_or(to_intel_plane(primary)->frontbuffer_bit,
                  &obj->frontbuffer_bits);
 }
@@ -3386,13 +3352,22 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
        int dst_w = drm_rect_width(&plane_state->base.dst);
        int dst_h = drm_rect_height(&plane_state->base.dst);
 
-       plane_ctl = PLANE_CTL_ENABLE |
-                   PLANE_CTL_PIPE_GAMMA_ENABLE |
-                   PLANE_CTL_PIPE_CSC_ENABLE;
+       plane_ctl = PLANE_CTL_ENABLE;
+
+       if (IS_GEMINILAKE(dev_priv)) {
+               I915_WRITE(PLANE_COLOR_CTL(pipe, plane_id),
+                          PLANE_COLOR_PIPE_GAMMA_ENABLE |
+                          PLANE_COLOR_PIPE_CSC_ENABLE |
+                          PLANE_COLOR_PLANE_GAMMA_DISABLE);
+       } else {
+               plane_ctl |=
+                       PLANE_CTL_PIPE_GAMMA_ENABLE |
+                       PLANE_CTL_PIPE_CSC_ENABLE |
+                       PLANE_CTL_PLANE_GAMMA_DISABLE;
+       }
 
        plane_ctl |= skl_plane_ctl_format(fb->format->format);
        plane_ctl |= skl_plane_ctl_tiling(fb->modifier);
-       plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
        plane_ctl |= skl_plane_ctl_rotation(rotation);
 
        /* Sizes are 0 based */
@@ -3473,10 +3448,14 @@ static void intel_update_primary_planes(struct drm_device *dev)
                struct intel_plane_state *plane_state =
                        to_intel_plane_state(plane->base.state);
 
-               if (plane_state->base.visible)
+               if (plane_state->base.visible) {
+                       trace_intel_update_plane(&plane->base,
+                                                to_intel_crtc(crtc));
+
                        plane->update_plane(&plane->base,
                                            to_intel_crtc_state(crtc->state),
                                            plane_state);
+               }
        }
 }
 
@@ -3505,7 +3484,8 @@ __intel_display_resume(struct drm_device *dev,
        }
 
        /* ignore any reset values/BIOS leftovers in the WM registers */
-       to_intel_atomic_state(state)->skip_intermediate_wm = true;
+       if (!HAS_GMCH_DISPLAY(to_i915(dev)))
+               to_intel_atomic_state(state)->skip_intermediate_wm = true;
 
        ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
 
@@ -3701,12 +3681,11 @@ static void intel_update_pipe_config(struct intel_crtc *crtc,
        }
 }
 
-static void intel_fdi_normal_train(struct drm_crtc *crtc)
+static void intel_fdi_normal_train(struct intel_crtc *crtc)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp;
 
@@ -3744,12 +3723,12 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
 }
 
 /* The FDI link training functions for ILK/Ibexpeak. */
-static void ironlake_fdi_link_train(struct drm_crtc *crtc)
+static void ironlake_fdi_link_train(struct intel_crtc *crtc,
+                                   const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp, tries;
 
@@ -3770,7 +3749,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
        reg = FDI_TX_CTL(pipe);
        temp = I915_READ(reg);
        temp &= ~FDI_DP_PORT_WIDTH_MASK;
-       temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+       temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
        temp &= ~FDI_LINK_TRAIN_NONE;
        temp |= FDI_LINK_TRAIN_PATTERN_1;
        I915_WRITE(reg, temp | FDI_TX_ENABLE);
@@ -3845,12 +3824,12 @@ static const int snb_b_fdi_train_param[] = {
 };
 
 /* The FDI link training functions for SNB/Cougarpoint. */
-static void gen6_fdi_link_train(struct drm_crtc *crtc)
+static void gen6_fdi_link_train(struct intel_crtc *crtc,
+                               const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp, i, retry;
 
@@ -3869,7 +3848,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
        reg = FDI_TX_CTL(pipe);
        temp = I915_READ(reg);
        temp &= ~FDI_DP_PORT_WIDTH_MASK;
-       temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+       temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
        temp &= ~FDI_LINK_TRAIN_NONE;
        temp |= FDI_LINK_TRAIN_PATTERN_1;
        temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
@@ -3978,12 +3957,12 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
 }
 
 /* Manual link training for Ivy Bridge A0 parts */
-static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
+static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
+                                     const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp, i, j;
 
@@ -4021,7 +4000,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
                reg = FDI_TX_CTL(pipe);
                temp = I915_READ(reg);
                temp &= ~FDI_DP_PORT_WIDTH_MASK;
-               temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+               temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
                temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
                temp |= snb_b_fdi_train_param[j/2];
@@ -4308,10 +4287,10 @@ void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
 }
 
 /* Program iCLKIP clock to the desired frequency */
-static void lpt_program_iclkip(struct drm_crtc *crtc)
+static void lpt_program_iclkip(struct intel_crtc *crtc)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc->dev);
-       int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       int clock = crtc->config->base.adjusted_mode.crtc_clock;
        u32 divsel, phaseinc, auxdiv, phasedir = 0;
        u32 temp;
 
@@ -4492,12 +4471,12 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
 
 /* Return which DP Port should be selected for Transcoder DP control */
 static enum port
-intel_trans_dp_port_sel(struct drm_crtc *crtc)
+intel_trans_dp_port_sel(struct intel_crtc *crtc)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct intel_encoder *encoder;
 
-       for_each_encoder_on_crtc(dev, crtc, encoder) {
+       for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
                if (encoder->type == INTEL_OUTPUT_DP ||
                    encoder->type == INTEL_OUTPUT_EDP)
                        return enc_to_dig_port(&encoder->base)->port;
@@ -4514,18 +4493,18 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
  *   - DP transcoding bits
  *   - transcoder
  */
-static void ironlake_pch_enable(struct drm_crtc *crtc)
+static void ironlake_pch_enable(const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        u32 temp;
 
        assert_pch_transcoder_disabled(dev_priv, pipe);
 
        if (IS_IVYBRIDGE(dev_priv))
-               ivybridge_update_fdi_bc_bifurcation(intel_crtc);
+               ivybridge_update_fdi_bc_bifurcation(crtc);
 
        /* Write the TU size bits before fdi link training, so that error
         * detection works. */
@@ -4533,7 +4512,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
                   I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
 
        /* For PCH output, training FDI link */
-       dev_priv->display.fdi_link_train(crtc);
+       dev_priv->display.fdi_link_train(crtc, crtc_state);
 
        /* We need to program the right clock selection before writing the pixel
         * mutliplier into the DPLL. */
@@ -4543,7 +4522,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
                temp = I915_READ(PCH_DPLL_SEL);
                temp |= TRANS_DPLL_ENABLE(pipe);
                sel = TRANS_DPLLB_SEL(pipe);
-               if (intel_crtc->config->shared_dpll ==
+               if (crtc_state->shared_dpll ==
                    intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B))
                        temp |= sel;
                else
@@ -4558,19 +4537,19 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
         * Note that enable_shared_dpll tries to do the right thing, but
         * get_shared_dpll unconditionally resets the pll - we need that to have
         * the right LVDS enable sequence. */
-       intel_enable_shared_dpll(intel_crtc);
+       intel_enable_shared_dpll(crtc);
 
        /* set transcoder timing, panel must allow it */
        assert_panel_unlocked(dev_priv, pipe);
-       ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
+       ironlake_pch_transcoder_set_timings(crtc, pipe);
 
        intel_fdi_normal_train(crtc);
 
        /* For PCH DP, enable TRANS_DP_CTL */
        if (HAS_PCH_CPT(dev_priv) &&
-           intel_crtc_has_dp_encoder(intel_crtc->config)) {
+           intel_crtc_has_dp_encoder(crtc_state)) {
                const struct drm_display_mode *adjusted_mode =
-                       &intel_crtc->config->base.adjusted_mode;
+                       &crtc_state->base.adjusted_mode;
                u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
                i915_reg_t reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
@@ -4605,19 +4584,18 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
        ironlake_enable_pch_transcoder(dev_priv, pipe);
 }
 
-static void lpt_pch_enable(struct drm_crtc *crtc)
+static void lpt_pch_enable(const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
        assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
 
        lpt_program_iclkip(crtc);
 
        /* Set transcoder timing. */
-       ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
+       ironlake_pch_transcoder_set_timings(crtc, PIPE_A);
 
        lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
 }
@@ -5026,8 +5004,6 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
 
        intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits);
 
-       crtc->wm.cxsr_allowed = true;
-
        if (pipe_config->update_wm_post && pipe_config->base.active)
                intel_update_watermarks(crtc);
 
@@ -5074,22 +5050,18 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
                        intel_pre_disable_primary(&crtc->base);
        }
 
-       if (pipe_config->disable_cxsr && HAS_GMCH_DISPLAY(dev_priv)) {
-               crtc->wm.cxsr_allowed = false;
-
-               /*
-                * Vblank time updates from the shadow to live plane control register
-                * are blocked if the memory self-refresh mode is active at that
-                * moment. So to make sure the plane gets truly disabled, disable
-                * first the self-refresh mode. The self-refresh enable bit in turn
-                * will be checked/applied by the HW only at the next frame start
-                * event which is after the vblank start event, so we need to have a
-                * wait-for-vblank between disabling the plane and the pipe.
-                */
-               if (old_crtc_state->base.active &&
-                   intel_set_memory_cxsr(dev_priv, false))
-                       intel_wait_for_vblank(dev_priv, crtc->pipe);
-       }
+       /*
+        * Vblank time updates from the shadow to live plane control register
+        * are blocked if the memory self-refresh mode is active at that
+        * moment. So to make sure the plane gets truly disabled, disable
+        * first the self-refresh mode. The self-refresh enable bit in turn
+        * will be checked/applied by the HW only at the next frame start
+        * event which is after the vblank start event, so we need to have a
+        * wait-for-vblank between disabling the plane and the pipe.
+        */
+       if (HAS_GMCH_DISPLAY(dev_priv) && old_crtc_state->base.active &&
+           pipe_config->disable_cxsr && intel_set_memory_cxsr(dev_priv, false))
+               intel_wait_for_vblank(dev_priv, crtc->pipe);
 
        /*
         * IVB workaround: must disable low power watermarks for at least
@@ -5344,7 +5316,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
        intel_enable_pipe(intel_crtc);
 
        if (intel_crtc->config->has_pch_encoder)
-               ironlake_pch_enable(crtc);
+               ironlake_pch_enable(pipe_config);
 
        assert_vblank_disabled(crtc);
        drm_crtc_vblank_on(crtc);
@@ -5426,10 +5398,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
        intel_encoders_pre_enable(crtc, pipe_config, old_state);
 
        if (intel_crtc->config->has_pch_encoder)
-               dev_priv->display.fdi_link_train(crtc);
+               dev_priv->display.fdi_link_train(intel_crtc, pipe_config);
 
        if (!transcoder_is_dsi(cpu_transcoder))
-               intel_ddi_enable_pipe_clock(intel_crtc);
+               intel_ddi_enable_pipe_clock(pipe_config);
 
        if (INTEL_GEN(dev_priv) >= 9)
                skylake_pfit_enable(intel_crtc);
@@ -5442,9 +5414,9 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
         */
        intel_color_load_luts(&pipe_config->base);
 
-       intel_ddi_set_pipe_settings(crtc);
+       intel_ddi_set_pipe_settings(pipe_config);
        if (!transcoder_is_dsi(cpu_transcoder))
-               intel_ddi_enable_transcoder_func(crtc);
+               intel_ddi_enable_transcoder_func(pipe_config);
 
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state, pipe_config);
@@ -5454,10 +5426,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
                intel_enable_pipe(intel_crtc);
 
        if (intel_crtc->config->has_pch_encoder)
-               lpt_pch_enable(crtc);
+               lpt_pch_enable(pipe_config);
 
        if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DP_MST))
-               intel_ddi_set_vc_payload_alloc(crtc, true);
+               intel_ddi_set_vc_payload_alloc(pipe_config, true);
 
        assert_vblank_disabled(crtc);
        drm_crtc_vblank_on(crtc);
@@ -5579,7 +5551,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
                intel_disable_pipe(intel_crtc);
 
        if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DP_MST))
-               intel_ddi_set_vc_payload_alloc(crtc, false);
+               intel_ddi_set_vc_payload_alloc(intel_crtc->config, false);
 
        if (!transcoder_is_dsi(cpu_transcoder))
                intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
@@ -5590,7 +5562,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
                ironlake_pfit_disable(intel_crtc, false);
 
        if (!transcoder_is_dsi(cpu_transcoder))
-               intel_ddi_disable_pipe_clock(intel_crtc);
+               intel_ddi_disable_pipe_clock(intel_crtc->config);
 
        intel_encoders_post_disable(crtc, old_crtc_state, old_state);
 
@@ -5623,7 +5595,7 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
        I915_WRITE(BCLRPAT(crtc->pipe), 0);
 }
 
-static enum intel_display_power_domain port_to_power_domain(enum port port)
+enum intel_display_power_domain intel_port_to_power_domain(enum port port)
 {
        switch (port) {
        case PORT_A:
@@ -5642,91 +5614,15 @@ static enum intel_display_power_domain port_to_power_domain(enum port port)
        }
 }
 
-static enum intel_display_power_domain port_to_aux_power_domain(enum port port)
-{
-       switch (port) {
-       case PORT_A:
-               return POWER_DOMAIN_AUX_A;
-       case PORT_B:
-               return POWER_DOMAIN_AUX_B;
-       case PORT_C:
-               return POWER_DOMAIN_AUX_C;
-       case PORT_D:
-               return POWER_DOMAIN_AUX_D;
-       case PORT_E:
-               /* FIXME: Check VBT for actual wiring of PORT E */
-               return POWER_DOMAIN_AUX_D;
-       default:
-               MISSING_CASE(port);
-               return POWER_DOMAIN_AUX_A;
-       }
-}
-
-enum intel_display_power_domain
-intel_display_port_power_domain(struct intel_encoder *intel_encoder)
-{
-       struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
-       struct intel_digital_port *intel_dig_port;
-
-       switch (intel_encoder->type) {
-       case INTEL_OUTPUT_UNKNOWN:
-               /* Only DDI platforms should ever use this output type */
-               WARN_ON_ONCE(!HAS_DDI(dev_priv));
-       case INTEL_OUTPUT_DP:
-       case INTEL_OUTPUT_HDMI:
-       case INTEL_OUTPUT_EDP:
-               intel_dig_port = enc_to_dig_port(&intel_encoder->base);
-               return port_to_power_domain(intel_dig_port->port);
-       case INTEL_OUTPUT_DP_MST:
-               intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
-               return port_to_power_domain(intel_dig_port->port);
-       case INTEL_OUTPUT_ANALOG:
-               return POWER_DOMAIN_PORT_CRT;
-       case INTEL_OUTPUT_DSI:
-               return POWER_DOMAIN_PORT_DSI;
-       default:
-               return POWER_DOMAIN_PORT_OTHER;
-       }
-}
-
-enum intel_display_power_domain
-intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
-{
-       struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
-       struct intel_digital_port *intel_dig_port;
-
-       switch (intel_encoder->type) {
-       case INTEL_OUTPUT_UNKNOWN:
-       case INTEL_OUTPUT_HDMI:
-               /*
-                * Only DDI platforms should ever use these output types.
-                * We can get here after the HDMI detect code has already set
-                * the type of the shared encoder. Since we can't be sure
-                * what's the status of the given connectors, play safe and
-                * run the DP detection too.
-                */
-               WARN_ON_ONCE(!HAS_DDI(dev_priv));
-       case INTEL_OUTPUT_DP:
-       case INTEL_OUTPUT_EDP:
-               intel_dig_port = enc_to_dig_port(&intel_encoder->base);
-               return port_to_aux_power_domain(intel_dig_port->port);
-       case INTEL_OUTPUT_DP_MST:
-               intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
-               return port_to_aux_power_domain(intel_dig_port->port);
-       default:
-               MISSING_CASE(intel_encoder->type);
-               return POWER_DOMAIN_AUX_A;
-       }
-}
-
-static unsigned long get_crtc_power_domains(struct drm_crtc *crtc,
-                                           struct intel_crtc_state *crtc_state)
+static u64 get_crtc_power_domains(struct drm_crtc *crtc,
+                                 struct intel_crtc_state *crtc_state)
 {
        struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_encoder *encoder;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        enum pipe pipe = intel_crtc->pipe;
-       unsigned long mask;
+       u64 mask;
        enum transcoder transcoder = crtc_state->cpu_transcoder;
 
        if (!crtc_state->base.active)
@@ -5736,28 +5632,31 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc,
        mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
        if (crtc_state->pch_pfit.enabled ||
            crtc_state->pch_pfit.force_thru)
-               mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
+               mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
 
        drm_for_each_encoder_mask(encoder, dev, crtc_state->base.encoder_mask) {
                struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
 
-               mask |= BIT(intel_display_port_power_domain(intel_encoder));
+               mask |= BIT_ULL(intel_encoder->power_domain);
        }
 
+       if (HAS_DDI(dev_priv) && crtc_state->has_audio)
+               mask |= BIT(POWER_DOMAIN_AUDIO);
+
        if (crtc_state->shared_dpll)
-               mask |= BIT(POWER_DOMAIN_PLLS);
+               mask |= BIT_ULL(POWER_DOMAIN_PLLS);
 
        return mask;
 }
 
-static unsigned long
+static u64
 modeset_get_crtc_power_domains(struct drm_crtc *crtc,
                               struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        enum intel_display_power_domain domain;
-       unsigned long domains, new_domains, old_domains;
+       u64 domains, new_domains, old_domains;
 
        old_domains = intel_crtc->enabled_power_domains;
        intel_crtc->enabled_power_domains = new_domains =
@@ -5772,7 +5671,7 @@ modeset_get_crtc_power_domains(struct drm_crtc *crtc,
 }
 
 static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
-                                     unsigned long domains)
+                                     u64 domains)
 {
        enum intel_display_power_domain domain;
 
@@ -5780,1032 +5679,122 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
                intel_display_power_put(dev_priv, domain);
 }
 
-static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
+static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
+                                  struct drm_atomic_state *old_state)
 {
-       int max_cdclk_freq = dev_priv->max_cdclk_freq;
+       struct intel_atomic_state *old_intel_state =
+               to_intel_atomic_state(old_state);
+       struct drm_crtc *crtc = pipe_config->base.crtc;
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int pipe = intel_crtc->pipe;
 
-       if (IS_GEMINILAKE(dev_priv))
-               return 2 * max_cdclk_freq;
-       else if (INTEL_INFO(dev_priv)->gen >= 9 ||
-                IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-               return max_cdclk_freq;
-       else if (IS_CHERRYVIEW(dev_priv))
-               return max_cdclk_freq*95/100;
-       else if (INTEL_INFO(dev_priv)->gen < 4)
-               return 2*max_cdclk_freq*90/100;
-       else
-               return max_cdclk_freq*90/100;
-}
+       if (WARN_ON(intel_crtc->active))
+               return;
 
-static int skl_calc_cdclk(int max_pixclk, int vco);
+       if (intel_crtc_has_dp_encoder(intel_crtc->config))
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
-static void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
-{
-       if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
-               u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
-               int max_cdclk, vco;
+       intel_set_pipe_timings(intel_crtc);
+       intel_set_pipe_src_size(intel_crtc);
 
-               vco = dev_priv->skl_preferred_vco_freq;
-               WARN_ON(vco != 8100000 && vco != 8640000);
+       if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
+               struct drm_i915_private *dev_priv = to_i915(dev);
 
-               /*
-                * Use the lower (vco 8640) cdclk values as a
-                * first guess. skl_calc_cdclk() will correct it
-                * if the preferred vco is 8100 instead.
-                */
-               if (limit == SKL_DFSM_CDCLK_LIMIT_675)
-                       max_cdclk = 617143;
-               else if (limit == SKL_DFSM_CDCLK_LIMIT_540)
-                       max_cdclk = 540000;
-               else if (limit == SKL_DFSM_CDCLK_LIMIT_450)
-                       max_cdclk = 432000;
-               else
-                       max_cdclk = 308571;
-
-               dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
-       } else if (IS_GEMINILAKE(dev_priv)) {
-               dev_priv->max_cdclk_freq = 316800;
-       } else if (IS_BROXTON(dev_priv)) {
-               dev_priv->max_cdclk_freq = 624000;
-       } else if (IS_BROADWELL(dev_priv))  {
-               /*
-                * FIXME with extra cooling we can allow
-                * 540 MHz for ULX and 675 Mhz for ULT.
-                * How can we know if extra cooling is
-                * available? PCI ID, VTB, something else?
-                */
-               if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
-                       dev_priv->max_cdclk_freq = 450000;
-               else if (IS_BDW_ULX(dev_priv))
-                       dev_priv->max_cdclk_freq = 450000;
-               else if (IS_BDW_ULT(dev_priv))
-                       dev_priv->max_cdclk_freq = 540000;
-               else
-                       dev_priv->max_cdclk_freq = 675000;
-       } else if (IS_CHERRYVIEW(dev_priv)) {
-               dev_priv->max_cdclk_freq = 320000;
-       } else if (IS_VALLEYVIEW(dev_priv)) {
-               dev_priv->max_cdclk_freq = 400000;
-       } else {
-               /* otherwise assume cdclk is fixed */
-               dev_priv->max_cdclk_freq = dev_priv->cdclk_freq;
+               I915_WRITE(CHV_BLEND(pipe), CHV_BLEND_LEGACY);
+               I915_WRITE(CHV_CANVAS(pipe), 0);
        }
 
-       dev_priv->max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
+       i9xx_set_pipeconf(intel_crtc);
 
-       DRM_DEBUG_DRIVER("Max CD clock rate: %d kHz\n",
-                        dev_priv->max_cdclk_freq);
+       intel_crtc->active = true;
 
-       DRM_DEBUG_DRIVER("Max dotclock rate: %d kHz\n",
-                        dev_priv->max_dotclk_freq);
-}
+       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
-static void intel_update_cdclk(struct drm_i915_private *dev_priv)
-{
-       dev_priv->cdclk_freq = dev_priv->display.get_display_clock_speed(dev_priv);
+       intel_encoders_pre_pll_enable(crtc, pipe_config, old_state);
 
-       if (INTEL_GEN(dev_priv) >= 9)
-               DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz, VCO: %d kHz, ref: %d kHz\n",
-                                dev_priv->cdclk_freq, dev_priv->cdclk_pll.vco,
-                                dev_priv->cdclk_pll.ref);
-       else
-               DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz\n",
-                                dev_priv->cdclk_freq);
+       if (IS_CHERRYVIEW(dev_priv)) {
+               chv_prepare_pll(intel_crtc, intel_crtc->config);
+               chv_enable_pll(intel_crtc, intel_crtc->config);
+       } else {
+               vlv_prepare_pll(intel_crtc, intel_crtc->config);
+               vlv_enable_pll(intel_crtc, intel_crtc->config);
+       }
 
-       /*
-        * 9:0 CMBUS [sic] CDCLK frequency (cdfreq):
-        * Programmng [sic] note: bit[9:2] should be programmed to the number
-        * of cdclk that generates 4MHz reference clock freq which is used to
-        * generate GMBus clock. This will vary with the cdclk freq.
-        */
-       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-               I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->cdclk_freq, 1000));
-}
+       intel_encoders_pre_enable(crtc, pipe_config, old_state);
 
-/* convert from kHz to .1 fixpoint MHz with -1MHz offset */
-static int skl_cdclk_decimal(int cdclk)
-{
-       return DIV_ROUND_CLOSEST(cdclk - 1000, 500);
-}
+       i9xx_pfit_enable(intel_crtc);
 
-static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
-{
-       int ratio;
+       intel_color_load_luts(&pipe_config->base);
 
-       if (cdclk == dev_priv->cdclk_pll.ref)
-               return 0;
+       dev_priv->display.initial_watermarks(old_intel_state,
+                                            pipe_config);
+       intel_enable_pipe(intel_crtc);
 
-       switch (cdclk) {
-       default:
-               MISSING_CASE(cdclk);
-       case 144000:
-       case 288000:
-       case 384000:
-       case 576000:
-               ratio = 60;
-               break;
-       case 624000:
-               ratio = 65;
-               break;
-       }
+       assert_vblank_disabled(crtc);
+       drm_crtc_vblank_on(crtc);
 
-       return dev_priv->cdclk_pll.ref * ratio;
+       intel_encoders_enable(crtc, pipe_config, old_state);
 }
 
-static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
+static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
 {
-       int ratio;
-
-       if (cdclk == dev_priv->cdclk_pll.ref)
-               return 0;
-
-       switch (cdclk) {
-       default:
-               MISSING_CASE(cdclk);
-       case  79200:
-       case 158400:
-       case 316800:
-               ratio = 33;
-               break;
-       }
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
 
-       return dev_priv->cdclk_pll.ref * ratio;
+       I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0);
+       I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1);
 }
 
-static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
+static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
+                            struct drm_atomic_state *old_state)
 {
-       I915_WRITE(BXT_DE_PLL_ENABLE, 0);
+       struct drm_crtc *crtc = pipe_config->base.crtc;
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       enum pipe pipe = intel_crtc->pipe;
 
-       /* Timeout 200us */
-       if (intel_wait_for_register(dev_priv,
-                                   BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 0,
-                                   1))
-               DRM_ERROR("timeout waiting for DE PLL unlock\n");
+       if (WARN_ON(intel_crtc->active))
+               return;
 
-       dev_priv->cdclk_pll.vco = 0;
-}
+       i9xx_set_pll_dividers(intel_crtc);
 
-static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
-{
-       int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk_pll.ref);
-       u32 val;
+       if (intel_crtc_has_dp_encoder(intel_crtc->config))
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
-       val = I915_READ(BXT_DE_PLL_CTL);
-       val &= ~BXT_DE_PLL_RATIO_MASK;
-       val |= BXT_DE_PLL_RATIO(ratio);
-       I915_WRITE(BXT_DE_PLL_CTL, val);
+       intel_set_pipe_timings(intel_crtc);
+       intel_set_pipe_src_size(intel_crtc);
 
-       I915_WRITE(BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
+       i9xx_set_pipeconf(intel_crtc);
 
-       /* Timeout 200us */
-       if (intel_wait_for_register(dev_priv,
-                                   BXT_DE_PLL_ENABLE,
-                                   BXT_DE_PLL_LOCK,
-                                   BXT_DE_PLL_LOCK,
-                                   1))
-               DRM_ERROR("timeout waiting for DE PLL lock\n");
+       intel_crtc->active = true;
 
-       dev_priv->cdclk_pll.vco = vco;
-}
+       if (!IS_GEN2(dev_priv))
+               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
-static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk)
-{
-       u32 val, divider;
-       int vco, ret;
+       intel_encoders_pre_enable(crtc, pipe_config, old_state);
 
-       if (IS_GEMINILAKE(dev_priv))
-               vco = glk_de_pll_vco(dev_priv, cdclk);
-       else
-               vco = bxt_de_pll_vco(dev_priv, cdclk);
+       i9xx_enable_pll(intel_crtc);
 
-       DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
+       i9xx_pfit_enable(intel_crtc);
 
-       /* cdclk = vco / 2 / div{1,1.5,2,4} */
-       switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
-       case 8:
-               divider = BXT_CDCLK_CD2X_DIV_SEL_4;
-               break;
-       case 4:
-               divider = BXT_CDCLK_CD2X_DIV_SEL_2;
-               break;
-       case 3:
-               WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n");
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
-               break;
-       case 2:
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1;
-               break;
-       default:
-               WARN_ON(cdclk != dev_priv->cdclk_pll.ref);
-               WARN_ON(vco != 0);
+       intel_color_load_luts(&pipe_config->base);
 
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1;
-               break;
-       }
+       intel_update_watermarks(intel_crtc);
+       intel_enable_pipe(intel_crtc);
 
-       /* Inform power controller of upcoming frequency change */
-       mutex_lock(&dev_priv->rps.hw_lock);
-       ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-                                     0x80000000);
-       mutex_unlock(&dev_priv->rps.hw_lock);
+       assert_vblank_disabled(crtc);
+       drm_crtc_vblank_on(crtc);
 
-       if (ret) {
-               DRM_ERROR("PCode CDCLK freq change notify failed (err %d, freq %d)\n",
-                         ret, cdclk);
-               return;
-       }
+       intel_encoders_enable(crtc, pipe_config, old_state);
+}
 
-       if (dev_priv->cdclk_pll.vco != 0 &&
-           dev_priv->cdclk_pll.vco != vco)
-               bxt_de_pll_disable(dev_priv);
-
-       if (dev_priv->cdclk_pll.vco != vco)
-               bxt_de_pll_enable(dev_priv, vco);
-
-       val = divider | skl_cdclk_decimal(cdclk);
-       /*
-        * FIXME if only the cd2x divider needs changing, it could be done
-        * without shutting off the pipe (if only one pipe is active).
-        */
-       val |= BXT_CDCLK_CD2X_PIPE_NONE;
-       /*
-        * Disable SSA Precharge when CD clock frequency < 500 MHz,
-        * enable otherwise.
-        */
-       if (cdclk >= 500000)
-               val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
-       I915_WRITE(CDCLK_CTL, val);
-
-       mutex_lock(&dev_priv->rps.hw_lock);
-       ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-                                     DIV_ROUND_UP(cdclk, 25000));
-       mutex_unlock(&dev_priv->rps.hw_lock);
-
-       if (ret) {
-               DRM_ERROR("PCode CDCLK freq set failed, (err %d, freq %d)\n",
-                         ret, cdclk);
-               return;
-       }
-
-       intel_update_cdclk(dev_priv);
-}
-
-static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
-{
-       u32 cdctl, expected;
-
-       intel_update_cdclk(dev_priv);
-
-       if (dev_priv->cdclk_pll.vco == 0 ||
-           dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref)
-               goto sanitize;
-
-       /* DPLL okay; verify the cdclock
-        *
-        * Some BIOS versions leave an incorrect decimal frequency value and
-        * set reserved MBZ bits in CDCLK_CTL at least during exiting from S4,
-        * so sanitize this register.
-        */
-       cdctl = I915_READ(CDCLK_CTL);
-       /*
-        * Let's ignore the pipe field, since BIOS could have configured the
-        * dividers both synching to an active pipe, or asynchronously
-        * (PIPE_NONE).
-        */
-       cdctl &= ~BXT_CDCLK_CD2X_PIPE_NONE;
-
-       expected = (cdctl & BXT_CDCLK_CD2X_DIV_SEL_MASK) |
-                  skl_cdclk_decimal(dev_priv->cdclk_freq);
-       /*
-        * Disable SSA Precharge when CD clock frequency < 500 MHz,
-        * enable otherwise.
-        */
-       if (dev_priv->cdclk_freq >= 500000)
-               expected |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
-
-       if (cdctl == expected)
-               /* All well; nothing to sanitize */
-               return;
-
-sanitize:
-       DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
-
-       /* force cdclk programming */
-       dev_priv->cdclk_freq = 0;
-
-       /* force full PLL disable + enable */
-       dev_priv->cdclk_pll.vco = -1;
-}
-
-void bxt_init_cdclk(struct drm_i915_private *dev_priv)
-{
-       int cdclk;
-
-       bxt_sanitize_cdclk(dev_priv);
-
-       if (dev_priv->cdclk_freq != 0 && dev_priv->cdclk_pll.vco != 0)
-               return;
-
-       /*
-        * FIXME:
-        * - The initial CDCLK needs to be read from VBT.
-        *   Need to make this change after VBT has changes for BXT.
-        */
-       if (IS_GEMINILAKE(dev_priv))
-               cdclk = glk_calc_cdclk(0);
-       else
-               cdclk = bxt_calc_cdclk(0);
-
-       bxt_set_cdclk(dev_priv, cdclk);
-}
-
-void bxt_uninit_cdclk(struct drm_i915_private *dev_priv)
-{
-       bxt_set_cdclk(dev_priv, dev_priv->cdclk_pll.ref);
-}
-
-static int skl_calc_cdclk(int max_pixclk, int vco)
-{
-       if (vco == 8640000) {
-               if (max_pixclk > 540000)
-                       return 617143;
-               else if (max_pixclk > 432000)
-                       return 540000;
-               else if (max_pixclk > 308571)
-                       return 432000;
-               else
-                       return 308571;
-       } else {
-               if (max_pixclk > 540000)
-                       return 675000;
-               else if (max_pixclk > 450000)
-                       return 540000;
-               else if (max_pixclk > 337500)
-                       return 450000;
-               else
-                       return 337500;
-       }
-}
-
-static void
-skl_dpll0_update(struct drm_i915_private *dev_priv)
-{
-       u32 val;
-
-       dev_priv->cdclk_pll.ref = 24000;
-       dev_priv->cdclk_pll.vco = 0;
-
-       val = I915_READ(LCPLL1_CTL);
-       if ((val & LCPLL_PLL_ENABLE) == 0)
-               return;
-
-       if (WARN_ON((val & LCPLL_PLL_LOCK) == 0))
-               return;
-
-       val = I915_READ(DPLL_CTRL1);
-
-       if (WARN_ON((val & (DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
-                           DPLL_CTRL1_SSC(SKL_DPLL0) |
-                           DPLL_CTRL1_OVERRIDE(SKL_DPLL0))) !=
-                   DPLL_CTRL1_OVERRIDE(SKL_DPLL0)))
-               return;
-
-       switch (val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) {
-       case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0):
-       case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, SKL_DPLL0):
-       case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, SKL_DPLL0):
-       case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, SKL_DPLL0):
-               dev_priv->cdclk_pll.vco = 8100000;
-               break;
-       case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0):
-       case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, SKL_DPLL0):
-               dev_priv->cdclk_pll.vco = 8640000;
-               break;
-       default:
-               MISSING_CASE(val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
-               break;
-       }
-}
-
-void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv, int vco)
-{
-       bool changed = dev_priv->skl_preferred_vco_freq != vco;
-
-       dev_priv->skl_preferred_vco_freq = vco;
-
-       if (changed)
-               intel_update_max_cdclk(dev_priv);
-}
-
-static void
-skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
-{
-       int min_cdclk = skl_calc_cdclk(0, vco);
-       u32 val;
-
-       WARN_ON(vco != 8100000 && vco != 8640000);
-
-       /* select the minimum CDCLK before enabling DPLL 0 */
-       val = CDCLK_FREQ_337_308 | skl_cdclk_decimal(min_cdclk);
-       I915_WRITE(CDCLK_CTL, val);
-       POSTING_READ(CDCLK_CTL);
-
-       /*
-        * We always enable DPLL0 with the lowest link rate possible, but still
-        * taking into account the VCO required to operate the eDP panel at the
-        * desired frequency. The usual DP link rates operate with a VCO of
-        * 8100 while the eDP 1.4 alternate link rates need a VCO of 8640.
-        * The modeset code is responsible for the selection of the exact link
-        * rate later on, with the constraint of choosing a frequency that
-        * works with vco.
-        */
-       val = I915_READ(DPLL_CTRL1);
-
-       val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
-                DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
-       val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
-       if (vco == 8640000)
-               val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
-                                           SKL_DPLL0);
-       else
-               val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
-                                           SKL_DPLL0);
-
-       I915_WRITE(DPLL_CTRL1, val);
-       POSTING_READ(DPLL_CTRL1);
-
-       I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) | LCPLL_PLL_ENABLE);
-
-       if (intel_wait_for_register(dev_priv,
-                                   LCPLL1_CTL, LCPLL_PLL_LOCK, LCPLL_PLL_LOCK,
-                                   5))
-               DRM_ERROR("DPLL0 not locked\n");
-
-       dev_priv->cdclk_pll.vco = vco;
-
-       /* We'll want to keep using the current vco from now on. */
-       skl_set_preferred_cdclk_vco(dev_priv, vco);
-}
-
-static void
-skl_dpll0_disable(struct drm_i915_private *dev_priv)
-{
-       I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
-       if (intel_wait_for_register(dev_priv,
-                                  LCPLL1_CTL, LCPLL_PLL_LOCK, 0,
-                                  1))
-               DRM_ERROR("Couldn't disable DPLL0\n");
-
-       dev_priv->cdclk_pll.vco = 0;
-}
-
-static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco)
-{
-       u32 freq_select, pcu_ack;
-       int ret;
-
-       WARN_ON((cdclk == 24000) != (vco == 0));
-
-       DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
-
-       mutex_lock(&dev_priv->rps.hw_lock);
-       ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
-                               SKL_CDCLK_PREPARE_FOR_CHANGE,
-                               SKL_CDCLK_READY_FOR_CHANGE,
-                               SKL_CDCLK_READY_FOR_CHANGE, 3);
-       mutex_unlock(&dev_priv->rps.hw_lock);
-       if (ret) {
-               DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
-                         ret);
-               return;
-       }
-
-       /* set CDCLK_CTL */
-       switch (cdclk) {
-       case 450000:
-       case 432000:
-               freq_select = CDCLK_FREQ_450_432;
-               pcu_ack = 1;
-               break;
-       case 540000:
-               freq_select = CDCLK_FREQ_540;
-               pcu_ack = 2;
-               break;
-       case 308571:
-       case 337500:
-       default:
-               freq_select = CDCLK_FREQ_337_308;
-               pcu_ack = 0;
-               break;
-       case 617143:
-       case 675000:
-               freq_select = CDCLK_FREQ_675_617;
-               pcu_ack = 3;
-               break;
-       }
-
-       if (dev_priv->cdclk_pll.vco != 0 &&
-           dev_priv->cdclk_pll.vco != vco)
-               skl_dpll0_disable(dev_priv);
-
-       if (dev_priv->cdclk_pll.vco != vco)
-               skl_dpll0_enable(dev_priv, vco);
-
-       I915_WRITE(CDCLK_CTL, freq_select | skl_cdclk_decimal(cdclk));
-       POSTING_READ(CDCLK_CTL);
-
-       /* inform PCU of the change */
-       mutex_lock(&dev_priv->rps.hw_lock);
-       sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
-       mutex_unlock(&dev_priv->rps.hw_lock);
-
-       intel_update_cdclk(dev_priv);
-}
-
-static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv);
-
-void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
-{
-       skl_set_cdclk(dev_priv, dev_priv->cdclk_pll.ref, 0);
-}
-
-void skl_init_cdclk(struct drm_i915_private *dev_priv)
-{
-       int cdclk, vco;
-
-       skl_sanitize_cdclk(dev_priv);
-
-       if (dev_priv->cdclk_freq != 0 && dev_priv->cdclk_pll.vco != 0) {
-               /*
-                * Use the current vco as our initial
-                * guess as to what the preferred vco is.
-                */
-               if (dev_priv->skl_preferred_vco_freq == 0)
-                       skl_set_preferred_cdclk_vco(dev_priv,
-                                                   dev_priv->cdclk_pll.vco);
-               return;
-       }
-
-       vco = dev_priv->skl_preferred_vco_freq;
-       if (vco == 0)
-               vco = 8100000;
-       cdclk = skl_calc_cdclk(0, vco);
-
-       skl_set_cdclk(dev_priv, cdclk, vco);
-}
-
-static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
-{
-       uint32_t cdctl, expected;
-
-       /*
-        * check if the pre-os intialized the display
-        * There is SWF18 scratchpad register defined which is set by the
-        * pre-os which can be used by the OS drivers to check the status
-        */
-       if ((I915_READ(SWF_ILK(0x18)) & 0x00FFFFFF) == 0)
-               goto sanitize;
-
-       intel_update_cdclk(dev_priv);
-       /* Is PLL enabled and locked ? */
-       if (dev_priv->cdclk_pll.vco == 0 ||
-           dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref)
-               goto sanitize;
-
-       /* DPLL okay; verify the cdclock
-        *
-        * Noticed in some instances that the freq selection is correct but
-        * decimal part is programmed wrong from BIOS where pre-os does not
-        * enable display. Verify the same as well.
-        */
-       cdctl = I915_READ(CDCLK_CTL);
-       expected = (cdctl & CDCLK_FREQ_SEL_MASK) |
-               skl_cdclk_decimal(dev_priv->cdclk_freq);
-       if (cdctl == expected)
-               /* All well; nothing to sanitize */
-               return;
-
-sanitize:
-       DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
-
-       /* force cdclk programming */
-       dev_priv->cdclk_freq = 0;
-       /* force full PLL disable + enable */
-       dev_priv->cdclk_pll.vco = -1;
-}
-
-/* Adjust CDclk dividers to allow high res or save power if possible */
-static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
-{
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       u32 val, cmd;
-
-       WARN_ON(dev_priv->display.get_display_clock_speed(dev_priv)
-                                       != dev_priv->cdclk_freq);
-
-       if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
-               cmd = 2;
-       else if (cdclk == 266667)
-               cmd = 1;
-       else
-               cmd = 0;
-
-       mutex_lock(&dev_priv->rps.hw_lock);
-       val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
-       val &= ~DSPFREQGUAR_MASK;
-       val |= (cmd << DSPFREQGUAR_SHIFT);
-       vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
-       if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
-                     DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
-                    50)) {
-               DRM_ERROR("timed out waiting for CDclk change\n");
-       }
-       mutex_unlock(&dev_priv->rps.hw_lock);
-
-       mutex_lock(&dev_priv->sb_lock);
-
-       if (cdclk == 400000) {
-               u32 divider;
-
-               divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
-
-               /* adjust cdclk divider */
-               val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
-               val &= ~CCK_FREQUENCY_VALUES;
-               val |= divider;
-               vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);
-
-               if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &
-                             CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),
-                            50))
-                       DRM_ERROR("timed out waiting for CDclk change\n");
-       }
-
-       /* adjust self-refresh exit latency value */
-       val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);
-       val &= ~0x7f;
-
-       /*
-        * For high bandwidth configs, we set a higher latency in the bunit
-        * so that the core display fetch happens in time to avoid underruns.
-        */
-       if (cdclk == 400000)
-               val |= 4500 / 250; /* 4.5 usec */
-       else
-               val |= 3000 / 250; /* 3.0 usec */
-       vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
-
-       mutex_unlock(&dev_priv->sb_lock);
-
-       intel_update_cdclk(dev_priv);
-}
-
-static void cherryview_set_cdclk(struct drm_device *dev, int cdclk)
-{
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       u32 val, cmd;
-
-       WARN_ON(dev_priv->display.get_display_clock_speed(dev_priv)
-                                               != dev_priv->cdclk_freq);
-
-       switch (cdclk) {
-       case 333333:
-       case 320000:
-       case 266667:
-       case 200000:
-               break;
-       default:
-               MISSING_CASE(cdclk);
-               return;
-       }
-
-       /*
-        * Specs are full of misinformation, but testing on actual
-        * hardware has shown that we just need to write the desired
-        * CCK divider into the Punit register.
-        */
-       cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
-
-       mutex_lock(&dev_priv->rps.hw_lock);
-       val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
-       val &= ~DSPFREQGUAR_MASK_CHV;
-       val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
-       vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
-       if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) &
-                     DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),
-                    50)) {
-               DRM_ERROR("timed out waiting for CDclk change\n");
-       }
-       mutex_unlock(&dev_priv->rps.hw_lock);
-
-       intel_update_cdclk(dev_priv);
-}
-
-static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
-                                int max_pixclk)
-{
-       int freq_320 = (dev_priv->hpll_freq <<  1) % 320000 != 0 ? 333333 : 320000;
-       int limit = IS_CHERRYVIEW(dev_priv) ? 95 : 90;
-
-       /*
-        * Really only a few cases to deal with, as only 4 CDclks are supported:
-        *   200MHz
-        *   267MHz
-        *   320/333MHz (depends on HPLL freq)
-        *   400MHz (VLV only)
-        * So we check to see whether we're above 90% (VLV) or 95% (CHV)
-        * of the lower bin and adjust if needed.
-        *
-        * We seem to get an unstable or solid color picture at 200MHz.
-        * Not sure what's wrong. For now use 200MHz only when all pipes
-        * are off.
-        */
-       if (!IS_CHERRYVIEW(dev_priv) &&
-           max_pixclk > freq_320*limit/100)
-               return 400000;
-       else if (max_pixclk > 266667*limit/100)
-               return freq_320;
-       else if (max_pixclk > 0)
-               return 266667;
-       else
-               return 200000;
-}
-
-static int glk_calc_cdclk(int max_pixclk)
-{
-       if (max_pixclk > 2 * 158400)
-               return 316800;
-       else if (max_pixclk > 2 * 79200)
-               return 158400;
-       else
-               return 79200;
-}
-
-static int bxt_calc_cdclk(int max_pixclk)
-{
-       if (max_pixclk > 576000)
-               return 624000;
-       else if (max_pixclk > 384000)
-               return 576000;
-       else if (max_pixclk > 288000)
-               return 384000;
-       else if (max_pixclk > 144000)
-               return 288000;
-       else
-               return 144000;
-}
-
-/* Compute the max pixel clock for new configuration. */
-static int intel_mode_max_pixclk(struct drm_device *dev,
-                                struct drm_atomic_state *state)
-{
-       struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct drm_crtc *crtc;
-       struct drm_crtc_state *crtc_state;
-       unsigned max_pixclk = 0, i;
-       enum pipe pipe;
-
-       memcpy(intel_state->min_pixclk, dev_priv->min_pixclk,
-              sizeof(intel_state->min_pixclk));
-
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
-               int pixclk = 0;
-
-               if (crtc_state->enable)
-                       pixclk = crtc_state->adjusted_mode.crtc_clock;
-
-               intel_state->min_pixclk[i] = pixclk;
-       }
-
-       for_each_pipe(dev_priv, pipe)
-               max_pixclk = max(intel_state->min_pixclk[pipe], max_pixclk);
-
-       return max_pixclk;
-}
-
-static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state)
-{
-       struct drm_device *dev = state->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       int max_pixclk = intel_mode_max_pixclk(dev, state);
-       struct intel_atomic_state *intel_state =
-               to_intel_atomic_state(state);
-
-       intel_state->cdclk = intel_state->dev_cdclk =
-               valleyview_calc_cdclk(dev_priv, max_pixclk);
-
-       if (!intel_state->active_crtcs)
-               intel_state->dev_cdclk = valleyview_calc_cdclk(dev_priv, 0);
-
-       return 0;
-}
-
-static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
-{
-       struct drm_i915_private *dev_priv = to_i915(state->dev);
-       int max_pixclk = ilk_max_pixel_rate(state);
-       struct intel_atomic_state *intel_state =
-               to_intel_atomic_state(state);
-       int cdclk;
-
-       if (IS_GEMINILAKE(dev_priv))
-               cdclk = glk_calc_cdclk(max_pixclk);
-       else
-               cdclk = bxt_calc_cdclk(max_pixclk);
-
-       intel_state->cdclk = intel_state->dev_cdclk = cdclk;
-
-       if (!intel_state->active_crtcs) {
-               if (IS_GEMINILAKE(dev_priv))
-                       cdclk = glk_calc_cdclk(0);
-               else
-                       cdclk = bxt_calc_cdclk(0);
-
-               intel_state->dev_cdclk = cdclk;
-       }
-
-       return 0;
-}
-
-static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
-{
-       unsigned int credits, default_credits;
-
-       if (IS_CHERRYVIEW(dev_priv))
-               default_credits = PFI_CREDIT(12);
-       else
-               default_credits = PFI_CREDIT(8);
-
-       if (dev_priv->cdclk_freq >= dev_priv->czclk_freq) {
-               /* CHV suggested value is 31 or 63 */
-               if (IS_CHERRYVIEW(dev_priv))
-                       credits = PFI_CREDIT_63;
-               else
-                       credits = PFI_CREDIT(15);
-       } else {
-               credits = default_credits;
-       }
-
-       /*
-        * WA - write default credits before re-programming
-        * FIXME: should we also set the resend bit here?
-        */
-       I915_WRITE(GCI_CONTROL, VGA_FAST_MODE_DISABLE |
-                  default_credits);
-
-       I915_WRITE(GCI_CONTROL, VGA_FAST_MODE_DISABLE |
-                  credits | PFI_CREDIT_RESEND);
-
-       /*
-        * FIXME is this guaranteed to clear
-        * immediately or should we poll for it?
-        */
-       WARN_ON(I915_READ(GCI_CONTROL) & PFI_CREDIT_RESEND);
-}
-
-static void valleyview_modeset_commit_cdclk(struct drm_atomic_state *old_state)
-{
-       struct drm_device *dev = old_state->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_atomic_state *old_intel_state =
-               to_intel_atomic_state(old_state);
-       unsigned req_cdclk = old_intel_state->dev_cdclk;
-
-       /*
-        * FIXME: We can end up here with all power domains off, yet
-        * with a CDCLK frequency other than the minimum. To account
-        * for this take the PIPE-A power domain, which covers the HW
-        * blocks needed for the following programming. This can be
-        * removed once it's guaranteed that we get here either with
-        * the minimum CDCLK set, or the required power domains
-        * enabled.
-        */
-       intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
-
-       if (IS_CHERRYVIEW(dev_priv))
-               cherryview_set_cdclk(dev, req_cdclk);
-       else
-               valleyview_set_cdclk(dev, req_cdclk);
-
-       vlv_program_pfi_credits(dev_priv);
-
-       intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
-}
-
-static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
-                                  struct drm_atomic_state *old_state)
-{
-       struct drm_crtc *crtc = pipe_config->base.crtc;
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
-
-       if (WARN_ON(intel_crtc->active))
-               return;
-
-       if (intel_crtc_has_dp_encoder(intel_crtc->config))
-               intel_dp_set_m_n(intel_crtc, M1_N1);
-
-       intel_set_pipe_timings(intel_crtc);
-       intel_set_pipe_src_size(intel_crtc);
-
-       if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
-               struct drm_i915_private *dev_priv = to_i915(dev);
-
-               I915_WRITE(CHV_BLEND(pipe), CHV_BLEND_LEGACY);
-               I915_WRITE(CHV_CANVAS(pipe), 0);
-       }
-
-       i9xx_set_pipeconf(intel_crtc);
-
-       intel_crtc->active = true;
-
-       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
-
-       intel_encoders_pre_pll_enable(crtc, pipe_config, old_state);
-
-       if (IS_CHERRYVIEW(dev_priv)) {
-               chv_prepare_pll(intel_crtc, intel_crtc->config);
-               chv_enable_pll(intel_crtc, intel_crtc->config);
-       } else {
-               vlv_prepare_pll(intel_crtc, intel_crtc->config);
-               vlv_enable_pll(intel_crtc, intel_crtc->config);
-       }
-
-       intel_encoders_pre_enable(crtc, pipe_config, old_state);
-
-       i9xx_pfit_enable(intel_crtc);
-
-       intel_color_load_luts(&pipe_config->base);
-
-       intel_update_watermarks(intel_crtc);
-       intel_enable_pipe(intel_crtc);
-
-       assert_vblank_disabled(crtc);
-       drm_crtc_vblank_on(crtc);
-
-       intel_encoders_enable(crtc, pipe_config, old_state);
-}
-
-static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
-{
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-
-       I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0);
-       I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1);
-}
-
-static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
-                            struct drm_atomic_state *old_state)
-{
-       struct drm_crtc *crtc = pipe_config->base.crtc;
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum pipe pipe = intel_crtc->pipe;
-
-       if (WARN_ON(intel_crtc->active))
-               return;
-
-       i9xx_set_pll_dividers(intel_crtc);
-
-       if (intel_crtc_has_dp_encoder(intel_crtc->config))
-               intel_dp_set_m_n(intel_crtc, M1_N1);
-
-       intel_set_pipe_timings(intel_crtc);
-       intel_set_pipe_src_size(intel_crtc);
-
-       i9xx_set_pipeconf(intel_crtc);
-
-       intel_crtc->active = true;
-
-       if (!IS_GEN2(dev_priv))
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
-
-       intel_encoders_pre_enable(crtc, pipe_config, old_state);
-
-       i9xx_enable_pll(intel_crtc);
-
-       i9xx_pfit_enable(intel_crtc);
-
-       intel_color_load_luts(&pipe_config->base);
-
-       intel_update_watermarks(intel_crtc);
-       intel_enable_pipe(intel_crtc);
-
-       assert_vblank_disabled(crtc);
-       drm_crtc_vblank_on(crtc);
-
-       intel_encoders_enable(crtc, pipe_config, old_state);
-}
-
-static void i9xx_pfit_disable(struct intel_crtc *crtc)
-{
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+static void i9xx_pfit_disable(struct intel_crtc *crtc)
+{
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
 
        if (!crtc->config->gmch_pfit.control)
                return;
@@ -6857,6 +5846,9 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
 
        if (!IS_GEN2(dev_priv))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+
+       if (!dev_priv->display.initial_watermarks)
+               intel_update_watermarks(intel_crtc);
 }
 
 static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
@@ -6865,7 +5857,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->dev);
        enum intel_display_power_domain domain;
-       unsigned long domains;
+       u64 domains;
        struct drm_atomic_state *state;
        struct intel_crtc_state *crtc_state;
        int ret;
@@ -7173,7 +6165,7 @@ static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
         *
         * Should measure whether using a lower cdclk w/o IPS
         */
-       return ilk_pipe_pixel_rate(pipe_config) <=
+       return pipe_config->pixel_rate <=
                dev_priv->max_cdclk_freq * 95 / 100;
 }
 
@@ -7188,490 +6180,118 @@ static void hsw_compute_ips_config(struct intel_crtc *crtc,
                pipe_config_supports_ips(dev_priv, pipe_config);
 }
 
-static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
-{
-       const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
-       /* GDG double wide on either pipe, otherwise pipe A only */
-       return INTEL_INFO(dev_priv)->gen < 4 &&
-               (crtc->pipe == PIPE_A || IS_I915G(dev_priv));
-}
-
-static int intel_crtc_compute_config(struct intel_crtc *crtc,
-                                    struct intel_crtc_state *pipe_config)
-{
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
-       int clock_limit = dev_priv->max_dotclk_freq;
-
-       if (INTEL_GEN(dev_priv) < 4) {
-               clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
-
-               /*
-                * Enable double wide mode when the dot clock
-                * is > 90% of the (display) core speed.
-                */
-               if (intel_crtc_supports_double_wide(crtc) &&
-                   adjusted_mode->crtc_clock > clock_limit) {
-                       clock_limit = dev_priv->max_dotclk_freq;
-                       pipe_config->double_wide = true;
-               }
-       }
-
-       if (adjusted_mode->crtc_clock > clock_limit) {
-               DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
-                             adjusted_mode->crtc_clock, clock_limit,
-                             yesno(pipe_config->double_wide));
-               return -EINVAL;
-       }
-
-       /*
-        * Pipe horizontal size must be even in:
-        * - DVO ganged mode
-        * - LVDS dual channel mode
-        * - Double wide pipe
-        */
-       if ((intel_crtc_has_type(pipe_config, INTEL_OUTPUT_LVDS) &&
-            intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
-               pipe_config->pipe_src_w &= ~1;
-
-       /* Cantiga+ cannot handle modes with a hsync front porch of 0.
-        * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
-        */
-       if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
-               adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
-               return -EINVAL;
-
-       if (HAS_IPS(dev_priv))
-               hsw_compute_ips_config(crtc, pipe_config);
-
-       if (pipe_config->has_pch_encoder)
-               return ironlake_fdi_compute_config(crtc, pipe_config);
-
-       return 0;
-}
-
-static int skylake_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       u32 cdctl;
-
-       skl_dpll0_update(dev_priv);
-
-       if (dev_priv->cdclk_pll.vco == 0)
-               return dev_priv->cdclk_pll.ref;
-
-       cdctl = I915_READ(CDCLK_CTL);
-
-       if (dev_priv->cdclk_pll.vco == 8640000) {
-               switch (cdctl & CDCLK_FREQ_SEL_MASK) {
-               case CDCLK_FREQ_450_432:
-                       return 432000;
-               case CDCLK_FREQ_337_308:
-                       return 308571;
-               case CDCLK_FREQ_540:
-                       return 540000;
-               case CDCLK_FREQ_675_617:
-                       return 617143;
-               default:
-                       MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);
-               }
-       } else {
-               switch (cdctl & CDCLK_FREQ_SEL_MASK) {
-               case CDCLK_FREQ_450_432:
-                       return 450000;
-               case CDCLK_FREQ_337_308:
-                       return 337500;
-               case CDCLK_FREQ_540:
-                       return 540000;
-               case CDCLK_FREQ_675_617:
-                       return 675000;
-               default:
-                       MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);
-               }
-       }
-
-       return dev_priv->cdclk_pll.ref;
-}
-
-static void bxt_de_pll_update(struct drm_i915_private *dev_priv)
-{
-       u32 val;
-
-       dev_priv->cdclk_pll.ref = 19200;
-       dev_priv->cdclk_pll.vco = 0;
-
-       val = I915_READ(BXT_DE_PLL_ENABLE);
-       if ((val & BXT_DE_PLL_PLL_ENABLE) == 0)
-               return;
-
-       if (WARN_ON((val & BXT_DE_PLL_LOCK) == 0))
-               return;
-
-       val = I915_READ(BXT_DE_PLL_CTL);
-       dev_priv->cdclk_pll.vco = (val & BXT_DE_PLL_RATIO_MASK) *
-               dev_priv->cdclk_pll.ref;
-}
-
-static int broxton_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       u32 divider;
-       int div, vco;
-
-       bxt_de_pll_update(dev_priv);
-
-       vco = dev_priv->cdclk_pll.vco;
-       if (vco == 0)
-               return dev_priv->cdclk_pll.ref;
-
-       divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
-
-       switch (divider) {
-       case BXT_CDCLK_CD2X_DIV_SEL_1:
-               div = 2;
-               break;
-       case BXT_CDCLK_CD2X_DIV_SEL_1_5:
-               WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n");
-               div = 3;
-               break;
-       case BXT_CDCLK_CD2X_DIV_SEL_2:
-               div = 4;
-               break;
-       case BXT_CDCLK_CD2X_DIV_SEL_4:
-               div = 8;
-               break;
-       default:
-               MISSING_CASE(divider);
-               return dev_priv->cdclk_pll.ref;
-       }
-
-       return DIV_ROUND_CLOSEST(vco, div);
-}
-
-static int broadwell_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       uint32_t lcpll = I915_READ(LCPLL_CTL);
-       uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
-
-       if (lcpll & LCPLL_CD_SOURCE_FCLK)
-               return 800000;
-       else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
-               return 450000;
-       else if (freq == LCPLL_CLK_FREQ_450)
-               return 450000;
-       else if (freq == LCPLL_CLK_FREQ_54O_BDW)
-               return 540000;
-       else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
-               return 337500;
-       else
-               return 675000;
-}
-
-static int haswell_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       uint32_t lcpll = I915_READ(LCPLL_CTL);
-       uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
-
-       if (lcpll & LCPLL_CD_SOURCE_FCLK)
-               return 800000;
-       else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
-               return 450000;
-       else if (freq == LCPLL_CLK_FREQ_450)
-               return 450000;
-       else if (IS_HSW_ULT(dev_priv))
-               return 337500;
-       else
-               return 540000;
-}
-
-static int valleyview_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       return vlv_get_cck_clock_hpll(dev_priv, "cdclk",
-                                     CCK_DISPLAY_CLOCK_CONTROL);
-}
-
-static int ilk_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       return 450000;
-}
-
-static int i945_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       return 400000;
-}
-
-static int i915_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       return 333333;
-}
-
-static int i9xx_misc_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       return 200000;
-}
-
-static int pnv_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       u16 gcfgc = 0;
-
-       pci_read_config_word(pdev, GCFGC, &gcfgc);
-
-       switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
-       case GC_DISPLAY_CLOCK_267_MHZ_PNV:
-               return 266667;
-       case GC_DISPLAY_CLOCK_333_MHZ_PNV:
-               return 333333;
-       case GC_DISPLAY_CLOCK_444_MHZ_PNV:
-               return 444444;
-       case GC_DISPLAY_CLOCK_200_MHZ_PNV:
-               return 200000;
-       default:
-               DRM_ERROR("Unknown pnv display core clock 0x%04x\n", gcfgc);
-       case GC_DISPLAY_CLOCK_133_MHZ_PNV:
-               return 133333;
-       case GC_DISPLAY_CLOCK_167_MHZ_PNV:
-               return 166667;
-       }
-}
-
-static int i915gm_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       u16 gcfgc = 0;
-
-       pci_read_config_word(pdev, GCFGC, &gcfgc);
-
-       if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
-               return 133333;
-       else {
-               switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
-               case GC_DISPLAY_CLOCK_333_MHZ:
-                       return 333333;
-               default:
-               case GC_DISPLAY_CLOCK_190_200_MHZ:
-                       return 190000;
-               }
-       }
-}
-
-static int i865_get_display_clock_speed(struct drm_i915_private *dev_priv)
+static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
 {
-       return 266667;
+       const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+       /* GDG double wide on either pipe, otherwise pipe A only */
+       return INTEL_INFO(dev_priv)->gen < 4 &&
+               (crtc->pipe == PIPE_A || IS_I915G(dev_priv));
 }
 
-static int i85x_get_display_clock_speed(struct drm_i915_private *dev_priv)
+static uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 {
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       u16 hpllcc = 0;
+       uint32_t pixel_rate;
+
+       pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
 
        /*
-        * 852GM/852GMV only supports 133 MHz and the HPLLCC
-        * encoding is different :(
-        * FIXME is this the right way to detect 852GM/852GMV?
+        * We only use IF-ID interlacing. If we ever use
+        * PF-ID we'll need to adjust the pixel_rate here.
         */
-       if (pdev->revision == 0x1)
-               return 133333;
 
-       pci_bus_read_config_word(pdev->bus,
-                                PCI_DEVFN(0, 3), HPLLCC, &hpllcc);
+       if (pipe_config->pch_pfit.enabled) {
+               uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
+               uint32_t pfit_size = pipe_config->pch_pfit.size;
 
-       /* Assume that the hardware is in the high speed state.  This
-        * should be the default.
-        */
-       switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
-       case GC_CLOCK_133_200:
-       case GC_CLOCK_133_200_2:
-       case GC_CLOCK_100_200:
-               return 200000;
-       case GC_CLOCK_166_250:
-               return 250000;
-       case GC_CLOCK_100_133:
-               return 133333;
-       case GC_CLOCK_133_266:
-       case GC_CLOCK_133_266_2:
-       case GC_CLOCK_166_266:
-               return 266667;
-       }
-
-       /* Shouldn't happen */
-       return 0;
-}
-
-static int i830_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       return 133333;
-}
+               pipe_w = pipe_config->pipe_src_w;
+               pipe_h = pipe_config->pipe_src_h;
 
-static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv)
-{
-       static const unsigned int blb_vco[8] = {
-               [0] = 3200000,
-               [1] = 4000000,
-               [2] = 5333333,
-               [3] = 4800000,
-               [4] = 6400000,
-       };
-       static const unsigned int pnv_vco[8] = {
-               [0] = 3200000,
-               [1] = 4000000,
-               [2] = 5333333,
-               [3] = 4800000,
-               [4] = 2666667,
-       };
-       static const unsigned int cl_vco[8] = {
-               [0] = 3200000,
-               [1] = 4000000,
-               [2] = 5333333,
-               [3] = 6400000,
-               [4] = 3333333,
-               [5] = 3566667,
-               [6] = 4266667,
-       };
-       static const unsigned int elk_vco[8] = {
-               [0] = 3200000,
-               [1] = 4000000,
-               [2] = 5333333,
-               [3] = 4800000,
-       };
-       static const unsigned int ctg_vco[8] = {
-               [0] = 3200000,
-               [1] = 4000000,
-               [2] = 5333333,
-               [3] = 6400000,
-               [4] = 2666667,
-               [5] = 4266667,
-       };
-       const unsigned int *vco_table;
-       unsigned int vco;
-       uint8_t tmp = 0;
-
-       /* FIXME other chipsets? */
-       if (IS_GM45(dev_priv))
-               vco_table = ctg_vco;
-       else if (IS_G4X(dev_priv))
-               vco_table = elk_vco;
-       else if (IS_I965GM(dev_priv))
-               vco_table = cl_vco;
-       else if (IS_PINEVIEW(dev_priv))
-               vco_table = pnv_vco;
-       else if (IS_G33(dev_priv))
-               vco_table = blb_vco;
-       else
-               return 0;
+               pfit_w = (pfit_size >> 16) & 0xFFFF;
+               pfit_h = pfit_size & 0xFFFF;
+               if (pipe_w < pfit_w)
+                       pipe_w = pfit_w;
+               if (pipe_h < pfit_h)
+                       pipe_h = pfit_h;
 
-       tmp = I915_READ(IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO);
+               if (WARN_ON(!pfit_w || !pfit_h))
+                       return pixel_rate;
 
-       vco = vco_table[tmp & 0x7];
-       if (vco == 0)
-               DRM_ERROR("Bad HPLL VCO (HPLLVCO=0x%02x)\n", tmp);
-       else
-               DRM_DEBUG_KMS("HPLL VCO %u kHz\n", vco);
+               pixel_rate = div_u64((uint64_t) pixel_rate * pipe_w * pipe_h,
+                                    pfit_w * pfit_h);
+       }
 
-       return vco;
+       return pixel_rate;
 }
 
-static int gm45_get_display_clock_speed(struct drm_i915_private *dev_priv)
+static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
 {
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       unsigned int cdclk_sel, vco = intel_hpll_vco(dev_priv);
-       uint16_t tmp = 0;
-
-       pci_read_config_word(pdev, GCFGC, &tmp);
-
-       cdclk_sel = (tmp >> 12) & 0x1;
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
 
-       switch (vco) {
-       case 2666667:
-       case 4000000:
-       case 5333333:
-               return cdclk_sel ? 333333 : 222222;
-       case 3200000:
-               return cdclk_sel ? 320000 : 228571;
-       default:
-               DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u, CFGC=0x%04x\n", vco, tmp);
-               return 222222;
-       }
+       if (HAS_GMCH_DISPLAY(dev_priv))
+               /* FIXME calculate proper pipe pixel rate for GMCH pfit */
+               crtc_state->pixel_rate =
+                       crtc_state->base.adjusted_mode.crtc_clock;
+       else
+               crtc_state->pixel_rate =
+                       ilk_pipe_pixel_rate(crtc_state);
 }
 
-static int i965gm_get_display_clock_speed(struct drm_i915_private *dev_priv)
+static int intel_crtc_compute_config(struct intel_crtc *crtc,
+                                    struct intel_crtc_state *pipe_config)
 {
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       static const uint8_t div_3200[] = { 16, 10,  8 };
-       static const uint8_t div_4000[] = { 20, 12, 10 };
-       static const uint8_t div_5333[] = { 24, 16, 14 };
-       const uint8_t *div_table;
-       unsigned int cdclk_sel, vco = intel_hpll_vco(dev_priv);
-       uint16_t tmp = 0;
-
-       pci_read_config_word(pdev, GCFGC, &tmp);
-
-       cdclk_sel = ((tmp >> 8) & 0x1f) - 1;
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+       int clock_limit = dev_priv->max_dotclk_freq;
 
-       if (cdclk_sel >= ARRAY_SIZE(div_3200))
-               goto fail;
+       if (INTEL_GEN(dev_priv) < 4) {
+               clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
 
-       switch (vco) {
-       case 3200000:
-               div_table = div_3200;
-               break;
-       case 4000000:
-               div_table = div_4000;
-               break;
-       case 5333333:
-               div_table = div_5333;
-               break;
-       default:
-               goto fail;
+               /*
+                * Enable double wide mode when the dot clock
+                * is > 90% of the (display) core speed.
+                */
+               if (intel_crtc_supports_double_wide(crtc) &&
+                   adjusted_mode->crtc_clock > clock_limit) {
+                       clock_limit = dev_priv->max_dotclk_freq;
+                       pipe_config->double_wide = true;
+               }
        }
 
-       return DIV_ROUND_CLOSEST(vco, div_table[cdclk_sel]);
-
-fail:
-       DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%04x\n", vco, tmp);
-       return 200000;
-}
-
-static int g33_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       static const uint8_t div_3200[] = { 12, 10,  8,  7, 5, 16 };
-       static const uint8_t div_4000[] = { 14, 12, 10,  8, 6, 20 };
-       static const uint8_t div_4800[] = { 20, 14, 12, 10, 8, 24 };
-       static const uint8_t div_5333[] = { 20, 16, 12, 12, 8, 28 };
-       const uint8_t *div_table;
-       unsigned int cdclk_sel, vco = intel_hpll_vco(dev_priv);
-       uint16_t tmp = 0;
+       if (adjusted_mode->crtc_clock > clock_limit) {
+               DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
+                             adjusted_mode->crtc_clock, clock_limit,
+                             yesno(pipe_config->double_wide));
+               return -EINVAL;
+       }
 
-       pci_read_config_word(pdev, GCFGC, &tmp);
+       /*
+        * Pipe horizontal size must be even in:
+        * - DVO ganged mode
+        * - LVDS dual channel mode
+        * - Double wide pipe
+        */
+       if ((intel_crtc_has_type(pipe_config, INTEL_OUTPUT_LVDS) &&
+            intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
+               pipe_config->pipe_src_w &= ~1;
 
-       cdclk_sel = (tmp >> 4) & 0x7;
+       /* Cantiga+ cannot handle modes with a hsync front porch of 0.
+        * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
+        */
+       if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
+               adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
+               return -EINVAL;
 
-       if (cdclk_sel >= ARRAY_SIZE(div_3200))
-               goto fail;
+       intel_crtc_compute_pixel_rate(pipe_config);
 
-       switch (vco) {
-       case 3200000:
-               div_table = div_3200;
-               break;
-       case 4000000:
-               div_table = div_4000;
-               break;
-       case 4800000:
-               div_table = div_4800;
-               break;
-       case 5333333:
-               div_table = div_5333;
-               break;
-       default:
-               goto fail;
-       }
+       if (HAS_IPS(dev_priv))
+               hsw_compute_ips_config(crtc, pipe_config);
 
-       return DIV_ROUND_CLOSEST(vco, div_table[cdclk_sel]);
+       if (pipe_config->has_pch_encoder)
+               return ironlake_fdi_compute_config(crtc, pipe_config);
 
-fail:
-       DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%08x\n", vco, tmp);
-       return 190476;
+       return 0;
 }
 
 static void
@@ -8768,7 +7388,8 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
        val = I915_READ(DSPSTRIDE(pipe));
        fb->pitches[0] = val & 0xffffffc0;
 
-       aligned_height = intel_fb_align_height(dev, fb->height,
+       aligned_height = intel_fb_align_height(dev_priv,
+                                              fb->height,
                                               fb->format->format,
                                               fb->modifier);
 
@@ -9809,7 +8430,8 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
                                                fb->format->format);
        fb->pitches[0] = (val & 0x3ff) * stride_mult;
 
-       aligned_height = intel_fb_align_height(dev, fb->height,
+       aligned_height = intel_fb_align_height(dev_priv,
+                                              fb->height,
                                               fb->format->format,
                                               fb->modifier);
 
@@ -9907,7 +8529,8 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
        val = I915_READ(DSPSTRIDE(pipe));
        fb->pitches[0] = val & 0xffffffc0;
 
-       aligned_height = intel_fb_align_height(dev, fb->height,
+       aligned_height = intel_fb_align_height(dev_priv,
+                                              fb->height,
                                               fb->format->format,
                                               fb->modifier);
 
@@ -10166,312 +8789,73 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
                                    5))
                DRM_ERROR("LCPLL not locked yet\n");
 
-       if (val & LCPLL_CD_SOURCE_FCLK) {
-               val = I915_READ(LCPLL_CTL);
-               val &= ~LCPLL_CD_SOURCE_FCLK;
-               I915_WRITE(LCPLL_CTL, val);
-
-               if (wait_for_us((I915_READ(LCPLL_CTL) &
-                                LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
-                       DRM_ERROR("Switching back to LCPLL failed\n");
-       }
-
-       intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
-       intel_update_cdclk(dev_priv);
-}
-
-/*
- * Package states C8 and deeper are really deep PC states that can only be
- * reached when all the devices on the system allow it, so even if the graphics
- * device allows PC8+, it doesn't mean the system will actually get to these
- * states. Our driver only allows PC8+ when going into runtime PM.
- *
- * The requirements for PC8+ are that all the outputs are disabled, the power
- * well is disabled and most interrupts are disabled, and these are also
- * requirements for runtime PM. When these conditions are met, we manually do
- * the other conditions: disable the interrupts, clocks and switch LCPLL refclk
- * to Fclk. If we're in PC8+ and we get an non-hotplug interrupt, we can hard
- * hang the machine.
- *
- * When we really reach PC8 or deeper states (not just when we allow it) we lose
- * the state of some registers, so when we come back from PC8+ we need to
- * restore this state. We don't get into PC8+ if we're not in RC6, so we don't
- * need to take care of the registers kept by RC6. Notice that this happens even
- * if we don't put the device in PCI D3 state (which is what currently happens
- * because of the runtime PM support).
- *
- * For more, read "Display Sequences for Package C8" on the hardware
- * documentation.
- */
-void hsw_enable_pc8(struct drm_i915_private *dev_priv)
-{
-       uint32_t val;
-
-       DRM_DEBUG_KMS("Enabling package C8+\n");
-
-       if (HAS_PCH_LPT_LP(dev_priv)) {
-               val = I915_READ(SOUTH_DSPCLK_GATE_D);
-               val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
-               I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
-       }
-
-       lpt_disable_clkout_dp(dev_priv);
-       hsw_disable_lcpll(dev_priv, true, true);
-}
-
-void hsw_disable_pc8(struct drm_i915_private *dev_priv)
-{
-       uint32_t val;
-
-       DRM_DEBUG_KMS("Disabling package C8+\n");
-
-       hsw_restore_lcpll(dev_priv);
-       lpt_init_pch_refclk(dev_priv);
-
-       if (HAS_PCH_LPT_LP(dev_priv)) {
-               val = I915_READ(SOUTH_DSPCLK_GATE_D);
-               val |= PCH_LP_PARTITION_LEVEL_DISABLE;
-               I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
-       }
-}
-
-static void bxt_modeset_commit_cdclk(struct drm_atomic_state *old_state)
-{
-       struct drm_device *dev = old_state->dev;
-       struct intel_atomic_state *old_intel_state =
-               to_intel_atomic_state(old_state);
-       unsigned int req_cdclk = old_intel_state->dev_cdclk;
-
-       bxt_set_cdclk(to_i915(dev), req_cdclk);
-}
-
-static int bdw_adjust_min_pipe_pixel_rate(struct intel_crtc_state *crtc_state,
-                                         int pixel_rate)
-{
-       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-
-       /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
-       if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
-               pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95);
-
-       /* BSpec says "Do not use DisplayPort with CDCLK less than
-        * 432 MHz, audio enabled, port width x4, and link rate
-        * HBR2 (5.4 GHz), or else there may be audio corruption or
-        * screen corruption."
-        */
-       if (intel_crtc_has_dp_encoder(crtc_state) &&
-           crtc_state->has_audio &&
-           crtc_state->port_clock >= 540000 &&
-           crtc_state->lane_count == 4)
-               pixel_rate = max(432000, pixel_rate);
-
-       return pixel_rate;
-}
-
-/* compute the max rate for new configuration */
-static int ilk_max_pixel_rate(struct drm_atomic_state *state)
-{
-       struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-       struct drm_i915_private *dev_priv = to_i915(state->dev);
-       struct drm_crtc *crtc;
-       struct drm_crtc_state *cstate;
-       struct intel_crtc_state *crtc_state;
-       unsigned max_pixel_rate = 0, i;
-       enum pipe pipe;
-
-       memcpy(intel_state->min_pixclk, dev_priv->min_pixclk,
-              sizeof(intel_state->min_pixclk));
-
-       for_each_crtc_in_state(state, crtc, cstate, i) {
-               int pixel_rate;
-
-               crtc_state = to_intel_crtc_state(cstate);
-               if (!crtc_state->base.enable) {
-                       intel_state->min_pixclk[i] = 0;
-                       continue;
-               }
-
-               pixel_rate = ilk_pipe_pixel_rate(crtc_state);
-
-               if (IS_BROADWELL(dev_priv) || IS_GEN9(dev_priv))
-                       pixel_rate = bdw_adjust_min_pipe_pixel_rate(crtc_state,
-                                                                   pixel_rate);
-
-               intel_state->min_pixclk[i] = pixel_rate;
-       }
-
-       for_each_pipe(dev_priv, pipe)
-               max_pixel_rate = max(intel_state->min_pixclk[pipe], max_pixel_rate);
-
-       return max_pixel_rate;
-}
-
-static void broadwell_set_cdclk(struct drm_device *dev, int cdclk)
-{
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       uint32_t val, data;
-       int ret;
-
-       if (WARN((I915_READ(LCPLL_CTL) &
-                 (LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |
-                  LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE |
-                  LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW |
-                  LCPLL_CD_SOURCE_FCLK)) != LCPLL_PLL_LOCK,
-                "trying to change cdclk frequency with cdclk not enabled\n"))
-               return;
-
-       mutex_lock(&dev_priv->rps.hw_lock);
-       ret = sandybridge_pcode_write(dev_priv,
-                                     BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
-       mutex_unlock(&dev_priv->rps.hw_lock);
-       if (ret) {
-               DRM_ERROR("failed to inform pcode about cdclk change\n");
-               return;
-       }
-
-       val = I915_READ(LCPLL_CTL);
-       val |= LCPLL_CD_SOURCE_FCLK;
-       I915_WRITE(LCPLL_CTL, val);
-
-       if (wait_for_us(I915_READ(LCPLL_CTL) &
-                       LCPLL_CD_SOURCE_FCLK_DONE, 1))
-               DRM_ERROR("Switching to FCLK failed\n");
-
-       val = I915_READ(LCPLL_CTL);
-       val &= ~LCPLL_CLK_FREQ_MASK;
-
-       switch (cdclk) {
-       case 450000:
-               val |= LCPLL_CLK_FREQ_450;
-               data = 0;
-               break;
-       case 540000:
-               val |= LCPLL_CLK_FREQ_54O_BDW;
-               data = 1;
-               break;
-       case 337500:
-               val |= LCPLL_CLK_FREQ_337_5_BDW;
-               data = 2;
-               break;
-       case 675000:
-               val |= LCPLL_CLK_FREQ_675_BDW;
-               data = 3;
-               break;
-       default:
-               WARN(1, "invalid cdclk frequency\n");
-               return;
-       }
-
-       I915_WRITE(LCPLL_CTL, val);
-
-       val = I915_READ(LCPLL_CTL);
-       val &= ~LCPLL_CD_SOURCE_FCLK;
-       I915_WRITE(LCPLL_CTL, val);
-
-       if (wait_for_us((I915_READ(LCPLL_CTL) &
-                       LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
-               DRM_ERROR("Switching back to LCPLL failed\n");
-
-       mutex_lock(&dev_priv->rps.hw_lock);
-       sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
-       mutex_unlock(&dev_priv->rps.hw_lock);
-
-       I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
-
-       intel_update_cdclk(dev_priv);
-
-       WARN(cdclk != dev_priv->cdclk_freq,
-            "cdclk requested %d kHz but got %d kHz\n",
-            cdclk, dev_priv->cdclk_freq);
-}
-
-static int broadwell_calc_cdclk(int max_pixclk)
-{
-       if (max_pixclk > 540000)
-               return 675000;
-       else if (max_pixclk > 450000)
-               return 540000;
-       else if (max_pixclk > 337500)
-               return 450000;
-       else
-               return 337500;
-}
-
-static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state)
-{
-       struct drm_i915_private *dev_priv = to_i915(state->dev);
-       struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-       int max_pixclk = ilk_max_pixel_rate(state);
-       int cdclk;
-
-       /*
-        * FIXME should also account for plane ratio
-        * once 64bpp pixel formats are supported.
-        */
-       cdclk = broadwell_calc_cdclk(max_pixclk);
-
-       if (cdclk > dev_priv->max_cdclk_freq) {
-               DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
-                             cdclk, dev_priv->max_cdclk_freq);
-               return -EINVAL;
-       }
-
-       intel_state->cdclk = intel_state->dev_cdclk = cdclk;
-       if (!intel_state->active_crtcs)
-               intel_state->dev_cdclk = broadwell_calc_cdclk(0);
-
-       return 0;
-}
+       if (val & LCPLL_CD_SOURCE_FCLK) {
+               val = I915_READ(LCPLL_CTL);
+               val &= ~LCPLL_CD_SOURCE_FCLK;
+               I915_WRITE(LCPLL_CTL, val);
 
-static void broadwell_modeset_commit_cdclk(struct drm_atomic_state *old_state)
-{
-       struct drm_device *dev = old_state->dev;
-       struct intel_atomic_state *old_intel_state =
-               to_intel_atomic_state(old_state);
-       unsigned req_cdclk = old_intel_state->dev_cdclk;
+               if (wait_for_us((I915_READ(LCPLL_CTL) &
+                                LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
+                       DRM_ERROR("Switching back to LCPLL failed\n");
+       }
 
-       broadwell_set_cdclk(dev, req_cdclk);
+       intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+       intel_update_cdclk(dev_priv);
 }
 
-static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
+/*
+ * Package states C8 and deeper are really deep PC states that can only be
+ * reached when all the devices on the system allow it, so even if the graphics
+ * device allows PC8+, it doesn't mean the system will actually get to these
+ * states. Our driver only allows PC8+ when going into runtime PM.
+ *
+ * The requirements for PC8+ are that all the outputs are disabled, the power
+ * well is disabled and most interrupts are disabled, and these are also
+ * requirements for runtime PM. When these conditions are met, we manually do
+ * the other conditions: disable the interrupts, clocks and switch LCPLL refclk
+ * to Fclk. If we're in PC8+ and we get an non-hotplug interrupt, we can hard
+ * hang the machine.
+ *
+ * When we really reach PC8 or deeper states (not just when we allow it) we lose
+ * the state of some registers, so when we come back from PC8+ we need to
+ * restore this state. We don't get into PC8+ if we're not in RC6, so we don't
+ * need to take care of the registers kept by RC6. Notice that this happens even
+ * if we don't put the device in PCI D3 state (which is what currently happens
+ * because of the runtime PM support).
+ *
+ * For more, read "Display Sequences for Package C8" on the hardware
+ * documentation.
+ */
+void hsw_enable_pc8(struct drm_i915_private *dev_priv)
 {
-       struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-       struct drm_i915_private *dev_priv = to_i915(state->dev);
-       const int max_pixclk = ilk_max_pixel_rate(state);
-       int vco = intel_state->cdclk_pll_vco;
-       int cdclk;
+       uint32_t val;
 
-       /*
-        * FIXME should also account for plane ratio
-        * once 64bpp pixel formats are supported.
-        */
-       cdclk = skl_calc_cdclk(max_pixclk, vco);
+       DRM_DEBUG_KMS("Enabling package C8+\n");
 
-       /*
-        * FIXME move the cdclk caclulation to
-        * compute_config() so we can fail gracegully.
-        */
-       if (cdclk > dev_priv->max_cdclk_freq) {
-               DRM_ERROR("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
-                         cdclk, dev_priv->max_cdclk_freq);
-               cdclk = dev_priv->max_cdclk_freq;
+       if (HAS_PCH_LPT_LP(dev_priv)) {
+               val = I915_READ(SOUTH_DSPCLK_GATE_D);
+               val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
+               I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
        }
 
-       intel_state->cdclk = intel_state->dev_cdclk = cdclk;
-       if (!intel_state->active_crtcs)
-               intel_state->dev_cdclk = skl_calc_cdclk(0, vco);
-
-       return 0;
+       lpt_disable_clkout_dp(dev_priv);
+       hsw_disable_lcpll(dev_priv, true, true);
 }
 
-static void skl_modeset_commit_cdclk(struct drm_atomic_state *old_state)
+void hsw_disable_pc8(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = to_i915(old_state->dev);
-       struct intel_atomic_state *intel_state = to_intel_atomic_state(old_state);
-       unsigned int req_cdclk = intel_state->dev_cdclk;
-       unsigned int req_vco = intel_state->cdclk_pll_vco;
+       uint32_t val;
+
+       DRM_DEBUG_KMS("Disabling package C8+\n");
+
+       hsw_restore_lcpll(dev_priv);
+       lpt_init_pch_refclk(dev_priv);
 
-       skl_set_cdclk(dev_priv, req_cdclk, req_vco);
+       if (HAS_PCH_LPT_LP(dev_priv)) {
+               val = I915_READ(SOUTH_DSPCLK_GATE_D);
+               val |= PCH_LP_PARTITION_LEVEL_DISABLE;
+               I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
+       }
 }
 
 static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
@@ -10565,7 +8949,7 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
 
 static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
                                     struct intel_crtc_state *pipe_config,
-                                    unsigned long *power_domain_mask)
+                                    u64 *power_domain_mask)
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -10607,7 +8991,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
        power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
-       *power_domain_mask |= BIT(power_domain);
+       *power_domain_mask |= BIT_ULL(power_domain);
 
        tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
 
@@ -10616,7 +9000,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
 
 static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
                                         struct intel_crtc_state *pipe_config,
-                                        unsigned long *power_domain_mask)
+                                        u64 *power_domain_mask)
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -10634,7 +9018,7 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
                power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
                if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                        continue;
-               *power_domain_mask |= BIT(power_domain);
+               *power_domain_mask |= BIT_ULL(power_domain);
 
                /*
                 * The PLL needs to be enabled with a valid divider
@@ -10674,7 +9058,7 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 
        port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
 
-       if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+       if (IS_GEN9_BC(dev_priv))
                skylake_get_ddi_pll(dev_priv, port, pipe_config);
        else if (IS_GEN9_LP(dev_priv))
                bxt_get_ddi_pll(dev_priv, port, pipe_config);
@@ -10709,13 +9093,13 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum intel_display_power_domain power_domain;
-       unsigned long power_domain_mask;
+       u64 power_domain_mask;
        bool active;
 
        power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
-       power_domain_mask = BIT(power_domain);
+       power_domain_mask = BIT_ULL(power_domain);
 
        pipe_config->shared_dpll = NULL;
 
@@ -10749,7 +9133,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 
        power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
        if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
-               power_domain_mask |= BIT(power_domain);
+               power_domain_mask |= BIT_ULL(power_domain);
                if (INTEL_GEN(dev_priv) >= 9)
                        skylake_get_pfit_config(crtc, pipe_config);
                else
@@ -10972,9 +9356,8 @@ static struct drm_display_mode load_detect_mode = {
 };
 
 struct drm_framebuffer *
-__intel_framebuffer_create(struct drm_device *dev,
-                          struct drm_mode_fb_cmd2 *mode_cmd,
-                          struct drm_i915_gem_object *obj)
+intel_framebuffer_create(struct drm_i915_gem_object *obj,
+                        struct drm_mode_fb_cmd2 *mode_cmd)
 {
        struct intel_framebuffer *intel_fb;
        int ret;
@@ -10983,7 +9366,7 @@ __intel_framebuffer_create(struct drm_device *dev,
        if (!intel_fb)
                return ERR_PTR(-ENOMEM);
 
-       ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
+       ret = intel_framebuffer_init(intel_fb, obj, mode_cmd);
        if (ret)
                goto err;
 
@@ -10994,23 +9377,6 @@ err:
        return ERR_PTR(ret);
 }
 
-static struct drm_framebuffer *
-intel_framebuffer_create(struct drm_device *dev,
-                        struct drm_mode_fb_cmd2 *mode_cmd,
-                        struct drm_i915_gem_object *obj)
-{
-       struct drm_framebuffer *fb;
-       int ret;
-
-       ret = i915_mutex_lock_interruptible(dev);
-       if (ret)
-               return ERR_PTR(ret);
-       fb = __intel_framebuffer_create(dev, mode_cmd, obj);
-       mutex_unlock(&dev->struct_mutex);
-
-       return fb;
-}
-
 static u32
 intel_framebuffer_pitch_for_width(int width, int bpp)
 {
@@ -11045,7 +9411,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
                                                                bpp);
        mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
 
-       fb = intel_framebuffer_create(dev, &mode_cmd, obj);
+       fb = intel_framebuffer_create(obj, &mode_cmd);
        if (IS_ERR(fb))
                i915_gem_object_put(obj);
 
@@ -11731,14 +10097,12 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
 {
-       struct intel_ring *ring = req->ring;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       u32 flip_mask;
-       int ret;
+       u32 flip_mask, *cs;
 
-       ret = intel_ring_begin(req, 6);
-       if (ret)
-               return ret;
+       cs = intel_ring_begin(req, 6);
+       if (IS_ERR(cs))
+               return PTR_ERR(cs);
 
        /* Can't queue multiple flips, so wait for the previous
         * one to finish before executing the next.
@@ -11747,13 +10111,12 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
                flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
        else
                flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
-       intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
-       intel_ring_emit(ring, MI_NOOP);
-       intel_ring_emit(ring, MI_DISPLAY_FLIP |
-                       MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0]);
-       intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset);
-       intel_ring_emit(ring, 0); /* aux display base address, unused */
+       *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
+       *cs++ = MI_NOOP;
+       *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
+       *cs++ = fb->pitches[0];
+       *cs++ = intel_crtc->flip_work->gtt_offset;
+       *cs++ = 0; /* aux display base address, unused */
 
        return 0;
 }
@@ -11765,26 +10128,23 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
 {
-       struct intel_ring *ring = req->ring;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       u32 flip_mask;
-       int ret;
+       u32 flip_mask, *cs;
 
-       ret = intel_ring_begin(req, 6);
-       if (ret)
-               return ret;
+       cs = intel_ring_begin(req, 6);
+       if (IS_ERR(cs))
+               return PTR_ERR(cs);
 
        if (intel_crtc->plane)
                flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
        else
                flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
-       intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
-       intel_ring_emit(ring, MI_NOOP);
-       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 |
-                       MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0]);
-       intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset);
-       intel_ring_emit(ring, MI_NOOP);
+       *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
+       *cs++ = MI_NOOP;
+       *cs++ = MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
+       *cs++ = fb->pitches[0];
+       *cs++ = intel_crtc->flip_work->gtt_offset;
+       *cs++ = MI_NOOP;
 
        return 0;
 }
@@ -11796,25 +10156,22 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
 {
-       struct intel_ring *ring = req->ring;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       uint32_t pf, pipesrc;
-       int ret;
+       u32 pf, pipesrc, *cs;
 
-       ret = intel_ring_begin(req, 4);
-       if (ret)
-               return ret;
+       cs = intel_ring_begin(req, 4);
+       if (IS_ERR(cs))
+               return PTR_ERR(cs);
 
        /* i965+ uses the linear or tiled offsets from the
         * Display Registers (which do not change across a page-flip)
         * so we need only reprogram the base address.
         */
-       intel_ring_emit(ring, MI_DISPLAY_FLIP |
-                       MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0]);
-       intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset |
-                       intel_fb_modifier_to_tiling(fb->modifier));
+       *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
+       *cs++ = fb->pitches[0];
+       *cs++ = intel_crtc->flip_work->gtt_offset |
+               intel_fb_modifier_to_tiling(fb->modifier);
 
        /* XXX Enabling the panel-fitter across page-flip is so far
         * untested on non-native modes, so ignore it for now.
@@ -11822,7 +10179,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
         */
        pf = 0;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
-       intel_ring_emit(ring, pf | pipesrc);
+       *cs++ = pf | pipesrc;
 
        return 0;
 }
@@ -11834,21 +10191,17 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
                                 struct drm_i915_gem_request *req,
                                 uint32_t flags)
 {
-       struct intel_ring *ring = req->ring;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       uint32_t pf, pipesrc;
-       int ret;
+       u32 pf, pipesrc, *cs;
 
-       ret = intel_ring_begin(req, 4);
-       if (ret)
-               return ret;
+       cs = intel_ring_begin(req, 4);
+       if (IS_ERR(cs))
+               return PTR_ERR(cs);
 
-       intel_ring_emit(ring, MI_DISPLAY_FLIP |
-                       MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       intel_ring_emit(ring, fb->pitches[0] |
-                       intel_fb_modifier_to_tiling(fb->modifier));
-       intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset);
+       *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
+       *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
+       *cs++ = intel_crtc->flip_work->gtt_offset;
 
        /* Contrary to the suggestions in the documentation,
         * "Enable Panel Fitter" does not seem to be required when page
@@ -11858,7 +10211,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
         */
        pf = 0;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
-       intel_ring_emit(ring, pf | pipesrc);
+       *cs++ = pf | pipesrc;
 
        return 0;
 }
@@ -11871,9 +10224,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
                                 uint32_t flags)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_ring *ring = req->ring;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       uint32_t plane_bit = 0;
+       u32 *cs, plane_bit = 0;
        int len, ret;
 
        switch (intel_crtc->plane) {
@@ -11917,9 +10269,9 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
        if (ret)
                return ret;
 
-       ret = intel_ring_begin(req, len);
-       if (ret)
-               return ret;
+       cs = intel_ring_begin(req, len);
+       if (IS_ERR(cs))
+               return PTR_ERR(cs);
 
        /* Unmask the flip-done completion message. Note that the bspec says that
         * we should do this for both the BCS and RCS, and that we must not unmask
@@ -11931,31 +10283,28 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
         * to zero does lead to lockups within MI_DISPLAY_FLIP.
         */
        if (req->engine->id == RCS) {
-               intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
-               intel_ring_emit_reg(ring, DERRMR);
-               intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
-                                         DERRMR_PIPEB_PRI_FLIP_DONE |
-                                         DERRMR_PIPEC_PRI_FLIP_DONE));
+               *cs++ = MI_LOAD_REGISTER_IMM(1);
+               *cs++ = i915_mmio_reg_offset(DERRMR);
+               *cs++ = ~(DERRMR_PIPEA_PRI_FLIP_DONE |
+                         DERRMR_PIPEB_PRI_FLIP_DONE |
+                         DERRMR_PIPEC_PRI_FLIP_DONE);
                if (IS_GEN8(dev_priv))
-                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8 |
-                                             MI_SRM_LRM_GLOBAL_GTT);
+                       *cs++ = MI_STORE_REGISTER_MEM_GEN8 |
+                               MI_SRM_LRM_GLOBAL_GTT;
                else
-                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM |
-                                             MI_SRM_LRM_GLOBAL_GTT);
-               intel_ring_emit_reg(ring, DERRMR);
-               intel_ring_emit(ring,
-                               i915_ggtt_offset(req->engine->scratch) + 256);
+                       *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
+               *cs++ = i915_mmio_reg_offset(DERRMR);
+               *cs++ = i915_ggtt_offset(req->engine->scratch) + 256;
                if (IS_GEN8(dev_priv)) {
-                       intel_ring_emit(ring, 0);
-                       intel_ring_emit(ring, MI_NOOP);
+                       *cs++ = 0;
+                       *cs++ = MI_NOOP;
                }
        }
 
-       intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
-       intel_ring_emit(ring, fb->pitches[0] |
-                       intel_fb_modifier_to_tiling(fb->modifier));
-       intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset);
-       intel_ring_emit(ring, (MI_NOOP));
+       *cs++ = MI_DISPLAY_FLIP_I915 | plane_bit;
+       *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
+       *cs++ = intel_crtc->flip_work->gtt_offset;
+       *cs++ = MI_NOOP;
 
        return 0;
 }
@@ -12147,6 +10496,7 @@ void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
        spin_unlock(&dev->event_lock);
 }
 
+__maybe_unused
 static int intel_crtc_page_flip(struct drm_crtc *crtc,
                                struct drm_framebuffer *fb,
                                struct drm_pending_vblank_event *event,
@@ -12441,11 +10791,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
        struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
        struct drm_crtc *crtc = crtc_state->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct drm_plane *plane = plane_state->plane;
+       struct intel_plane *plane = to_intel_plane(plane_state->plane);
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane_state *old_plane_state =
-               to_intel_plane_state(plane->state);
+               to_intel_plane_state(plane->base.state);
        bool mode_changed = needs_modeset(crtc_state);
        bool was_crtc_enabled = crtc->state->active;
        bool is_crtc_enabled = crtc_state->active;
@@ -12453,7 +10803,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
        struct drm_framebuffer *fb = plane_state->fb;
        int ret;
 
-       if (INTEL_GEN(dev_priv) >= 9 && plane->type != DRM_PLANE_TYPE_CURSOR) {
+       if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
                ret = skl_update_scaler_plane(
                        to_intel_crtc_state(crtc_state),
                        to_intel_plane_state(plane_state));
@@ -12477,8 +10827,10 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
         * per-plane wm computation to the .check_plane() hook, and
         * only combine the results from all planes in the current place?
         */
-       if (!is_crtc_enabled)
+       if (!is_crtc_enabled) {
                plane_state->visible = visible = false;
+               to_intel_crtc_state(crtc_state)->active_planes &= ~BIT(plane->id);
+       }
 
        if (!was_visible && !visible)
                return 0;
@@ -12490,41 +10842,39 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
        turn_on = visible && (!was_visible || mode_changed);
 
        DRM_DEBUG_ATOMIC("[CRTC:%d:%s] has [PLANE:%d:%s] with fb %i\n",
-                        intel_crtc->base.base.id,
-                        intel_crtc->base.name,
-                        plane->base.id, plane->name,
+                        intel_crtc->base.base.id, intel_crtc->base.name,
+                        plane->base.base.id, plane->base.name,
                         fb ? fb->base.id : -1);
 
        DRM_DEBUG_ATOMIC("[PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
-                        plane->base.id, plane->name,
+                        plane->base.base.id, plane->base.name,
                         was_visible, visible,
                         turn_off, turn_on, mode_changed);
 
        if (turn_on) {
-               pipe_config->update_wm_pre = true;
+               if (INTEL_GEN(dev_priv) < 5)
+                       pipe_config->update_wm_pre = true;
 
                /* must disable cxsr around plane enable/disable */
-               if (plane->type != DRM_PLANE_TYPE_CURSOR)
+               if (plane->id != PLANE_CURSOR)
                        pipe_config->disable_cxsr = true;
        } else if (turn_off) {
-               pipe_config->update_wm_post = true;
+               if (INTEL_GEN(dev_priv) < 5)
+                       pipe_config->update_wm_post = true;
 
                /* must disable cxsr around plane enable/disable */
-               if (plane->type != DRM_PLANE_TYPE_CURSOR)
+               if (plane->id != PLANE_CURSOR)
                        pipe_config->disable_cxsr = true;
-       } else if (intel_wm_need_update(plane, plane_state)) {
-               /* FIXME bollocks */
-               pipe_config->update_wm_pre = true;
-               pipe_config->update_wm_post = true;
+       } else if (intel_wm_need_update(&plane->base, plane_state)) {
+               if (INTEL_GEN(dev_priv) < 5) {
+                       /* FIXME bollocks */
+                       pipe_config->update_wm_pre = true;
+                       pipe_config->update_wm_post = true;
+               }
        }
 
-       /* Pre-gen9 platforms need two-step watermark updates */
-       if ((pipe_config->update_wm_pre || pipe_config->update_wm_post) &&
-           INTEL_GEN(dev_priv) < 9 && dev_priv->display.optimize_watermarks)
-               to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true;
-
        if (visible || was_visible)
-               pipe_config->fb_bits |= to_intel_plane(plane)->frontbuffer_bit;
+               pipe_config->fb_bits |= plane->frontbuffer_bit;
 
        /*
         * WaCxSRDisabledForSpriteScaling:ivb
@@ -12532,7 +10882,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
         * cstate->update_wm was already set above, so this flag will
         * take effect when we commit and program watermarks.
         */
-       if (plane->type == DRM_PLANE_TYPE_OVERLAY && IS_IVYBRIDGE(dev_priv) &&
+       if (plane->id == PLANE_SPRITE0 && IS_IVYBRIDGE(dev_priv) &&
            needs_scaling(to_intel_plane_state(plane_state)) &&
            !needs_scaling(old_plane_state))
                pipe_config->disable_lp_wm = true;
@@ -12642,7 +10992,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
                        ret = skl_update_scaler_crtc(pipe_config);
 
                if (!ret)
-                       ret = intel_atomic_setup_scalers(dev, intel_crtc,
+                       ret = intel_atomic_setup_scalers(dev_priv, intel_crtc,
                                                         pipe_config);
        }
 
@@ -12800,9 +11150,10 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
        DRM_DEBUG_KMS("adjusted mode:\n");
        drm_mode_debug_printmodeline(&pipe_config->base.adjusted_mode);
        intel_dump_crtc_timings(&pipe_config->base.adjusted_mode);
-       DRM_DEBUG_KMS("port clock: %d, pipe src size: %dx%d\n",
+       DRM_DEBUG_KMS("port clock: %d, pipe src size: %dx%d, pixel rate %d\n",
                      pipe_config->port_clock,
-                     pipe_config->pipe_src_w, pipe_config->pipe_src_h);
+                     pipe_config->pipe_src_w, pipe_config->pipe_src_h,
+                     pipe_config->pixel_rate);
 
        if (INTEL_GEN(dev_priv) >= 9)
                DRM_DEBUG_KMS("num_scalers: %d, scaler_users: 0x%x, scaler_id: %d\n",
@@ -12920,10 +11271,13 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
 static void
 clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 {
+       struct drm_i915_private *dev_priv =
+               to_i915(crtc_state->base.crtc->dev);
        struct drm_crtc_state tmp_state;
        struct intel_crtc_scaler_state scaler_state;
        struct intel_dpll_hw_state dpll_hw_state;
        struct intel_shared_dpll *shared_dpll;
+       struct intel_crtc_wm_state wm_state;
        bool force_thru;
 
        /* FIXME: before the switch to atomic started, a new pipe_config was
@@ -12936,6 +11290,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
        shared_dpll = crtc_state->shared_dpll;
        dpll_hw_state = crtc_state->dpll_hw_state;
        force_thru = crtc_state->pch_pfit.force_thru;
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               wm_state = crtc_state->wm;
 
        memset(crtc_state, 0, sizeof *crtc_state);
 
@@ -12944,6 +11300,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
        crtc_state->shared_dpll = shared_dpll;
        crtc_state->dpll_hw_state = dpll_hw_state;
        crtc_state->pch_pfit.force_thru = force_thru;
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               crtc_state->wm = wm_state;
 }
 
 static int
@@ -13060,8 +11418,11 @@ encoder_retry:
        }
 
        /* Dithering seems to not pass-through bits correctly when it should, so
-        * only enable it on 6bpc panels. */
-       pipe_config->dither = pipe_config->pipe_bpp == 6*3;
+        * only enable it on 6bpc panels and when its not a compliance
+        * test requesting 6bpc video pattern.
+        */
+       pipe_config->dither = (pipe_config->pipe_bpp == 6*3) &&
+               !pipe_config->dither_force_disable;
        DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
                      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
@@ -13375,6 +11736,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
                }
 
                PIPE_CONF_CHECK_I(scaler_state.scaler_id);
+               PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
        }
 
        /* BDW+ don't expose a synchronous way to read the state */
@@ -13666,6 +12028,8 @@ verify_crtc_state(struct drm_crtc *crtc,
                }
        }
 
+       intel_crtc_compute_pixel_rate(pipe_config);
+
        if (!new_crtc_state->active)
                return;
 
@@ -13993,6 +12357,8 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
 
        intel_state->modeset = true;
        intel_state->active_crtcs = dev_priv->active_crtcs;
+       intel_state->cdclk.logical = dev_priv->cdclk.logical;
+       intel_state->cdclk.actual = dev_priv->cdclk.actual;
 
        for_each_crtc_in_state(state, crtc, crtc_state, i) {
                if (crtc_state->active)
@@ -14012,38 +12378,35 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
         * adjusted_mode bits in the crtc directly.
         */
        if (dev_priv->display.modeset_calc_cdclk) {
-               if (!intel_state->cdclk_pll_vco)
-                       intel_state->cdclk_pll_vco = dev_priv->cdclk_pll.vco;
-               if (!intel_state->cdclk_pll_vco)
-                       intel_state->cdclk_pll_vco = dev_priv->skl_preferred_vco_freq;
-
                ret = dev_priv->display.modeset_calc_cdclk(state);
                if (ret < 0)
                        return ret;
 
                /*
-                * Writes to dev_priv->atomic_cdclk_freq must protected by
+                * Writes to dev_priv->cdclk.logical must protected by
                 * holding all the crtc locks, even if we don't end up
                 * touching the hardware
                 */
-               if (intel_state->cdclk != dev_priv->atomic_cdclk_freq) {
+               if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical,
+                                              &intel_state->cdclk.logical)) {
                        ret = intel_lock_all_pipes(state);
                        if (ret < 0)
                                return ret;
                }
 
                /* All pipes must be switched off while we change the cdclk. */
-               if (intel_state->dev_cdclk != dev_priv->cdclk_freq ||
-                   intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco) {
+               if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual,
+                                              &intel_state->cdclk.actual)) {
                        ret = intel_modeset_all_pipes(state);
                        if (ret < 0)
                                return ret;
                }
 
-               DRM_DEBUG_KMS("New cdclk calculated to be atomic %u, actual %u\n",
-                             intel_state->cdclk, intel_state->dev_cdclk);
+               DRM_DEBUG_KMS("New cdclk calculated to be logical %u kHz, actual %u kHz\n",
+                             intel_state->cdclk.logical.cdclk,
+                             intel_state->cdclk.actual.cdclk);
        } else {
-               to_intel_atomic_state(state)->cdclk = dev_priv->atomic_cdclk_freq;
+               to_intel_atomic_state(state)->cdclk.logical = dev_priv->cdclk.logical;
        }
 
        intel_modeset_clear_plls(state);
@@ -14146,7 +12509,7 @@ static int intel_atomic_check(struct drm_device *dev,
                if (ret)
                        return ret;
        } else {
-               intel_state->cdclk = dev_priv->atomic_cdclk_freq;
+               intel_state->cdclk.logical = dev_priv->cdclk.logical;
        }
 
        ret = drm_atomic_helper_check_planes(dev, state);
@@ -14253,12 +12616,7 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
        if (crtc_state->update_wm_post)
                return true;
 
-       /*
-        * cxsr is re-enabled after vblank.
-        * This is already handled by crtc_state->update_wm_post,
-        * but added for clarity.
-        */
-       if (crtc_state->disable_cxsr)
+       if (crtc_state->wm.need_postvbl_update)
                return true;
 
        return false;
@@ -14380,6 +12738,24 @@ static void skl_update_crtcs(struct drm_atomic_state *state,
        } while (progress);
 }
 
+static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
+{
+       struct intel_atomic_state *state, *next;
+       struct llist_node *freed;
+
+       freed = llist_del_all(&dev_priv->atomic_helper.free_list);
+       llist_for_each_entry_safe(state, next, freed, freed)
+               drm_atomic_state_put(&state->base);
+}
+
+static void intel_atomic_helper_free_state_worker(struct work_struct *work)
+{
+       struct drm_i915_private *dev_priv =
+               container_of(work, typeof(*dev_priv), atomic_helper.free_work);
+
+       intel_atomic_helper_free_state(dev_priv);
+}
+
 static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 {
        struct drm_device *dev = state->dev;
@@ -14389,7 +12765,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
        struct drm_crtc *crtc;
        struct intel_crtc_state *intel_cstate;
        bool hw_check = intel_state->modeset;
-       unsigned long put_domains[I915_MAX_PIPES] = {};
+       u64 put_domains[I915_MAX_PIPES] = {};
        unsigned crtc_vblank_mask = 0;
        int i;
 
@@ -14433,12 +12809,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
                                /*
                                 * Make sure we don't call initial_watermarks
                                 * for ILK-style watermark updates.
+                                *
+                                * No clue what this is supposed to achieve.
                                 */
-                               if (dev_priv->display.atomic_update_watermarks)
+                               if (INTEL_GEN(dev_priv) >= 9)
                                        dev_priv->display.initial_watermarks(intel_state,
                                                                             to_intel_crtc_state(crtc->state));
-                               else
-                                       intel_update_watermarks(intel_crtc);
                        }
                }
        }
@@ -14450,10 +12826,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
        if (intel_state->modeset) {
                drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
 
-               if (dev_priv->display.modeset_commit_cdclk &&
-                   (intel_state->dev_cdclk != dev_priv->cdclk_freq ||
-                    intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco))
-                       dev_priv->display.modeset_commit_cdclk(state);
+               intel_set_cdclk(dev_priv, &dev_priv->cdclk.actual);
 
                /*
                 * SKL workaround: bspec recommends we disable the SAGV when we
@@ -14546,6 +12919,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
         * can happen also when the device is completely off.
         */
        intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
+
+       intel_atomic_helper_free_state(dev_priv);
 }
 
 static void intel_atomic_commit_work(struct work_struct *work)
@@ -14615,6 +12990,17 @@ static int intel_atomic_commit(struct drm_device *dev,
        struct drm_i915_private *dev_priv = to_i915(dev);
        int ret = 0;
 
+       /*
+        * The intel_legacy_cursor_update() fast path takes care
+        * of avoiding the vblank waits for simple cursor
+        * movement and flips. For cursor on/off and size changes,
+        * we want to perform the vblank waits so that watermark
+        * updates happen during the correct frames. Gen9+ have
+        * double buffered watermarks and so shouldn't need this.
+        */
+       if (INTEL_GEN(dev_priv) < 9)
+               state->legacy_cursor_update = false;
+
        ret = drm_atomic_helper_setup_commit(state, nonblock);
        if (ret)
                return ret;
@@ -14639,7 +13025,8 @@ static int intel_atomic_commit(struct drm_device *dev,
                memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
                       sizeof(intel_state->min_pixclk));
                dev_priv->active_crtcs = intel_state->active_crtcs;
-               dev_priv->atomic_cdclk_freq = intel_state->cdclk;
+               dev_priv->cdclk.logical = intel_state->cdclk.logical;
+               dev_priv->cdclk.actual = intel_state->cdclk.actual;
        }
 
        drm_atomic_state_get(state);
@@ -14739,7 +13126,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
        .set_config = drm_atomic_helper_set_config,
        .set_property = drm_atomic_helper_crtc_set_property,
        .destroy = intel_crtc_destroy,
-       .page_flip = intel_crtc_page_flip,
+       .page_flip = drm_atomic_helper_page_flip,
        .atomic_duplicate_state = intel_crtc_duplicate_state,
        .atomic_destroy_state = intel_crtc_destroy_state,
        .set_crc_source = intel_crtc_set_crc_source,
@@ -14771,6 +13158,29 @@ intel_prepare_plane_fb(struct drm_plane *plane,
        struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
        int ret;
 
+       if (obj) {
+               if (plane->type == DRM_PLANE_TYPE_CURSOR &&
+                   INTEL_INFO(dev_priv)->cursor_needs_physical) {
+                       const int align = IS_I830(dev_priv) ? 16 * 1024 : 256;
+
+                       ret = i915_gem_object_attach_phys(obj, align);
+                       if (ret) {
+                               DRM_DEBUG_KMS("failed to attach phys object\n");
+                               return ret;
+                       }
+               } else {
+                       struct i915_vma *vma;
+
+                       vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
+                       if (IS_ERR(vma)) {
+                               DRM_DEBUG_KMS("failed to pin object\n");
+                               return PTR_ERR(vma);
+                       }
+
+                       to_intel_plane_state(new_state)->vma = vma;
+               }
+       }
+
        if (!obj && !old_obj)
                return 0;
 
@@ -14823,26 +13233,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
                i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
        }
 
-       if (plane->type == DRM_PLANE_TYPE_CURSOR &&
-           INTEL_INFO(dev_priv)->cursor_needs_physical) {
-               int align = IS_I830(dev_priv) ? 16 * 1024 : 256;
-               ret = i915_gem_object_attach_phys(obj, align);
-               if (ret) {
-                       DRM_DEBUG_KMS("failed to attach phys object\n");
-                       return ret;
-               }
-       } else {
-               struct i915_vma *vma;
-
-               vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
-               if (IS_ERR(vma)) {
-                       DRM_DEBUG_KMS("failed to pin object\n");
-                       return PTR_ERR(vma);
-               }
-
-               to_intel_plane_state(new_state)->vma = vma;
-       }
-
        return 0;
 }
 
@@ -14870,16 +13260,22 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 int
 skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state)
 {
+       struct drm_i915_private *dev_priv;
        int max_scale;
-       int crtc_clock, cdclk;
+       int crtc_clock, max_dotclk;
 
        if (!intel_crtc || !crtc_state->base.enable)
                return DRM_PLANE_HELPER_NO_SCALING;
 
+       dev_priv = to_i915(intel_crtc->base.dev);
+
        crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
-       cdclk = to_intel_atomic_state(crtc_state->base.state)->cdclk;
+       max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk;
 
-       if (WARN_ON_ONCE(!crtc_clock || cdclk < crtc_clock))
+       if (IS_GEMINILAKE(dev_priv))
+               max_dotclk *= 2;
+
+       if (WARN_ON_ONCE(!crtc_clock || max_dotclk < crtc_clock))
                return DRM_PLANE_HELPER_NO_SCALING;
 
        /*
@@ -14888,7 +13284,8 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state
         *            or
         *    cdclk/crtc_clock
         */
-       max_scale = min((1 << 16) * 3 - 1, (1 << 8) * ((cdclk << 8) / crtc_clock));
+       max_scale = min((1 << 16) * 3 - 1,
+                       (1 << 8) * ((max_dotclk << 8) / crtc_clock));
 
        return max_scale;
 }
@@ -15038,8 +13435,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
            old_plane_state->src_h != src_h ||
            old_plane_state->crtc_w != crtc_w ||
            old_plane_state->crtc_h != crtc_h ||
-           !old_plane_state->visible ||
-           old_plane_state->fb->modifier != fb->modifier)
+           !old_plane_state->fb != !fb)
                goto slow;
 
        new_plane_state = intel_plane_duplicate_state(plane);
@@ -15062,10 +13458,6 @@ intel_legacy_cursor_update(struct drm_plane *plane,
        if (ret)
                goto out_free;
 
-       /* Visibility changed, must take slowpath. */
-       if (!new_plane_state->visible)
-               goto slow_free;
-
        ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
        if (ret)
                goto out_free;
@@ -15105,9 +13497,15 @@ intel_legacy_cursor_update(struct drm_plane *plane,
        new_plane_state->fb = old_fb;
        to_intel_plane_state(new_plane_state)->vma = old_vma;
 
-       intel_plane->update_plane(plane,
-                                 to_intel_crtc_state(crtc->state),
-                                 to_intel_plane_state(plane->state));
+       if (plane->state->visible) {
+               trace_intel_update_plane(plane, to_intel_crtc(crtc));
+               intel_plane->update_plane(plane,
+                                         to_intel_crtc_state(crtc->state),
+                                         to_intel_plane_state(plane->state));
+       } else {
+               trace_intel_disable_plane(plane, to_intel_crtc(crtc));
+               intel_plane->disable_plane(plane, crtc);
+       }
 
        intel_cleanup_plane_fb(plane, new_plane_state);
 
@@ -15117,8 +13515,6 @@ out_free:
        intel_plane_destroy_state(plane, new_plane_state);
        return ret;
 
-slow_free:
-       intel_plane_destroy_state(plane, new_plane_state);
 slow:
        return drm_atomic_helper_update_plane(plane, crtc, fb,
                                              crtc_x, crtc_y, crtc_w, crtc_h,
@@ -15492,8 +13888,6 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
        intel_crtc->cursor_cntl = ~0;
        intel_crtc->cursor_size = ~0;
 
-       intel_crtc->wm.cxsr_allowed = true;
-
        /* initialize shared scalers */
        intel_crtc_init_scalers(intel_crtc, crtc_state);
 
@@ -15681,7 +14075,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
                 */
                found = I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
                /* WaIgnoreDDIAStrap: skl */
-               if (found || IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+               if (found || IS_GEN9_BC(dev_priv))
                        intel_ddi_init(dev_priv, PORT_A);
 
                /* DDI B, C and D detection is indicated by the SFUSE_STRAP
@@ -15697,7 +14091,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
                /*
                 * On SKL we don't have a way to detect DDI-E so we rely on VBT.
                 */
-               if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) &&
+               if (IS_GEN9_BC(dev_priv) &&
                    (dev_priv->vbt.ddi_port_info[PORT_E].supports_dp ||
                     dev_priv->vbt.ddi_port_info[PORT_E].supports_dvi ||
                     dev_priv->vbt.ddi_port_info[PORT_E].supports_hdmi))
@@ -15830,14 +14224,16 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
 
 static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
-       struct drm_device *dev = fb->dev;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
 
        drm_framebuffer_cleanup(fb);
-       mutex_lock(&dev->struct_mutex);
+
+       i915_gem_object_lock(intel_fb->obj);
        WARN_ON(!intel_fb->obj->framebuffer_references--);
+       i915_gem_object_unlock(intel_fb->obj);
+
        i915_gem_object_put(intel_fb->obj);
-       mutex_unlock(&dev->struct_mutex);
+
        kfree(intel_fb);
 }
 
@@ -15862,15 +14258,10 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
                                        struct drm_clip_rect *clips,
                                        unsigned num_clips)
 {
-       struct drm_device *dev = fb->dev;
-       struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj = intel_fb->obj;
+       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 
-       mutex_lock(&dev->struct_mutex);
-       if (obj->pin_display && obj->cache_dirty)
-               i915_gem_clflush_object(obj, true);
-       intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
-       mutex_unlock(&dev->struct_mutex);
+       i915_gem_object_flush_if_display(obj);
+       intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
 
        return 0;
 }
@@ -15885,7 +14276,7 @@ static
 u32 intel_fb_pitch_limit(struct drm_i915_private *dev_priv,
                         uint64_t fb_modifier, uint32_t pixel_format)
 {
-       u32 gen = INTEL_INFO(dev_priv)->gen;
+       u32 gen = INTEL_GEN(dev_priv);
 
        if (gen >= 9) {
                int cpp = drm_format_plane_cpp(pixel_format, 0);
@@ -15894,8 +14285,7 @@ u32 intel_fb_pitch_limit(struct drm_i915_private *dev_priv,
                 *  pixels and 32K bytes."
                 */
                return min(8192 * cpp, 32768);
-       } else if (gen >= 5 && !IS_VALLEYVIEW(dev_priv) &&
-                  !IS_CHERRYVIEW(dev_priv)) {
+       } else if (gen >= 5 && !HAS_GMCH_DISPLAY(dev_priv)) {
                return 32*1024;
        } else if (gen >= 4) {
                if (fb_modifier == I915_FORMAT_MOD_X_TILED)
@@ -15913,18 +14303,21 @@ u32 intel_fb_pitch_limit(struct drm_i915_private *dev_priv,
        }
 }
 
-static int intel_framebuffer_init(struct drm_device *dev,
-                                 struct intel_framebuffer *intel_fb,
-                                 struct drm_mode_fb_cmd2 *mode_cmd,
-                                 struct drm_i915_gem_object *obj)
+static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
+                                 struct drm_i915_gem_object *obj,
+                                 struct drm_mode_fb_cmd2 *mode_cmd)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       unsigned int tiling = i915_gem_object_get_tiling(obj);
-       int ret;
-       u32 pitch_limit, stride_alignment;
+       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
        struct drm_format_name_buf format_name;
+       u32 pitch_limit, stride_alignment;
+       unsigned int tiling, stride;
+       int ret = -EINVAL;
 
-       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+       i915_gem_object_lock(obj);
+       obj->framebuffer_references++;
+       tiling = i915_gem_object_get_tiling(obj);
+       stride = i915_gem_object_get_stride(obj);
+       i915_gem_object_unlock(obj);
 
        if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
                /*
@@ -15934,14 +14327,14 @@ static int intel_framebuffer_init(struct drm_device *dev,
                if (tiling != I915_TILING_NONE &&
                    tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
                        DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
-                       return -EINVAL;
+                       goto err;
                }
        } else {
                if (tiling == I915_TILING_X) {
                        mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
                } else if (tiling == I915_TILING_Y) {
                        DRM_DEBUG("No Y tiling for legacy addfb\n");
-                       return -EINVAL;
+                       goto err;
                }
        }
 
@@ -15952,7 +14345,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
                if (INTEL_GEN(dev_priv) < 9) {
                        DRM_DEBUG("Unsupported tiling 0x%llx!\n",
                                  mode_cmd->modifier[0]);
-                       return -EINVAL;
+                       goto err;
                }
        case DRM_FORMAT_MOD_NONE:
        case I915_FORMAT_MOD_X_TILED:
@@ -15960,7 +14353,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
        default:
                DRM_DEBUG("Unsupported fb modifier 0x%llx!\n",
                          mode_cmd->modifier[0]);
-               return -EINVAL;
+               goto err;
        }
 
        /*
@@ -15970,7 +14363,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
        if (INTEL_INFO(dev_priv)->gen < 4 &&
            tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
                DRM_DEBUG("tiling_mode must match fb modifier exactly on gen2/3\n");
-               return -EINVAL;
+               goto err;
        }
 
        stride_alignment = intel_fb_stride_alignment(dev_priv,
@@ -15979,7 +14372,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
        if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
                DRM_DEBUG("pitch (%d) must be at least %u byte aligned\n",
                          mode_cmd->pitches[0], stride_alignment);
-               return -EINVAL;
+               goto err;
        }
 
        pitch_limit = intel_fb_pitch_limit(dev_priv, mode_cmd->modifier[0],
@@ -15989,19 +14382,17 @@ static int intel_framebuffer_init(struct drm_device *dev,
                          mode_cmd->modifier[0] != DRM_FORMAT_MOD_NONE ?
                          "tiled" : "linear",
                          mode_cmd->pitches[0], pitch_limit);
-               return -EINVAL;
+               goto err;
        }
 
        /*
         * If there's a fence, enforce that
         * the fb pitch and fence stride match.
         */
-       if (tiling != I915_TILING_NONE &&
-           mode_cmd->pitches[0] != i915_gem_object_get_stride(obj)) {
+       if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] !=  stride) {
                DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
-                         mode_cmd->pitches[0],
-                         i915_gem_object_get_stride(obj));
-               return -EINVAL;
+                         mode_cmd->pitches[0], stride);
+               goto err;
        }
 
        /* Reject formats not supported by any plane early. */
@@ -16015,7 +14406,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
                if (INTEL_GEN(dev_priv) > 3) {
                        DRM_DEBUG("unsupported pixel format: %s\n",
                                  drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       return -EINVAL;
+                       goto err;
                }
                break;
        case DRM_FORMAT_ABGR8888:
@@ -16023,7 +14414,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
                    INTEL_GEN(dev_priv) < 9) {
                        DRM_DEBUG("unsupported pixel format: %s\n",
                                  drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       return -EINVAL;
+                       goto err;
                }
                break;
        case DRM_FORMAT_XBGR8888:
@@ -16032,14 +14423,14 @@ static int intel_framebuffer_init(struct drm_device *dev,
                if (INTEL_GEN(dev_priv) < 4) {
                        DRM_DEBUG("unsupported pixel format: %s\n",
                                  drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       return -EINVAL;
+                       goto err;
                }
                break;
        case DRM_FORMAT_ABGR2101010:
                if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
                        DRM_DEBUG("unsupported pixel format: %s\n",
                                  drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       return -EINVAL;
+                       goto err;
                }
                break;
        case DRM_FORMAT_YUYV:
@@ -16049,35 +14440,42 @@ static int intel_framebuffer_init(struct drm_device *dev,
                if (INTEL_GEN(dev_priv) < 5) {
                        DRM_DEBUG("unsupported pixel format: %s\n",
                                  drm_get_format_name(mode_cmd->pixel_format, &format_name));
-                       return -EINVAL;
+                       goto err;
                }
                break;
        default:
                DRM_DEBUG("unsupported pixel format: %s\n",
                          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-               return -EINVAL;
+               goto err;
        }
 
        /* FIXME need to adjust LINOFF/TILEOFF accordingly. */
        if (mode_cmd->offsets[0] != 0)
-               return -EINVAL;
+               goto err;
 
-       drm_helper_mode_fill_fb_struct(dev, &intel_fb->base, mode_cmd);
+       drm_helper_mode_fill_fb_struct(&dev_priv->drm,
+                                      &intel_fb->base, mode_cmd);
        intel_fb->obj = obj;
 
        ret = intel_fill_fb_info(dev_priv, &intel_fb->base);
        if (ret)
-               return ret;
+               goto err;
 
-       ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
+       ret = drm_framebuffer_init(obj->base.dev,
+                                  &intel_fb->base,
+                                  &intel_fb_funcs);
        if (ret) {
                DRM_ERROR("framebuffer init failed %d\n", ret);
-               return ret;
+               goto err;
        }
 
-       intel_fb->obj->framebuffer_references++;
-
        return 0;
+
+err:
+       i915_gem_object_lock(obj);
+       obj->framebuffer_references--;
+       i915_gem_object_unlock(obj);
+       return ret;
 }
 
 static struct drm_framebuffer *
@@ -16093,7 +14491,7 @@ intel_user_framebuffer_create(struct drm_device *dev,
        if (!obj)
                return ERR_PTR(-ENOENT);
 
-       fb = intel_framebuffer_create(dev, &mode_cmd, obj);
+       fb = intel_framebuffer_create(obj, &mode_cmd);
        if (IS_ERR(fb))
                i915_gem_object_put(obj);
 
@@ -16127,6 +14525,8 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
  */
 void intel_init_display_hooks(struct drm_i915_private *dev_priv)
 {
+       intel_init_cdclk_hooks(dev_priv);
+
        if (INTEL_INFO(dev_priv)->gen >= 9) {
                dev_priv->display.get_pipe_config = haswell_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
@@ -16195,62 +14595,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
        }
 
-       /* Returns the core display clock speed */
-       if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       skylake_get_display_clock_speed;
-       else if (IS_GEN9_LP(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       broxton_get_display_clock_speed;
-       else if (IS_BROADWELL(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       broadwell_get_display_clock_speed;
-       else if (IS_HASWELL(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       haswell_get_display_clock_speed;
-       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       valleyview_get_display_clock_speed;
-       else if (IS_GEN5(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       ilk_get_display_clock_speed;
-       else if (IS_I945G(dev_priv) || IS_I965G(dev_priv) ||
-                IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       i945_get_display_clock_speed;
-       else if (IS_GM45(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       gm45_get_display_clock_speed;
-       else if (IS_I965GM(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       i965gm_get_display_clock_speed;
-       else if (IS_PINEVIEW(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       pnv_get_display_clock_speed;
-       else if (IS_G33(dev_priv) || IS_G4X(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       g33_get_display_clock_speed;
-       else if (IS_I915G(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       i915_get_display_clock_speed;
-       else if (IS_I945GM(dev_priv) || IS_I845G(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       i9xx_misc_get_display_clock_speed;
-       else if (IS_I915GM(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       i915gm_get_display_clock_speed;
-       else if (IS_I865G(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       i865_get_display_clock_speed;
-       else if (IS_I85X(dev_priv))
-               dev_priv->display.get_display_clock_speed =
-                       i85x_get_display_clock_speed;
-       else { /* 830 */
-               WARN(!IS_I830(dev_priv), "Unknown platform. Assuming 133 MHz CDCLK\n");
-               dev_priv->display.get_display_clock_speed =
-                       i830_get_display_clock_speed;
-       }
-
        if (IS_GEN5(dev_priv)) {
                dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
        } else if (IS_GEN6(dev_priv)) {
@@ -16262,28 +14606,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
                dev_priv->display.fdi_link_train = hsw_fdi_link_train;
        }
 
-       if (IS_BROADWELL(dev_priv)) {
-               dev_priv->display.modeset_commit_cdclk =
-                       broadwell_modeset_commit_cdclk;
-               dev_priv->display.modeset_calc_cdclk =
-                       broadwell_modeset_calc_cdclk;
-       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-               dev_priv->display.modeset_commit_cdclk =
-                       valleyview_modeset_commit_cdclk;
-               dev_priv->display.modeset_calc_cdclk =
-                       valleyview_modeset_calc_cdclk;
-       } else if (IS_GEN9_LP(dev_priv)) {
-               dev_priv->display.modeset_commit_cdclk =
-                       bxt_modeset_commit_cdclk;
-               dev_priv->display.modeset_calc_cdclk =
-                       bxt_modeset_calc_cdclk;
-       } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
-               dev_priv->display.modeset_commit_cdclk =
-                       skl_modeset_commit_cdclk;
-               dev_priv->display.modeset_calc_cdclk =
-                       skl_modeset_calc_cdclk;
-       }
-
        if (dev_priv->info.gen >= 9)
                dev_priv->display.update_crtcs = skl_update_crtcs;
        else
@@ -16510,8 +14832,7 @@ void intel_modeset_init_hw(struct drm_device *dev)
        struct drm_i915_private *dev_priv = to_i915(dev);
 
        intel_update_cdclk(dev_priv);
-
-       dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
+       dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw;
 
        intel_init_clock_gating(dev_priv);
 }
@@ -16566,7 +14887,8 @@ retry:
         * intermediate watermarks (since we don't trust the current
         * watermarks).
         */
-       intel_state->skip_intermediate_wm = true;
+       if (!HAS_GMCH_DISPLAY(dev_priv))
+               intel_state->skip_intermediate_wm = true;
 
        ret = intel_atomic_check(dev, state);
        if (ret) {
@@ -16600,18 +14922,6 @@ fail:
        drm_modeset_acquire_fini(&ctx);
 }
 
-static void intel_atomic_helper_free_state(struct work_struct *work)
-{
-       struct drm_i915_private *dev_priv =
-               container_of(work, typeof(*dev_priv), atomic_helper.free_work);
-       struct intel_atomic_state *state, *next;
-       struct llist_node *freed;
-
-       freed = llist_del_all(&dev_priv->atomic_helper.free_list);
-       llist_for_each_entry_safe(state, next, freed, freed)
-               drm_atomic_state_put(&state->base);
-}
-
 int intel_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -16632,7 +14942,7 @@ int intel_modeset_init(struct drm_device *dev)
        dev->mode_config.funcs = &intel_mode_funcs;
 
        INIT_WORK(&dev_priv->atomic_helper.free_work,
-                 intel_atomic_helper_free_state);
+                 intel_atomic_helper_free_state_worker);
 
        intel_init_quirks(dev);
 
@@ -16697,12 +15007,11 @@ int intel_modeset_init(struct drm_device *dev)
                }
        }
 
-       intel_update_czclk(dev_priv);
-       intel_update_cdclk(dev_priv);
-       dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
-
        intel_shared_dpll_init(dev);
 
+       intel_update_czclk(dev_priv);
+       intel_modeset_init_hw(dev);
+
        if (dev_priv->max_cdclk_freq == 0)
                intel_update_max_cdclk(dev_priv);
 
@@ -16742,7 +15051,8 @@ int intel_modeset_init(struct drm_device *dev)
         * Note that we need to do this after reconstructing the BIOS fb's
         * since the watermark calculation done here will use pstate->fb.
         */
-       sanitize_watermarks(dev);
+       if (!HAS_GMCH_DISPLAY(dev_priv))
+               sanitize_watermarks(dev);
 
        return 0;
 }
@@ -16844,6 +15154,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                        if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
                                continue;
 
+                       trace_intel_disable_plane(&plane->base, crtc);
                        plane->disable_plane(&plane->base, &crtc->base);
                }
        }
@@ -16990,15 +15301,14 @@ static bool primary_get_hw_state(struct intel_plane *plane)
 /* FIXME read out full plane state for all planes */
 static void readout_plane_state(struct intel_crtc *crtc)
 {
-       struct drm_plane *primary = crtc->base.primary;
-       struct intel_plane_state *plane_state =
-               to_intel_plane_state(primary->state);
+       struct intel_plane *primary = to_intel_plane(crtc->base.primary);
+       bool visible;
 
-       plane_state->base.visible = crtc->active &&
-               primary_get_hw_state(to_intel_plane(primary));
+       visible = crtc->active && primary_get_hw_state(primary);
 
-       if (plane_state->base.visible)
-               crtc->base.state->plane_mask |= 1 << drm_plane_index(primary);
+       intel_set_plane_visible(to_intel_crtc_state(crtc->base.state),
+                               to_intel_plane_state(primary->base.state),
+                               visible);
 }
 
 static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -17131,10 +15441,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                         */
                        crtc_state->base.mode.private_flags = I915_MODE_FLAG_INHERITED;
 
-                       if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-                               pixclk = ilk_pipe_pixel_rate(crtc_state);
-                       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-                               pixclk = crtc_state->base.adjusted_mode.crtc_clock;
+                       intel_crtc_compute_pixel_rate(crtc_state);
+
+                       if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv) ||
+                           IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+                               pixclk = crtc_state->pixel_rate;
                        else
                                WARN_ON(dev_priv->display.modeset_calc_cdclk);
 
@@ -17152,6 +15463,24 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
        }
 }
 
+static void
+get_encoder_power_domains(struct drm_i915_private *dev_priv)
+{
+       struct intel_encoder *encoder;
+
+       for_each_intel_encoder(&dev_priv->drm, encoder) {
+               u64 get_domains;
+               enum intel_display_power_domain domain;
+
+               if (!encoder->get_power_domains)
+                       continue;
+
+               get_domains = encoder->get_power_domains(encoder);
+               for_each_power_domain(domain, get_domains)
+                       intel_display_power_get(dev_priv, domain);
+       }
+}
+
 /* Scan out the current hw modeset state,
  * and sanitizes it to the current state
  */
@@ -17167,6 +15496,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
        intel_modeset_readout_hw_state(dev);
 
        /* HW state is read out, now we need to sanitize this mess. */
+       get_encoder_power_domains(dev_priv);
+
        for_each_intel_encoder(dev, encoder) {
                intel_sanitize_encoder(encoder);
        }
@@ -17193,15 +15524,17 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
                pll->on = false;
        }
 
-       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                vlv_wm_get_hw_state(dev);
-       else if (IS_GEN9(dev_priv))
+               vlv_wm_sanitize(dev_priv);
+       } else if (IS_GEN9(dev_priv)) {
                skl_wm_get_hw_state(dev);
-       else if (HAS_PCH_SPLIT(dev_priv))
+       } else if (HAS_PCH_SPLIT(dev_priv)) {
                ilk_wm_get_hw_state(dev);
+       }
 
        for_each_intel_crtc(dev, crtc) {
-               unsigned long put_domains;
+               u64 put_domains;
 
                put_domains = modeset_get_crtc_power_domains(&crtc->base, crtc->config);
                if (WARN_ON(put_domains))
@@ -17209,6 +15542,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
        }
        intel_display_set_init_power(dev_priv, false);
 
+       intel_power_domains_verify_state(dev_priv);
+
        intel_fbc_init_pipe_state(dev_priv);
 }
 
@@ -17259,8 +15594,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
 
        intel_init_gt_powersave(dev_priv);
 
-       intel_modeset_init_hw(dev);
-
        intel_setup_overlay(dev_priv);
 }
 
@@ -17492,9 +15825,9 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv)
 
 void
 intel_display_print_error_state(struct drm_i915_error_state_buf *m,
-                               struct drm_i915_private *dev_priv,
                                struct intel_display_error_state *error)
 {
+       struct drm_i915_private *dev_priv = m->i915;
        int i;
 
        if (!error)