]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_display.c
drm/i915: Add power well SW/HW state verification
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_display.c
index 3dc8724df4004842c78bc985606da52a06e449c0..e1e828a8c5249ee5feb98d0b0bdaa9d124ee9383 100644 (file)
@@ -96,10 +96,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);
@@ -115,16 +114,13 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
                            const struct intel_crtc_state *pipe_config);
 static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
 static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
-static void skl_init_scalers(struct drm_i915_private *dev_priv,
-                            struct intel_crtc *crtc,
-                            struct intel_crtc_state *crtc_state);
+static void intel_crtc_init_scalers(struct intel_crtc *crtc,
+                                   struct intel_crtc_state *crtc_state);
 static void skylake_pfit_enable(struct intel_crtc *crtc);
 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 bxt_calc_cdclk(int max_pixclk);
 
 struct intel_limit {
        struct {
@@ -138,7 +134,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 +166,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)))
@@ -614,12 +553,12 @@ static bool intel_PLL_is_valid(struct drm_i915_private *dev_priv,
                INTELPllInvalid("m1 out of range\n");
 
        if (!IS_PINEVIEW(dev_priv) && !IS_VALLEYVIEW(dev_priv) &&
-           !IS_CHERRYVIEW(dev_priv) && !IS_BROXTON(dev_priv))
+           !IS_CHERRYVIEW(dev_priv) && !IS_GEN9_LP(dev_priv))
                if (clock->m1 <= clock->m2)
                        INTELPllInvalid("m1 <= m2\n");
 
        if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
-           !IS_BROXTON(dev_priv)) {
+           !IS_GEN9_LP(dev_priv)) {
                if (clock->p < limit->p.min || limit->p.max < clock->p)
                        INTELPllInvalid("p out of range\n");
                if (clock->m < limit->m.min || limit->m.max < clock->m)
@@ -1232,7 +1171,7 @@ static void assert_cursor(struct drm_i915_private *dev_priv,
 {
        bool cur_state;
 
-       if (IS_845G(dev_priv) || IS_I865G(dev_priv))
+       if (IS_I845G(dev_priv) || IS_I865G(dev_priv))
                cur_state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
        else
                cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
@@ -1327,7 +1266,7 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
                }
        } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                for_each_sprite(dev_priv, pipe, sprite) {
-                       u32 val = I915_READ(SPCNTR(pipe, sprite));
+                       u32 val = I915_READ(SPCNTR(pipe, PLANE_SPRITE0 + sprite));
                        I915_STATE_WARN(val & SP_ENABLE,
                             "sprite %c assertion failure, should be off on pipe %c but is still active\n",
                             sprite_name(pipe, sprite), pipe_name(pipe));
@@ -2112,11 +2051,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);
 }
@@ -2137,11 +2078,10 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view,
                        const struct drm_framebuffer *fb,
                        unsigned int rotation)
 {
+       view->type = I915_GGTT_VIEW_NORMAL;
        if (drm_rotation_90_or_270(rotation)) {
-               *view = i915_ggtt_view_rotated;
-               view->params.rotated = to_intel_framebuffer(fb)->rot_info;
-       } else {
-               *view = i915_ggtt_view_normal;
+               view->type = I915_GGTT_VIEW_ROTATED;
+               view->rotated = to_intel_framebuffer(fb)->rot_info;
        }
 }
 
@@ -2149,7 +2089,7 @@ static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_pr
 {
        if (INTEL_INFO(dev_priv)->gen >= 9)
                return 256 * 1024;
-       else if (IS_BROADWATER(dev_priv) || IS_CRESTLINE(dev_priv) ||
+       else if (IS_I965G(dev_priv) || IS_I965GM(dev_priv) ||
                 IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                return 128 * 1024;
        else if (INTEL_INFO(dev_priv)->gen >= 4)
@@ -2235,24 +2175,19 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
                        i915_vma_pin_fence(vma);
        }
 
+       i915_vma_get(vma);
 err:
        intel_runtime_pm_put(dev_priv);
        return vma;
 }
 
-void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
+void intel_unpin_fb_vma(struct i915_vma *vma)
 {
-       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-       struct i915_ggtt_view view;
-       struct i915_vma *vma;
-
-       WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
-
-       intel_fill_fb_ggtt_view(&view, fb, rotation);
-       vma = i915_gem_object_to_ggtt(obj, &view);
+       lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
 
        i915_vma_unpin_fence(vma);
        i915_gem_object_unpin_from_display_plane(vma);
+       i915_vma_put(vma);
 }
 
 static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane,
@@ -2275,7 +2210,7 @@ u32 intel_fb_xy_to_linear(int x, int y,
                          int plane)
 {
        const struct drm_framebuffer *fb = state->base.fb;
-       unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+       unsigned int cpp = fb->format->cpp[plane];
        unsigned int pitch = fb->pitches[plane];
 
        return y * pitch + x * cpp;
@@ -2344,7 +2279,7 @@ static u32 intel_adjust_tile_offset(int *x, int *y,
 {
        const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
        const struct drm_framebuffer *fb = state->base.fb;
-       unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+       unsigned int cpp = fb->format->cpp[plane];
        unsigned int rotation = state->base.rotation;
        unsigned int pitch = intel_fb_pitch(fb, plane, rotation);
 
@@ -2400,7 +2335,7 @@ static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv,
                                      u32 alignment)
 {
        uint64_t fb_modifier = fb->modifier;
-       unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+       unsigned int cpp = fb->format->cpp[plane];
        u32 offset, offset_aligned;
 
        if (alignment)
@@ -2455,7 +2390,7 @@ u32 intel_compute_tile_offset(int *x, int *y,
        u32 alignment;
 
        /* AUX_DIST needs only 4K alignment */
-       if (fb->pixel_format == DRM_FORMAT_NV12 && plane == 1)
+       if (fb->format->format == DRM_FORMAT_NV12 && plane == 1)
                alignment = 4096;
        else
                alignment = intel_surf_alignment(dev_priv, fb->modifier);
@@ -2468,7 +2403,7 @@ u32 intel_compute_tile_offset(int *x, int *y,
 static void intel_fb_offset_to_xy(int *x, int *y,
                                  const struct drm_framebuffer *fb, int plane)
 {
-       unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+       unsigned int cpp = fb->format->cpp[plane];
        unsigned int pitch = fb->pitches[plane];
        u32 linear_offset = fb->offsets[plane];
 
@@ -2496,8 +2431,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
        struct intel_rotation_info *rot_info = &intel_fb->rot_info;
        u32 gtt_offset_rotated = 0;
        unsigned int max_size = 0;
-       uint32_t format = fb->pixel_format;
-       int i, num_planes = drm_format_num_planes(format);
+       int i, num_planes = fb->format->num_planes;
        unsigned int tile_size = intel_tile_size(dev_priv);
 
        for (i = 0; i < num_planes; i++) {
@@ -2506,9 +2440,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
                u32 offset;
                int x, y;
 
-               cpp = drm_format_plane_cpp(format, i);
-               width = drm_format_plane_width(fb->width, format, i);
-               height = drm_format_plane_height(fb->height, format, i);
+               cpp = fb->format->cpp[i];
+               width = drm_framebuffer_plane_width(fb->width, fb, i);
+               height = drm_framebuffer_plane_height(fb->height, fb, i);
 
                intel_fb_offset_to_xy(&x, &y, fb, i);
 
@@ -2585,8 +2519,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
                         * We only keep the x/y offsets, so push all of the
                         * gtt offset into the x/y offsets.
                         */
-                       _intel_adjust_tile_offset(&x, &y, tile_size,
-                                                 tile_width, tile_height, pitch_tiles,
+                       _intel_adjust_tile_offset(&x, &y,
+                                                 tile_width, tile_height,
+                                                 tile_size, pitch_tiles,
                                                  gtt_offset_rotated * tile_size, 0);
 
                        gtt_offset_rotated += rot_info->plane[i].width * rot_info->plane[i].height;
@@ -2688,40 +2623,35 @@ 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,
+       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;
 
-       mode_cmd.pixel_format = fb->pixel_format;
+       mode_cmd.pixel_format = fb->format->format;
        mode_cmd.width = fb->width;
        mode_cmd.height = fb->height;
        mode_cmd.pitches[0] = fb->pitches[0];
        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;
 }
 
@@ -2746,7 +2676,6 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
        struct drm_device *dev = intel_crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_crtc *c;
-       struct intel_crtc *i;
        struct drm_i915_gem_object *obj;
        struct drm_plane *primary = intel_crtc->base.primary;
        struct drm_plane_state *plane_state = primary->state;
@@ -2771,20 +2700,20 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
         * an fb with another CRTC instead
         */
        for_each_crtc(dev, c) {
-               i = to_intel_crtc(c);
+               struct intel_plane_state *state;
 
                if (c == &intel_crtc->base)
                        continue;
 
-               if (!i->active)
+               if (!to_intel_crtc(c)->active)
                        continue;
 
-               fb = c->primary->fb;
-               if (!fb)
+               state = to_intel_plane_state(c->primary->state);
+               if (!state->vma)
                        continue;
 
-               obj = intel_fb_obj(fb);
-               if (i915_gem_object_ggtt_offset(obj, NULL) == plane_config->base) {
+               if (intel_plane_ggtt_offset(state) == plane_config->base) {
+                       fb = c->primary->fb;
                        drm_framebuffer_reference(fb);
                        goto valid_fb;
                }
@@ -2797,7 +2726,7 @@ 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.
         */
-       to_intel_plane_state(plane_state)->base.visible = false;
+       plane_state->visible = false;
        crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
        intel_pre_disable_primary_noatomic(&intel_crtc->base);
        intel_plane->disable_plane(primary, &intel_crtc->base);
@@ -2805,6 +2734,19 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
        return;
 
 valid_fb:
+       mutex_lock(&dev->struct_mutex);
+       intel_state->vma =
+               intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
+       mutex_unlock(&dev->struct_mutex);
+       if (IS_ERR(intel_state->vma)) {
+               DRM_ERROR("failed to pin boot fb on pipe %d: %li\n",
+                         intel_crtc->pipe, PTR_ERR(intel_state->vma));
+
+               intel_state->vma = NULL;
+               drm_framebuffer_unreference(fb);
+               return;
+       }
+
        plane_state->src_x = 0;
        plane_state->src_y = 0;
        plane_state->src_w = fb->width << 16;
@@ -2833,7 +2775,7 @@ valid_fb:
 static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
                               unsigned int rotation)
 {
-       int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+       int cpp = fb->format->cpp[plane];
 
        switch (fb->modifier) {
        case DRM_FORMAT_MOD_NONE:
@@ -2912,7 +2854,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
         * TODO: linear and Y-tiled seem fine, Yf untested,
         */
        if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
-               int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+               int cpp = fb->format->cpp[0];
 
                while ((x + w) * cpp > fb->pitches[0]) {
                        if (offset == 0) {
@@ -2967,6 +2909,9 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
        unsigned int rotation = plane_state->base.rotation;
        int ret;
 
+       if (!plane_state->base.visible)
+               return 0;
+
        /* Rotate src coordinates to match rotated GTT view */
        if (drm_rotation_90_or_270(rotation))
                drm_rect_rotate(&plane_state->base.src,
@@ -2977,7 +2922,7 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
         * Handle the AUX surface first since
         * the main surface setup depends on it.
         */
-       if (fb->pixel_format == DRM_FORMAT_NV12) {
+       if (fb->format->format == DRM_FORMAT_NV12) {
                ret = skl_check_nv12_aux_surface(plane_state);
                if (ret)
                        return ret;
@@ -3032,7 +2977,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary,
                I915_WRITE(PRIMCNSTALPHA(plane), 0);
        }
 
-       switch (fb->pixel_format) {
+       switch (fb->format->format) {
        case DRM_FORMAT_C8:
                dspcntr |= DISPPLANE_8BPP;
                break;
@@ -3097,13 +3042,13 @@ static void i9xx_update_primary_plane(struct drm_plane *primary,
        I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
        if (INTEL_GEN(dev_priv) >= 4) {
                I915_WRITE(DSPSURF(plane),
-                          intel_fb_gtt_offset(fb, rotation) +
+                          intel_plane_ggtt_offset(plane_state) +
                           intel_crtc->dspaddr_offset);
                I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
                I915_WRITE(DSPLINOFF(plane), linear_offset);
        } else {
                I915_WRITE(DSPADDR(plane),
-                          intel_fb_gtt_offset(fb, rotation) +
+                          intel_plane_ggtt_offset(plane_state) +
                           intel_crtc->dspaddr_offset);
        }
        POSTING_READ(reg);
@@ -3147,7 +3092,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary,
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
                dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
 
-       switch (fb->pixel_format) {
+       switch (fb->format->format) {
        case DRM_FORMAT_C8:
                dspcntr |= DISPPLANE_8BPP;
                break;
@@ -3200,7 +3145,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary,
 
        I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
        I915_WRITE(DSPSURF(plane),
-                  intel_fb_gtt_offset(fb, rotation) +
+                  intel_plane_ggtt_offset(plane_state) +
                   intel_crtc->dspaddr_offset);
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
                I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
@@ -3223,23 +3168,6 @@ u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv,
        }
 }
 
-u32 intel_fb_gtt_offset(struct drm_framebuffer *fb,
-                       unsigned int rotation)
-{
-       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-       struct i915_ggtt_view view;
-       struct i915_vma *vma;
-
-       intel_fill_fb_ggtt_view(&view, fb, rotation);
-
-       vma = i915_gem_object_to_ggtt(obj, &view);
-       if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
-                view.type))
-               return -1;
-
-       return i915_ggtt_offset(vma);
-}
-
 static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
 {
        struct drm_device *dev = intel_crtc->base.dev;
@@ -3278,12 +3206,12 @@ u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
         * linear buffers or in number of tiles for tiled buffers.
         */
        if (drm_rotation_90_or_270(rotation)) {
-               int cpp = drm_format_plane_cpp(fb->pixel_format, plane);
+               int cpp = fb->format->cpp[plane];
 
                stride /= intel_tile_height(dev_priv, fb->modifier, cpp);
        } else {
                stride /= intel_fb_stride_alignment(dev_priv, fb->modifier,
-                                                   fb->pixel_format);
+                                                   fb->format->format);
        }
 
        return stride;
@@ -3378,7 +3306,8 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
        struct drm_framebuffer *fb = plane_state->base.fb;
-       int pipe = intel_crtc->pipe;
+       enum plane_id plane_id = to_intel_plane(plane)->id;
+       enum pipe pipe = to_intel_plane(plane)->pipe;
        u32 plane_ctl;
        unsigned int rotation = plane_state->base.rotation;
        u32 stride = skl_plane_stride(fb, 0, rotation);
@@ -3393,13 +3322,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->pixel_format);
+       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 */
@@ -3413,30 +3351,30 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
        intel_crtc->adjusted_x = src_x;
        intel_crtc->adjusted_y = src_y;
 
-       I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
-       I915_WRITE(PLANE_OFFSET(pipe, 0), (src_y << 16) | src_x);
-       I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
-       I915_WRITE(PLANE_SIZE(pipe, 0), (src_h << 16) | src_w);
+       I915_WRITE(PLANE_CTL(pipe, plane_id), plane_ctl);
+       I915_WRITE(PLANE_OFFSET(pipe, plane_id), (src_y << 16) | src_x);
+       I915_WRITE(PLANE_STRIDE(pipe, plane_id), stride);
+       I915_WRITE(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
 
        if (scaler_id >= 0) {
                uint32_t ps_ctrl = 0;
 
                WARN_ON(!dst_w || !dst_h);
-               ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) |
+               ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane_id) |
                        crtc_state->scaler_state.scalers[scaler_id].mode;
                I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
                I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
                I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (dst_x << 16) | dst_y);
                I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h);
-               I915_WRITE(PLANE_POS(pipe, 0), 0);
+               I915_WRITE(PLANE_POS(pipe, plane_id), 0);
        } else {
-               I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x);
+               I915_WRITE(PLANE_POS(pipe, plane_id), (dst_y << 16) | dst_x);
        }
 
-       I915_WRITE(PLANE_SURF(pipe, 0),
-                  intel_fb_gtt_offset(fb, rotation) + surf_addr);
+       I915_WRITE(PLANE_SURF(pipe, plane_id),
+                  intel_plane_ggtt_offset(plane_state) + surf_addr);
 
-       POSTING_READ(PLANE_SURF(pipe, 0));
+       POSTING_READ(PLANE_SURF(pipe, plane_id));
 }
 
 static void skylake_disable_primary_plane(struct drm_plane *primary,
@@ -3444,12 +3382,12 @@ static void skylake_disable_primary_plane(struct drm_plane *primary,
 {
        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;
+       enum plane_id plane_id = to_intel_plane(primary)->id;
+       enum pipe pipe = to_intel_plane(primary)->pipe;
 
-       I915_WRITE(PLANE_CTL(pipe, 0), 0);
-       I915_WRITE(PLANE_SURF(pipe, 0), 0);
-       POSTING_READ(PLANE_SURF(pipe, 0));
+       I915_WRITE(PLANE_CTL(pipe, plane_id), 0);
+       I915_WRITE(PLANE_SURF(pipe, plane_id), 0);
+       POSTING_READ(PLANE_SURF(pipe, plane_id));
 }
 
 /* Assume fb object is pinned & idle & fenced and just update base pointers */
@@ -3558,23 +3496,19 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
        state = drm_atomic_helper_duplicate_state(dev, ctx);
        if (IS_ERR(state)) {
                ret = PTR_ERR(state);
-               state = NULL;
                DRM_ERROR("Duplicating state failed with %i\n", ret);
-               goto err;
+               return;
        }
 
        ret = drm_atomic_helper_disable_all(dev, ctx);
        if (ret) {
                DRM_ERROR("Suspending crtc's failed with %i\n", ret);
-               goto err;
+               drm_atomic_state_put(state);
+               return;
        }
 
        dev_priv->modeset_restore_state = state;
        state->acquire_ctx = ctx;
-       return;
-
-err:
-       drm_atomic_state_put(state);
 }
 
 void intel_finish_reset(struct drm_i915_private *dev_priv)
@@ -4227,9 +4161,8 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
        udelay(100);
 }
 
-bool intel_has_pending_fb_unpin(struct drm_device *dev)
+bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *crtc;
 
        /* Note that we don't need to be called with mode_config.lock here
@@ -4239,7 +4172,7 @@ bool intel_has_pending_fb_unpin(struct drm_device *dev)
         * cannot claim and pin a new fb without at least acquring the
         * struct_mutex and so serialising with us.
         */
-       for_each_intel_crtc(dev, crtc) {
+       for_each_intel_crtc(&dev_priv->drm, crtc) {
                if (atomic_read(&crtc->unpin_work_count) == 0)
                        continue;
 
@@ -4265,10 +4198,10 @@ static void page_flip_completed(struct intel_crtc *intel_crtc)
        drm_crtc_vblank_put(&intel_crtc->base);
 
        wake_up_all(&dev_priv->pending_flip_queue);
-       queue_work(dev_priv->wq, &work->unpin_work);
-
        trace_i915_flip_complete(intel_crtc->plane,
                                 work->pending_flip_obj);
+
+       queue_work(dev_priv->wq, &work->unpin_work);
 }
 
 static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
@@ -4769,7 +4702,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
        }
 
        /* Check src format */
-       switch (fb->pixel_format) {
+       switch (fb->format->format) {
        case DRM_FORMAT_RGB565:
        case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_XRGB8888:
@@ -4785,7 +4718,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
        default:
                DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n",
                              intel_plane->base.base.id, intel_plane->base.name,
-                             fb->base.id, fb->pixel_format);
+                             fb->base.id, fb->format->format);
                return -EINVAL;
        }
 
@@ -5020,11 +4953,9 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
         * 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)) {
-               intel_set_memory_cxsr(dev_priv, false);
-               dev_priv->wm.vlv.cxsr = false;
+       if (HAS_GMCH_DISPLAY(dev_priv) &&
+           intel_set_memory_cxsr(dev_priv, false))
                intel_wait_for_vblank(dev_priv, pipe);
-       }
 }
 
 static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
@@ -5099,11 +5030,9 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
                 * 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);
-                       dev_priv->wm.vlv.cxsr = false;
+               if (old_crtc_state->base.active &&
+                   intel_set_memory_cxsr(dev_priv, false))
                        intel_wait_for_vblank(dev_priv, crtc->pipe);
-               }
        }
 
        /*
@@ -5113,10 +5042,8 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
         *
         * WaCxSRDisabledForSpriteScaling:ivb
         */
-       if (pipe_config->disable_lp_wm) {
-               ilk_disable_lp_wm(dev);
+       if (pipe_config->disable_lp_wm && ilk_disable_lp_wm(dev))
                intel_wait_for_vblank(dev_priv, crtc->pipe);
-       }
 
        /*
         * If we're doing a modeset, we're done.  No need to do any pre-vblank
@@ -5464,10 +5391,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
                intel_ddi_enable_transcoder_func(crtc);
 
        if (dev_priv->display.initial_watermarks != NULL)
-               dev_priv->display.initial_watermarks(old_intel_state,
-                                                    pipe_config);
-       else
-               intel_update_watermarks(intel_crtc);
+               dev_priv->display.initial_watermarks(old_intel_state, pipe_config);
 
        /* XXX: Do the pipe assertions at the right place for BXT DSI. */
        if (!transcoder_is_dsi(cpu_transcoder))
@@ -5739,14 +5663,15 @@ intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder)
        }
 }
 
-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)
@@ -5756,28 +5681,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_display_port_power_domain(intel_encoder));
        }
 
+       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 =
@@ -5792,7 +5720,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;
 
@@ -5800,1012 +5728,156 @@ 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;
-
-       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;
-}
+       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;
 
-static int skl_calc_cdclk(int max_pixclk, int vco);
+       if (WARN_ON(intel_crtc->active))
+               return;
 
-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;
+       if (intel_crtc_has_dp_encoder(intel_crtc->config))
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
-               vco = dev_priv->skl_preferred_vco_freq;
-               WARN_ON(vco != 8100000 && vco != 8640000);
+       intel_set_pipe_timings(intel_crtc);
+       intel_set_pipe_src_size(intel_crtc);
 
-               /*
-                * 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;
+       if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
+               struct drm_i915_private *dev_priv = to_i915(dev);
 
-               dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
-       } 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;
+       intel_update_watermarks(intel_crtc);
+       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 void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
+static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
 {
-       I915_WRITE(BXT_DE_PLL_ENABLE, 0);
-
-       /* 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");
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
 
-       dev_priv->cdclk_pll.vco = 0;
+       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_enable(struct drm_i915_private *dev_priv, int vco)
+static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
+                            struct drm_atomic_state *old_state)
 {
-       int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk_pll.ref);
-       u32 val;
+       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;
 
-       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);
+       if (WARN_ON(intel_crtc->active))
+               return;
 
-       I915_WRITE(BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
+       i9xx_set_pll_dividers(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");
+       if (intel_crtc_has_dp_encoder(intel_crtc->config))
+               intel_dp_set_m_n(intel_crtc, M1_N1);
 
-       dev_priv->cdclk_pll.vco = vco;
-}
+       intel_set_pipe_timings(intel_crtc);
+       intel_set_pipe_src_size(intel_crtc);
 
-static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk)
-{
-       u32 val, divider;
-       int vco, ret;
+       i9xx_set_pipeconf(intel_crtc);
 
-       vco = bxt_de_pll_vco(dev_priv, cdclk);
+       intel_crtc->active = true;
 
-       DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
+       if (!IS_GEN2(dev_priv))
+               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
-       /* 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:
-               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_encoders_pre_enable(crtc, pipe_config, old_state);
 
-               divider = BXT_CDCLK_CD2X_DIV_SEL_1;
-               break;
-       }
+       i9xx_enable_pll(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);
+       i9xx_pfit_enable(intel_crtc);
 
-       if (ret) {
-               DRM_ERROR("PCode CDCLK freq change notify failed (err %d, freq %d)\n",
-                         ret, cdclk);
-               return;
-       }
+       intel_color_load_luts(&pipe_config->base);
 
-       if (dev_priv->cdclk_pll.vco != 0 &&
-           dev_priv->cdclk_pll.vco != vco)
-               bxt_de_pll_disable(dev_priv);
+       intel_update_watermarks(intel_crtc);
+       intel_enable_pipe(intel_crtc);
 
-       if (dev_priv->cdclk_pll.vco != vco)
-               bxt_de_pll_enable(dev_priv, vco);
+       assert_vblank_disabled(crtc);
+       drm_crtc_vblank_on(crtc);
 
-       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);
+       intel_encoders_enable(crtc, pipe_config, old_state);
+}
 
-       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);
+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 (ret) {
-               DRM_ERROR("PCode CDCLK freq set failed, (err %d, freq %d)\n",
-                         ret, cdclk);
+       if (!crtc->config->gmch_pfit.control)
                return;
-       }
 
-       intel_update_cdclk(dev_priv);
+       assert_pipe_disabled(dev_priv, crtc->pipe);
+
+       DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
+                        I915_READ(PFIT_CONTROL));
+       I915_WRITE(PFIT_CONTROL, 0);
 }
 
-static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
+static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
+                             struct drm_atomic_state *old_state)
 {
-       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;
+       struct drm_crtc *crtc = old_crtc_state->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;
 
-       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.
+        * On gen2 planes are double buffered but the pipe isn't, so we must
+        * wait for planes to fully turn off before disabling the pipe.
         */
-       if (dev_priv->cdclk_freq >= 500000)
-               expected |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
-
-       if (cdctl == expected)
-               /* All well; nothing to sanitize */
-               return;
+       if (IS_GEN2(dev_priv))
+               intel_wait_for_vblank(dev_priv, pipe);
 
-sanitize:
-       DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
+       intel_encoders_disable(crtc, old_crtc_state, old_state);
 
-       /* force cdclk programming */
-       dev_priv->cdclk_freq = 0;
+       drm_crtc_vblank_off(crtc);
+       assert_vblank_disabled(crtc);
 
-       /* force full PLL disable + enable */
-       dev_priv->cdclk_pll.vco = -1;
-}
+       intel_disable_pipe(intel_crtc);
 
-void bxt_init_cdclk(struct drm_i915_private *dev_priv)
-{
-       bxt_sanitize_cdclk(dev_priv);
+       i9xx_pfit_disable(intel_crtc);
 
-       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.
-        */
-       bxt_set_cdclk(dev_priv, bxt_calc_cdclk(0));
-}
-
-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 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)
-{
-       int max_pixclk = ilk_max_pixel_rate(state);
-       struct intel_atomic_state *intel_state =
-               to_intel_atomic_state(state);
-
-       intel_state->cdclk = intel_state->dev_cdclk =
-               bxt_calc_cdclk(max_pixclk);
-
-       if (!intel_state->active_crtcs)
-               intel_state->dev_cdclk = bxt_calc_cdclk(0);
-
-       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);
-
-       if (!crtc->config->gmch_pfit.control)
-               return;
-
-       assert_pipe_disabled(dev_priv, crtc->pipe);
-
-       DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
-                        I915_READ(PFIT_CONTROL));
-       I915_WRITE(PFIT_CONTROL, 0);
-}
-
-static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
-                             struct drm_atomic_state *old_state)
-{
-       struct drm_crtc *crtc = old_crtc_state->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;
-
-       /*
-        * On gen2 planes are double buffered but the pipe isn't, so we must
-        * wait for planes to fully turn off before disabling the pipe.
-        */
-       if (IS_GEN2(dev_priv))
-               intel_wait_for_vblank(dev_priv, pipe);
-
-       intel_encoders_disable(crtc, old_crtc_state, old_state);
-
-       drm_crtc_vblank_off(crtc);
-       assert_vblank_disabled(crtc);
-
-       intel_disable_pipe(intel_crtc);
-
-       i9xx_pfit_disable(intel_crtc);
-
-       intel_encoders_post_disable(crtc, old_crtc_state, old_state);
+       intel_encoders_post_disable(crtc, old_crtc_state, old_state);
 
        if (!intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DSI)) {
                if (IS_CHERRYVIEW(dev_priv))
@@ -6828,7 +5900,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;
@@ -6836,16 +5908,22 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
        if (!intel_crtc->active)
                return;
 
-       if (to_intel_plane_state(crtc->primary->state)->base.visible) {
+       if (crtc->primary->state->visible) {
                WARN_ON(intel_crtc->flip_work);
 
                intel_pre_disable_primary_noatomic(crtc);
 
                intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
-               to_intel_plane_state(crtc->primary->state)->base.visible = false;
+               crtc->primary->state->visible = false;
        }
 
        state = drm_atomic_state_alloc(crtc->dev);
+       if (!state) {
+               DRM_DEBUG_KMS("failed to disable [CRTC:%d:%s], out of memory",
+                             crtc->base.id, crtc->name);
+               return;
+       }
+
        state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
 
        /* Everything's already locked, -EDEADLK can't happen. */
@@ -7113,521 +6191,150 @@ retry:
        return ret;
 }
 
-static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
-                                    struct intel_crtc_state *pipe_config)
-{
-       if (pipe_config->pipe_bpp > 24)
-               return false;
-
-       /* HSW can handle pixel rate up to cdclk? */
-       if (IS_HASWELL(dev_priv))
-               return true;
-
-       /*
-        * We compare against max which means we must take
-        * the increased cdclk requirement into account when
-        * calculating the new cdclk.
-        *
-        * Should measure whether using a lower cdclk w/o IPS
-        */
-       return ilk_pipe_pixel_rate(pipe_config) <=
-               dev_priv->max_cdclk_freq * 95 / 100;
-}
-
-static void hsw_compute_ips_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);
-
-       pipe_config->ips_enabled = i915.enable_ips &&
-               hsw_crtc_supports_ips(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:
-               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 pipe_config_supports_ips(struct drm_i915_private *dev_priv,
+                                    struct intel_crtc_state *pipe_config)
 {
-       return 266667;
-}
+       if (pipe_config->pipe_bpp > 24)
+               return false;
 
-static int i85x_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       u16 hpllcc = 0;
+       /* HSW can handle pixel rate up to cdclk? */
+       if (IS_HASWELL(dev_priv))
+               return true;
 
        /*
-        * 852GM/852GMV only supports 133 MHz and the HPLLCC
-        * encoding is different :(
-        * FIXME is this the right way to detect 852GM/852GMV?
+        * We compare against max which means we must take
+        * the increased cdclk requirement into account when
+        * calculating the new cdclk.
+        *
+        * Should measure whether using a lower cdclk w/o IPS
         */
-       if (pdev->revision == 0x1)
-               return 133333;
+       return pipe_config->pixel_rate <=
+               dev_priv->max_cdclk_freq * 95 / 100;
+}
 
-       pci_bus_read_config_word(pdev->bus,
-                                PCI_DEVFN(0, 3), HPLLCC, &hpllcc);
+static void hsw_compute_ips_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);
 
-       /* 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;
+       pipe_config->ips_enabled = i915.enable_ips &&
+               hsw_crtc_supports_ips(crtc) &&
+               pipe_config_supports_ips(dev_priv, pipe_config);
 }
 
-static int i830_get_display_clock_speed(struct drm_i915_private *dev_priv)
+static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
 {
-       return 133333;
+       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 unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv)
+static uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 {
-       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_CRESTLINE(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;
+       uint32_t pixel_rate;
 
-       tmp = I915_READ(IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO);
+       pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
 
-       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);
+       /*
+        * We only use IF-ID interlacing. If we ever use
+        * PF-ID we'll need to adjust the pixel_rate here.
+        */
 
-       return vco;
-}
+       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;
 
-static int gm45_get_display_clock_speed(struct drm_i915_private *dev_priv)
-{
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       unsigned int cdclk_sel, vco = intel_hpll_vco(dev_priv);
-       uint16_t tmp = 0;
+               pipe_w = pipe_config->pipe_src_w;
+               pipe_h = pipe_config->pipe_src_h;
 
-       pci_read_config_word(pdev, GCFGC, &tmp);
+               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;
 
-       cdclk_sel = (tmp >> 12) & 0x1;
+               if (WARN_ON(!pfit_w || !pfit_h))
+                       return pixel_rate;
 
-       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;
+               pixel_rate = div_u64((uint64_t) pixel_rate * pipe_w * pipe_h,
+                                    pfit_w * pfit_h);
        }
+
+       return pixel_rate;
 }
 
-static int i965gm_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;
-       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;
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
 
-       pci_read_config_word(pdev, GCFGC, &tmp);
+       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);
+}
 
-       cdclk_sel = ((tmp >> 8) & 0x1f) - 1;
+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 (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
@@ -8119,7 +6826,8 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc,
        else
                dpll |= DPLLB_MODE_DAC_SERIAL;
 
-       if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) || IS_G33(dev_priv)) {
+       if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
+           IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
                dpll |= (crtc_state->pixel_multiplier - 1)
                        << SDVO_MULTIPLIER_SHIFT_HIRES;
        }
@@ -8354,7 +7062,6 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
        mode->type = DRM_MODE_TYPE_DRIVER;
 
        mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
-       mode->flags |= pipe_config->base.adjusted_mode.flags;
 
        mode->hsync = drm_mode_hsync(mode);
        mode->vrefresh = drm_mode_vrefresh(mode);
@@ -8693,6 +7400,8 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
 
        fb = &intel_fb->base;
 
+       fb->dev = dev;
+
        if (INTEL_GEN(dev_priv) >= 4) {
                if (val & DISPPLANE_TILED) {
                        plane_config->tiling = I915_TILING_X;
@@ -8702,8 +7411,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
 
        pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
        fourcc = i9xx_format_to_fourcc(pixel_format);
-       fb->pixel_format = fourcc;
-       fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
+       fb->format = drm_format_info(fourcc);
 
        if (INTEL_GEN(dev_priv) >= 4) {
                if (plane_config->tiling)
@@ -8723,15 +7431,16 @@ 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,
-                                              fb->pixel_format,
+       aligned_height = intel_fb_align_height(dev_priv,
+                                              fb->height,
+                                              fb->format->format,
                                               fb->modifier);
 
        plane_config->size = fb->pitches[0] * aligned_height;
 
        DRM_DEBUG_KMS("pipe/plane %c/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
                      pipe_name(pipe), plane, fb->width, fb->height,
-                     fb->bits_per_pixel, base, fb->pitches[0],
+                     fb->format->cpp[0] * 8, base, fb->pitches[0],
                      plane_config->size);
 
        plane_config->fb = intel_fb;
@@ -8832,7 +7541,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
                         >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
                pipe_config->dpll_hw_state.dpll_md = tmp;
        } else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
-                  IS_G33(dev_priv)) {
+                  IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
                tmp = I915_READ(DPLL(crtc->pipe));
                pipe_config->pixel_multiplier =
                        ((tmp & SDVO_MULTIPLIER_MASK)
@@ -8885,9 +7594,8 @@ out:
        return ret;
 }
 
-static void ironlake_init_pch_refclk(struct drm_device *dev)
+static void ironlake_init_pch_refclk(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_encoder *encoder;
        int i;
        u32 val, final;
@@ -8899,7 +7607,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
        bool using_ssc_source = false;
 
        /* We need to take the global config into account */
-       for_each_intel_encoder(dev, encoder) {
+       for_each_intel_encoder(&dev_priv->drm, encoder) {
                switch (encoder->type) {
                case INTEL_OUTPUT_LVDS:
                        has_panel = true;
@@ -9155,10 +7863,9 @@ static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv)
  * - Sequence to enable CLKOUT_DP without spread
  * - Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O
  */
-static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread,
-                                bool with_fdi)
+static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv,
+                                bool with_spread, bool with_fdi)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
        uint32_t reg, tmp;
 
        if (WARN(with_fdi && !with_spread, "FDI requires downspread\n"))
@@ -9196,9 +7903,8 @@ static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread,
 }
 
 /* Sequence to disable CLKOUT_DP */
-static void lpt_disable_clkout_dp(struct drm_device *dev)
+static void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
        uint32_t reg, tmp;
 
        mutex_lock(&dev_priv->sb_lock);
@@ -9283,12 +7989,12 @@ static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
 
 #undef BEND_IDX
 
-static void lpt_init_pch_refclk(struct drm_device *dev)
+static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv)
 {
        struct intel_encoder *encoder;
        bool has_vga = false;
 
-       for_each_intel_encoder(dev, encoder) {
+       for_each_intel_encoder(&dev_priv->drm, encoder) {
                switch (encoder->type) {
                case INTEL_OUTPUT_ANALOG:
                        has_vga = true;
@@ -9299,24 +8005,22 @@ static void lpt_init_pch_refclk(struct drm_device *dev)
        }
 
        if (has_vga) {
-               lpt_bend_clkout_dp(to_i915(dev), 0);
-               lpt_enable_clkout_dp(dev, true, true);
+               lpt_bend_clkout_dp(dev_priv, 0);
+               lpt_enable_clkout_dp(dev_priv, true, true);
        } else {
-               lpt_disable_clkout_dp(dev);
+               lpt_disable_clkout_dp(dev_priv);
        }
 }
 
 /*
  * Initialize reference clocks when the driver loads
  */
-void intel_init_pch_refclk(struct drm_device *dev)
+void intel_init_pch_refclk(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
-
        if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))
-               ironlake_init_pch_refclk(dev);
+               ironlake_init_pch_refclk(dev_priv);
        else if (HAS_PCH_LPT(dev_priv))
-               lpt_init_pch_refclk(dev);
+               lpt_init_pch_refclk(dev_priv);
 }
 
 static void ironlake_set_pipeconf(struct drm_crtc *crtc)
@@ -9723,6 +8427,8 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 
        fb = &intel_fb->base;
 
+       fb->dev = dev;
+
        val = I915_READ(PLANE_CTL(pipe, 0));
        if (!(val & PLANE_CTL_ENABLE))
                goto error;
@@ -9731,8 +8437,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
        fourcc = skl_format_to_fourcc(pixel_format,
                                      val & PLANE_CTL_ORDER_RGBX,
                                      val & PLANE_CTL_ALPHA_MASK);
-       fb->pixel_format = fourcc;
-       fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
+       fb->format = drm_format_info(fourcc);
 
        tiling = val & PLANE_CTL_TILED_MASK;
        switch (tiling) {
@@ -9765,18 +8470,19 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 
        val = I915_READ(PLANE_STRIDE(pipe, 0));
        stride_mult = intel_fb_stride_alignment(dev_priv, fb->modifier,
-                                               fb->pixel_format);
+                                               fb->format->format);
        fb->pitches[0] = (val & 0x3ff) * stride_mult;
 
-       aligned_height = intel_fb_align_height(dev, fb->height,
-                                              fb->pixel_format,
+       aligned_height = intel_fb_align_height(dev_priv,
+                                              fb->height,
+                                              fb->format->format,
                                               fb->modifier);
 
        plane_config->size = fb->pitches[0] * aligned_height;
 
        DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
                      pipe_name(pipe), fb->width, fb->height,
-                     fb->bits_per_pixel, base, fb->pitches[0],
+                     fb->format->cpp[0] * 8, base, fb->pitches[0],
                      plane_config->size);
 
        plane_config->fb = intel_fb;
@@ -9835,6 +8541,8 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
 
        fb = &intel_fb->base;
 
+       fb->dev = dev;
+
        if (INTEL_GEN(dev_priv) >= 4) {
                if (val & DISPPLANE_TILED) {
                        plane_config->tiling = I915_TILING_X;
@@ -9844,8 +8552,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
 
        pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
        fourcc = i9xx_format_to_fourcc(pixel_format);
-       fb->pixel_format = fourcc;
-       fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
+       fb->format = drm_format_info(fourcc);
 
        base = I915_READ(DSPSURF(pipe)) & 0xfffff000;
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
@@ -9865,15 +8572,16 @@ 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,
-                                              fb->pixel_format,
+       aligned_height = intel_fb_align_height(dev_priv,
+                                              fb->height,
+                                              fb->format->format,
                                               fb->modifier);
 
        plane_config->size = fb->pitches[0] * aligned_height;
 
        DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
                      pipe_name(pipe), fb->width, fb->height,
-                     fb->bits_per_pixel, base, fb->pitches[0],
+                     fb->format->cpp[0] * 8, base, fb->pitches[0],
                      plane_config->size);
 
        plane_config->fb = intel_fb;
@@ -10163,7 +8871,6 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
  */
 void hsw_enable_pc8(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        uint32_t val;
 
        DRM_DEBUG_KMS("Enabling package C8+\n");
@@ -10174,264 +8881,24 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv)
                I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
        }
 
-       lpt_disable_clkout_dp(dev);
-       hsw_disable_lcpll(dev_priv, true, true);
-}
-
-void hsw_disable_pc8(struct drm_i915_private *dev_priv)
-{
-       struct drm_device *dev = &dev_priv->drm;
-       uint32_t val;
-
-       DRM_DEBUG_KMS("Disabling package C8+\n");
-
-       hsw_restore_lcpll(dev_priv);
-       lpt_init_pch_refclk(dev);
-
-       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;
-}
-
-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;
-
-       broadwell_set_cdclk(dev, req_cdclk);
-}
-
-static int skl_modeset_calc_cdclk(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);
-       const int max_pixclk = ilk_max_pixel_rate(state);
-       int vco = intel_state->cdclk_pll_vco;
-       int cdclk;
-
-       /*
-        * FIXME should also account for plane ratio
-        * once 64bpp pixel formats are supported.
-        */
-       cdclk = skl_calc_cdclk(max_pixclk, vco);
-
-       /*
-        * 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;
-       }
-
-       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,
@@ -10525,7 +8992,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);
@@ -10567,7 +9034,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));
 
@@ -10576,7 +9043,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);
@@ -10594,7 +9061,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
@@ -10634,9 +9101,9 @@ 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_BROXTON(dev_priv))
+       else if (IS_GEN9_LP(dev_priv))
                bxt_get_ddi_pll(dev_priv, port, pipe_config);
        else
                haswell_get_ddi_pll(dev_priv, port, pipe_config);
@@ -10669,19 +9136,19 @@ 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;
 
        active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask);
 
-       if (IS_BROXTON(dev_priv) &&
+       if (IS_GEN9_LP(dev_priv) &&
            bxt_get_dsi_transcoder_state(crtc, pipe_config, &power_domain_mask)) {
                WARN_ON(active);
                active = true;
@@ -10701,7 +9168,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
                I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
 
        if (INTEL_GEN(dev_priv) >= 9) {
-               skl_init_scalers(dev_priv, crtc, pipe_config);
+               intel_crtc_init_scalers(crtc, pipe_config);
 
                pipe_config->scaler_state.scaler_id = -1;
                pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
@@ -10709,7 +9176,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
@@ -10882,7 +9349,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
 
        I915_WRITE(CURPOS(pipe), pos);
 
-       if (IS_845G(dev_priv) || IS_I865G(dev_priv))
+       if (IS_I845G(dev_priv) || IS_I865G(dev_priv))
                i845_update_cursor(crtc, base, plane_state);
        else
                i9xx_update_cursor(crtc, base, plane_state);
@@ -10900,11 +9367,11 @@ static bool cursor_size_ok(struct drm_i915_private *dev_priv,
         * the precision of the register. Everything else requires
         * square cursors, limited to a few power-of-two sizes.
         */
-       if (IS_845G(dev_priv) || IS_I865G(dev_priv)) {
+       if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
                if ((width & 63) != 0)
                        return false;
 
-               if (width > (IS_845G(dev_priv) ? 64 : 512))
+               if (width > (IS_I845G(dev_priv) ? 64 : 512))
                        return false;
 
                if (height > 1023)
@@ -10932,9 +9399,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;
@@ -10943,7 +9409,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;
 
@@ -10954,23 +9420,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)
 {
@@ -10994,7 +9443,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
        struct drm_i915_gem_object *obj;
        struct drm_mode_fb_cmd2 mode_cmd = { 0 };
 
-       obj = i915_gem_object_create(dev,
+       obj = i915_gem_object_create(to_i915(dev),
                                    intel_framebuffer_size_for_mode(mode, bpp));
        if (IS_ERR(obj))
                return ERR_CAST(obj);
@@ -11005,7 +9454,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);
 
@@ -11032,7 +9481,7 @@ mode_fits_in_fbdev(struct drm_device *dev,
 
        fb = &dev_priv->fbdev->fb->base;
        if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
-                                                              fb->bits_per_pixel))
+                                                              fb->format->cpp[0] * 8))
                return NULL;
 
        if (obj->base.size < mode->vdisplay * fb->pitches[0])
@@ -11060,7 +9509,7 @@ static int intel_modeset_setup_plane_state(struct drm_atomic_state *state,
                return PTR_ERR(plane_state);
 
        if (mode)
-               drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
+               drm_mode_get_hv_timing(mode, &hdisplay, &vdisplay);
        else
                hdisplay = vdisplay = 0;
 
@@ -11243,6 +9692,7 @@ found:
        }
 
        old->restore_state = restore_state;
+       drm_atomic_state_put(state);
 
        /* let the connector get through one full cycle before testing */
        intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
@@ -11522,7 +9972,7 @@ static void intel_unpin_work_fn(struct work_struct *__work)
                flush_work(&work->mmio_work);
 
        mutex_lock(&dev->struct_mutex);
-       intel_unpin_fb_obj(work->old_fb, primary->state->rotation);
+       intel_unpin_fb_vma(work->old_vma);
        i915_gem_object_put(work->pending_flip_obj);
        mutex_unlock(&dev->struct_mutex);
 
@@ -11690,14 +10140,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.
@@ -11706,13 +10154,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;
 }
@@ -11724,26 +10171,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;
 }
@@ -11755,25 +10199,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.
@@ -11781,7 +10222,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;
 }
@@ -11793,21 +10234,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
@@ -11817,7 +10254,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;
 }
@@ -11830,9 +10267,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) {
@@ -11876,9 +10312,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
@@ -11890,31 +10326,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;
 }
@@ -12106,6 +10539,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,
@@ -12134,7 +10568,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
                return -EBUSY;
 
        /* Can't change pixel format via MI display flips. */
-       if (fb->pixel_format != crtc->primary->fb->pixel_format)
+       if (fb->format != crtc->primary->fb->format)
                return -EINVAL;
 
        /*
@@ -12232,8 +10666,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
                goto cleanup_pending;
        }
 
-       work->gtt_offset = intel_fb_gtt_offset(fb, primary->state->rotation);
-       work->gtt_offset += intel_crtc->dspaddr_offset;
+       work->old_vma = to_intel_plane_state(primary->state)->vma;
+       to_intel_plane_state(primary->state)->vma = vma;
+
+       work->gtt_offset = i915_ggtt_offset(vma) + intel_crtc->dspaddr_offset;
        work->rotation = crtc->primary->state->rotation;
 
        /*
@@ -12251,7 +10687,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
                INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func);
                queue_work(system_unbound_wq, &work->mmio_work);
        } else {
-               request = i915_gem_request_alloc(engine, engine->last_context);
+               request = i915_gem_request_alloc(engine,
+                                                dev_priv->kernel_context);
                if (IS_ERR(request)) {
                        ret = PTR_ERR(request);
                        goto cleanup_unpin;
@@ -12287,7 +10724,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 cleanup_request:
        i915_add_request_no_flush(request);
 cleanup_unpin:
-       intel_unpin_fb_obj(fb, crtc->primary->state->rotation);
+       to_intel_plane_state(primary->state)->vma = work->old_vma;
+       intel_unpin_fb_vma(vma);
 cleanup_pending:
        atomic_dec(&intel_crtc->unpin_work_count);
 unlock:
@@ -12417,7 +10855,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
        }
 
        was_visible = old_plane_state->base.visible;
-       visible = to_intel_plane_state(plane_state)->base.visible;
+       visible = plane_state->visible;
 
        if (!was_crtc_enabled && WARN_ON(was_visible))
                was_visible = false;
@@ -12433,7 +10871,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
         * only combine the results from all planes in the current place?
         */
        if (!is_crtc_enabled)
-               to_intel_plane_state(plane_state)->base.visible = visible = false;
+               plane_state->visible = visible = false;
 
        if (!was_visible && !visible)
                return 0;
@@ -12755,9 +11193,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",
@@ -12779,39 +11218,7 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
        DRM_DEBUG_KMS("ips: %i, double wide: %i\n",
                      pipe_config->ips_enabled, pipe_config->double_wide);
 
-       if (IS_BROXTON(dev_priv)) {
-               DRM_DEBUG_KMS("dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
-                             "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
-                             "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
-                             pipe_config->dpll_hw_state.ebb0,
-                             pipe_config->dpll_hw_state.ebb4,
-                             pipe_config->dpll_hw_state.pll0,
-                             pipe_config->dpll_hw_state.pll1,
-                             pipe_config->dpll_hw_state.pll2,
-                             pipe_config->dpll_hw_state.pll3,
-                             pipe_config->dpll_hw_state.pll6,
-                             pipe_config->dpll_hw_state.pll8,
-                             pipe_config->dpll_hw_state.pll9,
-                             pipe_config->dpll_hw_state.pll10,
-                             pipe_config->dpll_hw_state.pcsdw12);
-       } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
-               DRM_DEBUG_KMS("dpll_hw_state: "
-                             "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
-                             pipe_config->dpll_hw_state.ctrl1,
-                             pipe_config->dpll_hw_state.cfgcr1,
-                             pipe_config->dpll_hw_state.cfgcr2);
-       } else if (HAS_DDI(dev_priv)) {
-               DRM_DEBUG_KMS("dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
-                             pipe_config->dpll_hw_state.wrpll,
-                             pipe_config->dpll_hw_state.spll);
-       } else {
-               DRM_DEBUG_KMS("dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
-                             "fp0: 0x%x, fp1: 0x%x\n",
-                             pipe_config->dpll_hw_state.dpll,
-                             pipe_config->dpll_hw_state.dpll_md,
-                             pipe_config->dpll_hw_state.fp0,
-                             pipe_config->dpll_hw_state.fp1);
-       }
+       intel_dpll_dump_hw_state(dev_priv, &pipe_config->dpll_hw_state);
 
        DRM_DEBUG_KMS("planes on this crtc\n");
        list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
@@ -12831,7 +11238,7 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
                DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d, fb = %ux%u format = %s\n",
                              plane->base.id, plane->name,
                              fb->base.id, fb->width, fb->height,
-                             drm_get_format_name(fb->pixel_format, &format_name));
+                             drm_get_format_name(fb->format->format, &format_name));
                if (INTEL_GEN(dev_priv) >= 9)
                        DRM_DEBUG_KMS("\tscaler:%d src %dx%d+%d+%d dst %dx%d+%d+%d\n",
                                      state->scaler_id,
@@ -12976,7 +11383,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
         * computation to clearly distinguish it from the adjusted mode, which
         * can be changed by the connectors in the below retry loop.
         */
-       drm_crtc_get_hv_timing(&pipe_config->base.mode,
+       drm_mode_get_hv_timing(&pipe_config->base.mode,
                               &pipe_config->pipe_src_w,
                               &pipe_config->pipe_src_h);
 
@@ -13047,8 +11454,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);
 
@@ -13155,6 +11565,31 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n,
        return false;
 }
 
+static void __printf(3, 4)
+pipe_config_err(bool adjust, const char *name, const char *format, ...)
+{
+       char *level;
+       unsigned int category;
+       struct va_format vaf;
+       va_list args;
+
+       if (adjust) {
+               level = KERN_DEBUG;
+               category = DRM_UT_KMS;
+       } else {
+               level = KERN_ERR;
+               category = DRM_UT_NONE;
+       }
+
+       va_start(args, format);
+       vaf.fmt = format;
+       vaf.va = &args;
+
+       drm_printk(level, category, "mismatch in %s %pV", name, &vaf);
+
+       va_end(args);
+}
+
 static bool
 intel_pipe_config_compare(struct drm_i915_private *dev_priv,
                          struct intel_crtc_state *current_config,
@@ -13163,17 +11598,9 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 {
        bool ret = true;
 
-#define INTEL_ERR_OR_DBG_KMS(fmt, ...) \
-       do { \
-               if (!adjust) \
-                       DRM_ERROR(fmt, ##__VA_ARGS__); \
-               else \
-                       DRM_DEBUG_KMS(fmt, ##__VA_ARGS__); \
-       } while (0)
-
 #define PIPE_CONF_CHECK_X(name)        \
        if (current_config->name != pipe_config->name) { \
-               INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+               pipe_config_err(adjust, __stringify(name), \
                          "(expected 0x%08x, found 0x%08x)\n", \
                          current_config->name, \
                          pipe_config->name); \
@@ -13182,7 +11609,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 
 #define PIPE_CONF_CHECK_I(name)        \
        if (current_config->name != pipe_config->name) { \
-               INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+               pipe_config_err(adjust, __stringify(name), \
                          "(expected %i, found %i)\n", \
                          current_config->name, \
                          pipe_config->name); \
@@ -13191,7 +11618,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 
 #define PIPE_CONF_CHECK_P(name)        \
        if (current_config->name != pipe_config->name) { \
-               INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+               pipe_config_err(adjust, __stringify(name), \
                          "(expected %p, found %p)\n", \
                          current_config->name, \
                          pipe_config->name); \
@@ -13202,7 +11629,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
        if (!intel_compare_link_m_n(&current_config->name, \
                                    &pipe_config->name,\
                                    adjust)) { \
-               INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+               pipe_config_err(adjust, __stringify(name), \
                          "(expected tu %i gmch %i/%i link %i/%i, " \
                          "found tu %i, gmch %i/%i link %i/%i)\n", \
                          current_config->name.tu, \
@@ -13228,7 +11655,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
                                    &pipe_config->name, adjust) && \
            !intel_compare_link_m_n(&current_config->alt_name, \
                                    &pipe_config->name, adjust)) { \
-               INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+               pipe_config_err(adjust, __stringify(name), \
                          "(expected tu %i gmch %i/%i link %i/%i, " \
                          "or tu %i gmch %i/%i link %i/%i, " \
                          "found tu %i, gmch %i/%i link %i/%i)\n", \
@@ -13252,8 +11679,9 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 
 #define PIPE_CONF_CHECK_FLAGS(name, mask)      \
        if ((current_config->name ^ pipe_config->name) & (mask)) { \
-               INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \
-                         "(expected %i, found %i)\n", \
+               pipe_config_err(adjust, __stringify(name), \
+                         "(%x) (expected %i, found %i)\n", \
+                         (mask), \
                          current_config->name & (mask), \
                          pipe_config->name & (mask)); \
                ret = false; \
@@ -13261,7 +11689,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 
 #define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
        if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
-               INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+               pipe_config_err(adjust, __stringify(name), \
                          "(expected %i, found %i)\n", \
                          current_config->name, \
                          pipe_config->name); \
@@ -13344,6 +11772,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 */
@@ -13378,7 +11807,6 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 #undef PIPE_CONF_CHECK_FLAGS
 #undef PIPE_CONF_CHECK_CLOCK_FUZZY
 #undef PIPE_CONF_QUIRK
-#undef INTEL_ERR_OR_DBG_KMS
 
        return ret;
 }
@@ -13636,6 +12064,8 @@ verify_crtc_state(struct drm_crtc *crtc,
                }
        }
 
+       intel_crtc_compute_pixel_rate(pipe_config);
+
        if (!new_crtc_state->active)
                return;
 
@@ -13679,9 +12109,9 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
        }
 
        if (!crtc) {
-               I915_STATE_WARN(pll->active_mask & ~pll->config.crtc_mask,
+               I915_STATE_WARN(pll->active_mask & ~pll->state.crtc_mask,
                                "more active pll users than references: %x vs %x\n",
-                               pll->active_mask, pll->config.crtc_mask);
+                               pll->active_mask, pll->state.crtc_mask);
 
                return;
        }
@@ -13697,11 +12127,11 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
                                "pll active mismatch (didn't expect pipe %c in active mask 0x%02x)\n",
                                pipe_name(drm_crtc_index(crtc)), pll->active_mask);
 
-       I915_STATE_WARN(!(pll->config.crtc_mask & crtc_mask),
+       I915_STATE_WARN(!(pll->state.crtc_mask & crtc_mask),
                        "pll enabled crtcs mismatch (expected 0x%x in 0x%02x)\n",
-                       crtc_mask, pll->config.crtc_mask);
+                       crtc_mask, pll->state.crtc_mask);
 
-       I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state,
+       I915_STATE_WARN(pll->on && memcmp(&pll->state.hw_state,
                                          &dpll_hw_state,
                                          sizeof(dpll_hw_state)),
                        "pll hw state mismatch\n");
@@ -13727,7 +12157,7 @@ verify_shared_dpll_state(struct drm_device *dev, struct drm_crtc *crtc,
                I915_STATE_WARN(pll->active_mask & crtc_mask,
                                "pll active mismatch (didn't expect pipe %c in active mask)\n",
                                pipe_name(drm_crtc_index(crtc)));
-               I915_STATE_WARN(pll->config.crtc_mask & crtc_mask,
+               I915_STATE_WARN(pll->state.crtc_mask & crtc_mask,
                                "pll enabled crtcs mismatch (found %x in enabled mask)\n",
                                pipe_name(drm_crtc_index(crtc)));
        }
@@ -13810,7 +12240,6 @@ static void intel_modeset_clear_plls(struct drm_atomic_state *state)
 {
        struct drm_device *dev = state->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_shared_dpll_config *shared_dpll = NULL;
        struct drm_crtc *crtc;
        struct drm_crtc_state *crtc_state;
        int i;
@@ -13831,10 +12260,7 @@ static void intel_modeset_clear_plls(struct drm_atomic_state *state)
                if (!old_dpll)
                        continue;
 
-               if (!shared_dpll)
-                       shared_dpll = intel_atomic_get_shared_dpll_state(state);
-
-               intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc);
+               intel_release_shared_dpll(old_dpll, intel_crtc, state);
        }
 }
 
@@ -13903,14 +12329,34 @@ static int haswell_mode_set_planes_workaround(struct drm_atomic_state *state)
        return 0;
 }
 
+static int intel_lock_all_pipes(struct drm_atomic_state *state)
+{
+       struct drm_crtc *crtc;
+
+       /* Add all pipes to the state */
+       for_each_crtc(state->dev, crtc) {
+               struct drm_crtc_state *crtc_state;
+
+               crtc_state = drm_atomic_get_crtc_state(state, crtc);
+               if (IS_ERR(crtc_state))
+                       return PTR_ERR(crtc_state);
+       }
+
+       return 0;
+}
+
 static int intel_modeset_all_pipes(struct drm_atomic_state *state)
 {
        struct drm_crtc *crtc;
-       struct drm_crtc_state *crtc_state;
-       int ret = 0;
 
-       /* add all active pipes to the state */
+       /*
+        * Add all pipes to the state, and force
+        * a modeset on all the active ones.
+        */
        for_each_crtc(state->dev, crtc) {
+               struct drm_crtc_state *crtc_state;
+               int ret;
+
                crtc_state = drm_atomic_get_crtc_state(state, crtc);
                if (IS_ERR(crtc_state))
                        return PTR_ERR(crtc_state);
@@ -13922,14 +12368,14 @@ static int intel_modeset_all_pipes(struct drm_atomic_state *state)
 
                ret = drm_atomic_add_affected_connectors(state, crtc);
                if (ret)
-                       break;
+                       return ret;
 
                ret = drm_atomic_add_affected_planes(state, crtc);
                if (ret)
-                       break;
+                       return ret;
        }
 
-       return ret;
+       return 0;
 }
 
 static int intel_modeset_checks(struct drm_atomic_state *state)
@@ -13947,6 +12393,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)
@@ -13966,26 +12414,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;
 
-               if (intel_state->dev_cdclk != dev_priv->cdclk_freq ||
-                   intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)
-                       ret = intel_modeset_all_pipes(state);
+               /*
+                * 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_cdclk_state_compare(&dev_priv->cdclk.logical,
+                                              &intel_state->cdclk.logical)) {
+                       ret = intel_lock_all_pipes(state);
+                       if (ret < 0)
+                               return ret;
+               }
 
-               if (ret < 0)
-                       return ret;
+               /* All pipes must be switched off while we change the cdclk. */
+               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);
@@ -14088,7 +12545,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);
@@ -14322,6 +12779,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;
@@ -14331,7 +12806,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;
 
@@ -14392,10 +12867,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
@@ -14488,6 +12960,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)
@@ -14512,8 +12986,14 @@ intel_atomic_commit_ready(struct i915_sw_fence *fence,
                break;
 
        case FENCE_FREE:
-               drm_atomic_state_put(&state->base);
-               break;
+               {
+                       struct intel_atomic_helper *helper =
+                               &to_i915(state->base.dev)->atomic_helper;
+
+                       if (llist_add(&state->freed, &helper->free_list))
+                               schedule_work(&helper->free_work);
+                       break;
+               }
        }
 
        return NOTIFY_DONE;
@@ -14568,14 +13048,15 @@ static int intel_atomic_commit(struct drm_device *dev,
 
        drm_atomic_helper_swap_state(state, true);
        dev_priv->wm.distrust_bios_wm = false;
-       intel_shared_dpll_commit(state);
+       intel_shared_dpll_swap_state(state);
        intel_atomic_track_fbs(state);
 
        if (intel_state->modeset) {
                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);
@@ -14675,9 +13156,10 @@ 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,
 };
 
 /**
@@ -14774,6 +13256,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
                        DRM_DEBUG_KMS("failed to pin object\n");
                        return PTR_ERR(vma);
                }
+
+               to_intel_plane_state(new_state)->vma = vma;
        }
 
        return 0;
@@ -14792,19 +13276,12 @@ void
 intel_cleanup_plane_fb(struct drm_plane *plane,
                       struct drm_plane_state *old_state)
 {
-       struct drm_i915_private *dev_priv = to_i915(plane->dev);
-       struct intel_plane_state *old_intel_state;
-       struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
-       struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
-
-       old_intel_state = to_intel_plane_state(old_state);
-
-       if (!obj && !old_obj)
-               return;
+       struct i915_vma *vma;
 
-       if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
-           !INTEL_INFO(dev_priv)->cursor_needs_physical))
-               intel_unpin_fb_obj(old_state->fb, old_state->rotation);
+       /* Should only be called after a successful intel_prepare_plane_fb()! */
+       vma = fetch_and_zero(&to_intel_plane_state(old_state)->vma);
+       if (vma)
+               intel_unpin_fb_vma(vma);
 }
 
 int
@@ -14817,7 +13294,7 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state
                return DRM_PLANE_HELPER_NO_SCALING;
 
        crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
-       cdclk = to_intel_atomic_state(crtc_state->base.state)->cdclk;
+       cdclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk;
 
        if (WARN_ON_ONCE(!crtc_clock || cdclk < crtc_clock))
                return DRM_PLANE_HELPER_NO_SCALING;
@@ -14941,6 +13418,141 @@ const struct drm_plane_funcs intel_plane_funcs = {
        .atomic_destroy_state = intel_plane_destroy_state,
 };
 
+static int
+intel_legacy_cursor_update(struct drm_plane *plane,
+                          struct drm_crtc *crtc,
+                          struct drm_framebuffer *fb,
+                          int crtc_x, int crtc_y,
+                          unsigned int crtc_w, unsigned int crtc_h,
+                          uint32_t src_x, uint32_t src_y,
+                          uint32_t src_w, uint32_t src_h)
+{
+       struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+       int ret;
+       struct drm_plane_state *old_plane_state, *new_plane_state;
+       struct intel_plane *intel_plane = to_intel_plane(plane);
+       struct drm_framebuffer *old_fb;
+       struct drm_crtc_state *crtc_state = crtc->state;
+       struct i915_vma *old_vma;
+
+       /*
+        * When crtc is inactive or there is a modeset pending,
+        * wait for it to complete in the slowpath
+        */
+       if (!crtc_state->active || needs_modeset(crtc_state) ||
+           to_intel_crtc_state(crtc_state)->update_pipe)
+               goto slow;
+
+       old_plane_state = plane->state;
+
+       /*
+        * If any parameters change that may affect watermarks,
+        * take the slowpath. Only changing fb or position should be
+        * in the fastpath.
+        */
+       if (old_plane_state->crtc != crtc ||
+           old_plane_state->src_w != src_w ||
+           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)
+               goto slow;
+
+       new_plane_state = intel_plane_duplicate_state(plane);
+       if (!new_plane_state)
+               return -ENOMEM;
+
+       drm_atomic_set_fb_for_plane(new_plane_state, fb);
+
+       new_plane_state->src_x = src_x;
+       new_plane_state->src_y = src_y;
+       new_plane_state->src_w = src_w;
+       new_plane_state->src_h = src_h;
+       new_plane_state->crtc_x = crtc_x;
+       new_plane_state->crtc_y = crtc_y;
+       new_plane_state->crtc_w = crtc_w;
+       new_plane_state->crtc_h = crtc_h;
+
+       ret = intel_plane_atomic_check_with_state(to_intel_crtc_state(crtc->state),
+                                                 to_intel_plane_state(new_plane_state));
+       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;
+
+       if (INTEL_INFO(dev_priv)->cursor_needs_physical) {
+               int align = IS_I830(dev_priv) ? 16 * 1024 : 256;
+
+               ret = i915_gem_object_attach_phys(intel_fb_obj(fb), align);
+               if (ret) {
+                       DRM_DEBUG_KMS("failed to attach phys object\n");
+                       goto out_unlock;
+               }
+       } else {
+               struct i915_vma *vma;
+
+               vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation);
+               if (IS_ERR(vma)) {
+                       DRM_DEBUG_KMS("failed to pin object\n");
+
+                       ret = PTR_ERR(vma);
+                       goto out_unlock;
+               }
+
+               to_intel_plane_state(new_plane_state)->vma = vma;
+       }
+
+       old_fb = old_plane_state->fb;
+       old_vma = to_intel_plane_state(old_plane_state)->vma;
+
+       i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
+                         intel_plane->frontbuffer_bit);
+
+       /* Swap plane state */
+       new_plane_state->fence = old_plane_state->fence;
+       *to_intel_plane_state(old_plane_state) = *to_intel_plane_state(new_plane_state);
+       new_plane_state->fence = NULL;
+       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));
+
+       intel_cleanup_plane_fb(plane, new_plane_state);
+
+out_unlock:
+       mutex_unlock(&dev_priv->drm.struct_mutex);
+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,
+                                             src_x, src_y, src_w, src_h);
+}
+
+static const struct drm_plane_funcs intel_cursor_plane_funcs = {
+       .update_plane = intel_legacy_cursor_update,
+       .disable_plane = drm_atomic_helper_disable_plane,
+       .destroy = intel_plane_destroy,
+       .set_property = drm_atomic_helper_plane_set_property,
+       .atomic_get_property = intel_plane_atomic_get_property,
+       .atomic_set_property = intel_plane_atomic_set_property,
+       .atomic_duplicate_state = intel_plane_duplicate_state,
+       .atomic_destroy_state = intel_plane_destroy_state,
+};
+
 static struct intel_plane *
 intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
 {
@@ -14980,6 +13592,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
                primary->plane = (enum plane) !pipe;
        else
                primary->plane = (enum plane) pipe;
+       primary->id = PLANE_PRIMARY;
        primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
        primary->check_plane = intel_check_primary_plane;
 
@@ -15146,7 +13759,7 @@ intel_update_cursor_plane(struct drm_plane *plane,
        if (!obj)
                addr = 0;
        else if (!INTEL_INFO(dev_priv)->cursor_needs_physical)
-               addr = i915_gem_object_ggtt_offset(obj, NULL);
+               addr = intel_plane_ggtt_offset(state);
        else
                addr = obj->phys_handle->busaddr;
 
@@ -15179,13 +13792,14 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
        cursor->max_downscale = 1;
        cursor->pipe = pipe;
        cursor->plane = pipe;
+       cursor->id = PLANE_CURSOR;
        cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
        cursor->check_plane = intel_check_cursor_plane;
        cursor->update_plane = intel_update_cursor_plane;
        cursor->disable_plane = intel_disable_cursor_plane;
 
        ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base,
-                                      0, &intel_plane_funcs,
+                                      0, &intel_cursor_plane_funcs,
                                       intel_cursor_formats,
                                       ARRAY_SIZE(intel_cursor_formats),
                                       DRM_PLANE_TYPE_CURSOR,
@@ -15213,14 +13827,18 @@ fail:
        return ERR_PTR(ret);
 }
 
-static void skl_init_scalers(struct drm_i915_private *dev_priv,
-                            struct intel_crtc *crtc,
-                            struct intel_crtc_state *crtc_state)
+static void intel_crtc_init_scalers(struct intel_crtc *crtc,
+                                   struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc_scaler_state *scaler_state =
                &crtc_state->scaler_state;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        int i;
 
+       crtc->num_scalers = dev_priv->info.num_scalers[crtc->pipe];
+       if (!crtc->num_scalers)
+               return;
+
        for (i = 0; i < crtc->num_scalers; i++) {
                struct intel_scaler *scaler = &scaler_state->scalers[i];
 
@@ -15252,21 +13870,12 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
        intel_crtc->base.state = &crtc_state->base;
        crtc_state->base.crtc = &intel_crtc->base;
 
-       /* initialize shared scalers */
-       if (INTEL_GEN(dev_priv) >= 9) {
-               if (pipe == PIPE_C)
-                       intel_crtc->num_scalers = 1;
-               else
-                       intel_crtc->num_scalers = SKL_NUM_SCALERS;
-
-               skl_init_scalers(dev_priv, intel_crtc, crtc_state);
-       }
-
        primary = intel_primary_plane_create(dev_priv, pipe);
        if (IS_ERR(primary)) {
                ret = PTR_ERR(primary);
                goto fail;
        }
+       intel_crtc->plane_ids_mask |= BIT(primary->id);
 
        for_each_sprite(dev_priv, pipe, sprite) {
                struct intel_plane *plane;
@@ -15276,6 +13885,7 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
                        ret = PTR_ERR(plane);
                        goto fail;
                }
+               intel_crtc->plane_ids_mask |= BIT(plane->id);
        }
 
        cursor = intel_cursor_plane_create(dev_priv, pipe);
@@ -15283,6 +13893,7 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
                ret = PTR_ERR(cursor);
                goto fail;
        }
+       intel_crtc->plane_ids_mask |= BIT(cursor->id);
 
        ret = drm_crtc_init_with_planes(&dev_priv->drm, &intel_crtc->base,
                                        &primary->base, &cursor->base,
@@ -15300,6 +13911,9 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
 
        intel_crtc->wm.cxsr_allowed = true;
 
+       /* initialize shared scalers */
+       intel_crtc_init_scalers(intel_crtc, crtc_state);
+
        BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
               dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
        dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = intel_crtc;
@@ -15436,7 +14050,7 @@ void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv)
 
 static void intel_pps_init(struct drm_i915_private *dev_priv)
 {
-       if (HAS_PCH_SPLIT(dev_priv) || IS_BROXTON(dev_priv))
+       if (HAS_PCH_SPLIT(dev_priv) || IS_GEN9_LP(dev_priv))
                dev_priv->pps_mmio_base = PCH_PPS_BASE;
        else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                dev_priv->pps_mmio_base = VLV_PPS_BASE;
@@ -15446,9 +14060,8 @@ static void intel_pps_init(struct drm_i915_private *dev_priv)
        intel_pps_unlock_regs_wa(dev_priv);
 }
 
-static void intel_setup_outputs(struct drm_device *dev)
+static void intel_setup_outputs(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_encoder *encoder;
        bool dpd_is_edp = false;
 
@@ -15459,22 +14072,22 @@ static void intel_setup_outputs(struct drm_device *dev)
         * prevent the registeration of both eDP and LVDS and the incorrect
         * sharing of the PPS.
         */
-       intel_lvds_init(dev);
+       intel_lvds_init(dev_priv);
 
        if (intel_crt_present(dev_priv))
-               intel_crt_init(dev);
+               intel_crt_init(dev_priv);
 
-       if (IS_BROXTON(dev_priv)) {
+       if (IS_GEN9_LP(dev_priv)) {
                /*
                 * FIXME: Broxton doesn't support port detection via the
                 * DDI_BUF_CTL_A or SFUSE_STRAP registers, find another way to
                 * detect the ports.
                 */
-               intel_ddi_init(dev, PORT_A);
-               intel_ddi_init(dev, PORT_B);
-               intel_ddi_init(dev, PORT_C);
+               intel_ddi_init(dev_priv, PORT_A);
+               intel_ddi_init(dev_priv, PORT_B);
+               intel_ddi_init(dev_priv, PORT_C);
 
-               intel_dsi_init(dev);
+               intel_dsi_init(dev_priv);
        } else if (HAS_DDI(dev_priv)) {
                int found;
 
@@ -15485,55 +14098,55 @@ static void intel_setup_outputs(struct drm_device *dev)
                 */
                found = I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
                /* WaIgnoreDDIAStrap: skl */
-               if (found || IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
-                       intel_ddi_init(dev, PORT_A);
+               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
                 * register */
                found = I915_READ(SFUSE_STRAP);
 
                if (found & SFUSE_STRAP_DDIB_DETECTED)
-                       intel_ddi_init(dev, PORT_B);
+                       intel_ddi_init(dev_priv, PORT_B);
                if (found & SFUSE_STRAP_DDIC_DETECTED)
-                       intel_ddi_init(dev, PORT_C);
+                       intel_ddi_init(dev_priv, PORT_C);
                if (found & SFUSE_STRAP_DDID_DETECTED)
-                       intel_ddi_init(dev, PORT_D);
+                       intel_ddi_init(dev_priv, PORT_D);
                /*
                 * 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))
-                       intel_ddi_init(dev, PORT_E);
+                       intel_ddi_init(dev_priv, PORT_E);
 
        } else if (HAS_PCH_SPLIT(dev_priv)) {
                int found;
                dpd_is_edp = intel_dp_is_edp(dev_priv, PORT_D);
 
                if (has_edp_a(dev_priv))
-                       intel_dp_init(dev, DP_A, PORT_A);
+                       intel_dp_init(dev_priv, DP_A, PORT_A);
 
                if (I915_READ(PCH_HDMIB) & SDVO_DETECTED) {
                        /* PCH SDVOB multiplex with HDMIB */
-                       found = intel_sdvo_init(dev, PCH_SDVOB, PORT_B);
+                       found = intel_sdvo_init(dev_priv, PCH_SDVOB, PORT_B);
                        if (!found)
-                               intel_hdmi_init(dev, PCH_HDMIB, PORT_B);
+                               intel_hdmi_init(dev_priv, PCH_HDMIB, PORT_B);
                        if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
-                               intel_dp_init(dev, PCH_DP_B, PORT_B);
+                               intel_dp_init(dev_priv, PCH_DP_B, PORT_B);
                }
 
                if (I915_READ(PCH_HDMIC) & SDVO_DETECTED)
-                       intel_hdmi_init(dev, PCH_HDMIC, PORT_C);
+                       intel_hdmi_init(dev_priv, PCH_HDMIC, PORT_C);
 
                if (!dpd_is_edp && I915_READ(PCH_HDMID) & SDVO_DETECTED)
-                       intel_hdmi_init(dev, PCH_HDMID, PORT_D);
+                       intel_hdmi_init(dev_priv, PCH_HDMID, PORT_D);
 
                if (I915_READ(PCH_DP_C) & DP_DETECTED)
-                       intel_dp_init(dev, PCH_DP_C, PORT_C);
+                       intel_dp_init(dev_priv, PCH_DP_C, PORT_C);
 
                if (I915_READ(PCH_DP_D) & DP_DETECTED)
-                       intel_dp_init(dev, PCH_DP_D, PORT_D);
+                       intel_dp_init(dev_priv, PCH_DP_D, PORT_D);
        } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                bool has_edp, has_port;
 
@@ -15555,16 +14168,16 @@ static void intel_setup_outputs(struct drm_device *dev)
                has_edp = intel_dp_is_edp(dev_priv, PORT_B);
                has_port = intel_bios_is_port_present(dev_priv, PORT_B);
                if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port)
-                       has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B);
+                       has_edp &= intel_dp_init(dev_priv, VLV_DP_B, PORT_B);
                if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
-                       intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
+                       intel_hdmi_init(dev_priv, VLV_HDMIB, PORT_B);
 
                has_edp = intel_dp_is_edp(dev_priv, PORT_C);
                has_port = intel_bios_is_port_present(dev_priv, PORT_C);
                if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port)
-                       has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C);
+                       has_edp &= intel_dp_init(dev_priv, VLV_DP_C, PORT_C);
                if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp)
-                       intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
+                       intel_hdmi_init(dev_priv, VLV_HDMIC, PORT_C);
 
                if (IS_CHERRYVIEW(dev_priv)) {
                        /*
@@ -15573,75 +14186,74 @@ static void intel_setup_outputs(struct drm_device *dev)
                         */
                        has_port = intel_bios_is_port_present(dev_priv, PORT_D);
                        if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port)
-                               intel_dp_init(dev, CHV_DP_D, PORT_D);
+                               intel_dp_init(dev_priv, CHV_DP_D, PORT_D);
                        if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port)
-                               intel_hdmi_init(dev, CHV_HDMID, PORT_D);
+                               intel_hdmi_init(dev_priv, CHV_HDMID, PORT_D);
                }
 
-               intel_dsi_init(dev);
+               intel_dsi_init(dev_priv);
        } else if (!IS_GEN2(dev_priv) && !IS_PINEVIEW(dev_priv)) {
                bool found = false;
 
                if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
                        DRM_DEBUG_KMS("probing SDVOB\n");
-                       found = intel_sdvo_init(dev, GEN3_SDVOB, PORT_B);
+                       found = intel_sdvo_init(dev_priv, GEN3_SDVOB, PORT_B);
                        if (!found && IS_G4X(dev_priv)) {
                                DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
-                               intel_hdmi_init(dev, GEN4_HDMIB, PORT_B);
+                               intel_hdmi_init(dev_priv, GEN4_HDMIB, PORT_B);
                        }
 
                        if (!found && IS_G4X(dev_priv))
-                               intel_dp_init(dev, DP_B, PORT_B);
+                               intel_dp_init(dev_priv, DP_B, PORT_B);
                }
 
                /* Before G4X SDVOC doesn't have its own detect register */
 
                if (I915_READ(GEN3_SDVOB) & SDVO_DETECTED) {
                        DRM_DEBUG_KMS("probing SDVOC\n");
-                       found = intel_sdvo_init(dev, GEN3_SDVOC, PORT_C);
+                       found = intel_sdvo_init(dev_priv, GEN3_SDVOC, PORT_C);
                }
 
                if (!found && (I915_READ(GEN3_SDVOC) & SDVO_DETECTED)) {
 
                        if (IS_G4X(dev_priv)) {
                                DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
-                               intel_hdmi_init(dev, GEN4_HDMIC, PORT_C);
+                               intel_hdmi_init(dev_priv, GEN4_HDMIC, PORT_C);
                        }
                        if (IS_G4X(dev_priv))
-                               intel_dp_init(dev, DP_C, PORT_C);
+                               intel_dp_init(dev_priv, DP_C, PORT_C);
                }
 
                if (IS_G4X(dev_priv) && (I915_READ(DP_D) & DP_DETECTED))
-                       intel_dp_init(dev, DP_D, PORT_D);
+                       intel_dp_init(dev_priv, DP_D, PORT_D);
        } else if (IS_GEN2(dev_priv))
-               intel_dvo_init(dev);
+               intel_dvo_init(dev_priv);
 
        if (SUPPORTS_TV(dev_priv))
-               intel_tv_init(dev);
+               intel_tv_init(dev_priv);
 
-       intel_psr_init(dev);
+       intel_psr_init(dev_priv);
 
-       for_each_intel_encoder(dev, encoder) {
+       for_each_intel_encoder(&dev_priv->drm, encoder) {
                encoder->base.possible_crtcs = encoder->crtc_mask;
                encoder->base.possible_clones =
                        intel_encoder_clones(encoder);
        }
 
-       intel_init_pch_refclk(dev);
+       intel_init_pch_refclk(dev_priv);
 
-       drm_helper_move_panel_connectors_to_head(dev);
+       drm_helper_move_panel_connectors_to_head(&dev_priv->drm);
 }
 
 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);
-       WARN_ON(!intel_fb->obj->framebuffer_references--);
+
+       WARN_ON(atomic_dec_return(&intel_fb->obj->framebuffer_references) < 0);
        i915_gem_object_put(intel_fb->obj);
-       mutex_unlock(&dev->struct_mutex);
+
        kfree(intel_fb);
 }
 
@@ -15689,7 +14301,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);
@@ -15698,8 +14310,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)
@@ -15717,18 +14328,17 @@ 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);
+       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
        unsigned int tiling = i915_gem_object_get_tiling(obj);
-       int ret;
        u32 pitch_limit, stride_alignment;
        struct drm_format_name_buf format_name;
+       int ret = -EINVAL;
 
-       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+       atomic_inc(&obj->framebuffer_references);
 
        if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
                /*
@@ -15738,14 +14348,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;
                }
        }
 
@@ -15756,7 +14366,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:
@@ -15764,7 +14374,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;
        }
 
        /*
@@ -15783,7 +14393,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],
@@ -15793,7 +14403,7 @@ 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;
        }
 
        /*
@@ -15805,7 +14415,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
                DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
                          mode_cmd->pitches[0],
                          i915_gem_object_get_stride(obj));
-               return -EINVAL;
+               goto err;
        }
 
        /* Reject formats not supported by any plane early. */
@@ -15864,24 +14474,29 @@ static int intel_framebuffer_init(struct drm_device *dev,
 
        /* FIXME need to adjust LINOFF/TILEOFF accordingly. */
        if (mode_cmd->offsets[0] != 0)
-               return -EINVAL;
+               goto err;
 
-       drm_helper_mode_fill_fb_struct(&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;
 
-       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:
+       atomic_dec(&obj->framebuffer_references);
+       return ret;
 }
 
 static struct drm_framebuffer *
@@ -15897,13 +14512,24 @@ 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);
 
        return fb;
 }
 
+static void intel_atomic_state_free(struct drm_atomic_state *state)
+{
+       struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+
+       drm_atomic_state_default_release(state);
+
+       i915_sw_fence_fini(&intel_state->commit_ready);
+
+       kfree(state);
+}
+
 static const struct drm_mode_config_funcs intel_mode_funcs = {
        .fb_create = intel_user_framebuffer_create,
        .output_poll_changed = intel_fbdev_output_poll_changed,
@@ -15911,6 +14537,7 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
        .atomic_commit = intel_atomic_commit,
        .atomic_state_alloc = intel_atomic_state_alloc,
        .atomic_state_clear = intel_atomic_state_clear,
+       .atomic_state_free = intel_atomic_state_free,
 };
 
 /**
@@ -15919,6 +14546,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 =
@@ -15987,62 +14616,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_BROXTON(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_BROADWATER(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_CRESTLINE(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_845G(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)) {
@@ -16054,28 +14627,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_BROXTON(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
@@ -16302,8 +14853,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);
 }
@@ -16411,6 +14961,9 @@ 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_worker);
+
        intel_init_quirks(dev);
 
        intel_init_pm(dev_priv);
@@ -16447,8 +15000,8 @@ int intel_modeset_init(struct drm_device *dev)
                dev->mode_config.max_height = 8192;
        }
 
-       if (IS_845G(dev_priv) || IS_I865G(dev_priv)) {
-               dev->mode_config.cursor_width = IS_845G(dev_priv) ? 64 : 512;
+       if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
+               dev->mode_config.cursor_width = IS_I845G(dev_priv) ? 64 : 512;
                dev->mode_config.cursor_height = 1023;
        } else if (IS_GEN2(dev_priv)) {
                dev->mode_config.cursor_width = GEN2_CURSOR_WIDTH;
@@ -16476,7 +15029,7 @@ 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;
+       dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw;
 
        intel_shared_dpll_init(dev);
 
@@ -16485,7 +15038,7 @@ int intel_modeset_init(struct drm_device *dev)
 
        /* Just disable it once at startup */
        i915_disable_vga(dev_priv);
-       intel_setup_outputs(dev);
+       intel_setup_outputs(dev_priv);
 
        drm_modeset_lock_all(dev);
        intel_modeset_setup_hw_state(dev);
@@ -16638,7 +15191,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                 * Temporarily change the plane mapping and disable everything
                 * ...  */
                plane = crtc->plane;
-               to_intel_plane_state(crtc->base.primary->state)->base.visible = true;
+               crtc->base.primary->state->visible = true;
                crtc->plane = !plane;
                intel_crtc_disable_noatomic(&crtc->base);
                crtc->plane = plane;
@@ -16790,7 +15343,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
        dev_priv->active_crtcs = 0;
 
        for_each_intel_crtc(dev, crtc) {
-               struct intel_crtc_state *crtc_state = crtc->config;
+               struct intel_crtc_state *crtc_state =
+                       to_intel_crtc_state(crtc->base.state);
 
                __drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
                memset(crtc_state, 0, sizeof(*crtc_state));
@@ -16809,34 +15363,41 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 
                DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
                              crtc->base.base.id, crtc->base.name,
-                             enableddisabled(crtc->active));
+                             enableddisabled(crtc_state->base.active));
        }
 
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
 
                pll->on = pll->funcs.get_hw_state(dev_priv, pll,
-                                                 &pll->config.hw_state);
-               pll->config.crtc_mask = 0;
+                                                 &pll->state.hw_state);
+               pll->state.crtc_mask = 0;
                for_each_intel_crtc(dev, crtc) {
-                       if (crtc->active && crtc->config->shared_dpll == pll)
-                               pll->config.crtc_mask |= 1 << crtc->pipe;
+                       struct intel_crtc_state *crtc_state =
+                               to_intel_crtc_state(crtc->base.state);
+
+                       if (crtc_state->base.active &&
+                           crtc_state->shared_dpll == pll)
+                               pll->state.crtc_mask |= 1 << crtc->pipe;
                }
-               pll->active_mask = pll->config.crtc_mask;
+               pll->active_mask = pll->state.crtc_mask;
 
                DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
-                             pll->name, pll->config.crtc_mask, pll->on);
+                             pll->name, pll->state.crtc_mask, pll->on);
        }
 
        for_each_intel_encoder(dev, encoder) {
                pipe = 0;
 
                if (encoder->get_hw_state(encoder, &pipe)) {
+                       struct intel_crtc_state *crtc_state;
+
                        crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
+                       crtc_state = to_intel_crtc_state(crtc->base.state);
 
                        encoder->base.crtc = &crtc->base;
-                       crtc->config->output_types |= 1 << encoder->type;
-                       encoder->get_config(encoder, crtc->config);
+                       crtc_state->output_types |= 1 << encoder->type;
+                       encoder->get_config(encoder, crtc_state);
                } else {
                        encoder->base.crtc = NULL;
                }
@@ -16877,14 +15438,16 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
        }
 
        for_each_intel_crtc(dev, crtc) {
+               struct intel_crtc_state *crtc_state =
+                       to_intel_crtc_state(crtc->base.state);
                int pixclk = 0;
 
-               crtc->base.hwmode = crtc->config->base.adjusted_mode;
+               crtc->base.hwmode = crtc_state->base.adjusted_mode;
 
                memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
-               if (crtc->base.state->active) {
-                       intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
-                       intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
+               if (crtc_state->base.active) {
+                       intel_mode_from_pipe_config(&crtc->base.mode, crtc_state);
+                       intel_mode_from_pipe_config(&crtc_state->base.adjusted_mode, crtc_state);
                        WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
 
                        /*
@@ -16892,29 +15455,22 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                         * the atomic core happy. It wants a valid mode if the
                         * crtc's enabled, so we do the above call.
                         *
-                        * At this point some state updated by the connectors
-                        * in their ->detect() callback has not run yet, so
-                        * no recalculation can be done yet.
-                        *
-                        * Even if we could do a recalculation and modeset
-                        * right now it would cause a double modeset if
-                        * fbdev or userspace chooses a different initial mode.
-                        *
-                        * If that happens, someone indicated they wanted a
-                        * mode change, which means it's safe to do a full
-                        * recalculation.
+                        * But we don't set all the derived state fully, hence
+                        * set a flag to indicate that a full recalculation is
+                        * needed on the next commit.
                         */
-                       crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
+                       crtc_state->base.mode.private_flags = I915_MODE_FLAG_INHERITED;
+
+                       intel_crtc_compute_pixel_rate(crtc_state);
 
-                       if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-                               pixclk = ilk_pipe_pixel_rate(crtc->config);
-                       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-                               pixclk = crtc->config->base.adjusted_mode.crtc_clock;
+                       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);
 
                        /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
-                       if (IS_BROADWELL(dev_priv) && crtc->config->ips_enabled)
+                       if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
                                pixclk = DIV_ROUND_UP(pixclk * 100, 95);
 
                        drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
@@ -16923,7 +15479,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 
                dev_priv->min_pixclk[crtc->pipe] = pixclk;
 
-               intel_pipe_config_sanity_check(dev_priv, crtc->config);
+               intel_pipe_config_sanity_check(dev_priv, crtc_state);
        }
 }
 
@@ -16976,7 +15532,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
                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))
@@ -16984,6 +15540,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);
 }
 
@@ -17024,47 +15582,19 @@ void intel_display_resume(struct drm_device *dev)
 
        if (ret)
                DRM_ERROR("Restoring old state failed with %i\n", ret);
-       drm_atomic_state_put(state);
+       if (state)
+               drm_atomic_state_put(state);
 }
 
 void intel_modeset_gem_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct drm_crtc *c;
-       struct drm_i915_gem_object *obj;
 
        intel_init_gt_powersave(dev_priv);
 
        intel_modeset_init_hw(dev);
 
        intel_setup_overlay(dev_priv);
-
-       /*
-        * Make sure any fbs we allocated at startup are properly
-        * pinned & fenced.  When we do the allocation it's too early
-        * for this.
-        */
-       for_each_crtc(dev, c) {
-               struct i915_vma *vma;
-
-               obj = intel_fb_obj(c->primary->fb);
-               if (obj == NULL)
-                       continue;
-
-               mutex_lock(&dev->struct_mutex);
-               vma = intel_pin_and_fence_fb_obj(c->primary->fb,
-                                                c->primary->state->rotation);
-               mutex_unlock(&dev->struct_mutex);
-               if (IS_ERR(vma)) {
-                       DRM_ERROR("failed to pin boot fb on pipe %d\n",
-                                 to_intel_crtc(c)->pipe);
-                       drm_framebuffer_unreference(c->primary->fb);
-                       c->primary->fb = NULL;
-                       c->primary->crtc = c->primary->state->crtc = NULL;
-                       update_state_fb(c->primary);
-                       c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
-               }
-       }
 }
 
 int intel_connector_register(struct drm_connector *connector)
@@ -17094,6 +15624,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
 
+       flush_work(&dev_priv->atomic_helper.free_work);
+       WARN_ON(!llist_empty(&dev_priv->atomic_helper.free_list));
+
        intel_disable_gt_powersave(dev_priv);
 
        /*
@@ -17122,7 +15655,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
 
        intel_cleanup_gt_powersave(dev_priv);
 
-       intel_teardown_gmbus(dev);
+       intel_teardown_gmbus(dev_priv);
 }
 
 void intel_connector_attach_encoder(struct intel_connector *connector,
@@ -17292,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)