drm/i915: Drop redundant watermark programming
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / intel_display.c
index cf418be7d30a52d0e25ac42201b61b0e42f16dbe..f2df9b16d85738b950721e23cd18ced8e590f7e5 100644 (file)
@@ -72,6 +72,10 @@ static const uint32_t skl_primary_formats[] = {
        DRM_FORMAT_ABGR8888,
        DRM_FORMAT_XRGB2101010,
        DRM_FORMAT_XBGR2101010,
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_YVYU,
+       DRM_FORMAT_UYVY,
+       DRM_FORMAT_VYUY,
 };
 
 /* Cursor formats */
@@ -108,6 +112,9 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
        struct intel_crtc_state *crtc_state);
 static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
                           int num_connectors);
+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);
 
 typedef struct {
@@ -125,6 +132,42 @@ struct intel_limit {
        intel_p2_t          p2;
 };
 
+/* returns HPLL frequency in kHz */
+static int valleyview_get_vco(struct drm_i915_private *dev_priv)
+{
+       int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
+
+       /* Obtain SKU information */
+       mutex_lock(&dev_priv->sb_lock);
+       hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
+               CCK_FUSE_HPLL_FREQ_MASK;
+       mutex_unlock(&dev_priv->sb_lock);
+
+       return vco_freq[hpll_freq] * 1000;
+}
+
+static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
+                                 const char *name, u32 reg)
+{
+       u32 val;
+       int divider;
+
+       if (dev_priv->hpll_freq == 0)
+               dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
+
+       mutex_lock(&dev_priv->sb_lock);
+       val = vlv_cck_read(dev_priv, reg);
+       mutex_unlock(&dev_priv->sb_lock);
+
+       divider = val & CCK_FREQUENCY_VALUES;
+
+       WARN((val & CCK_FREQUENCY_STATUS) !=
+            (divider << CCK_FREQUENCY_STATUS_SHIFT),
+            "%s change in progress\n", name);
+
+       return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1);
+}
+
 int
 intel_pch_rawclk(struct drm_device *dev)
 {
@@ -135,6 +178,50 @@ intel_pch_rawclk(struct drm_device *dev)
        return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK;
 }
 
+/* hrawclock is 1/4 the FSB frequency */
+int intel_hrawclk(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       uint32_t clkcfg;
+
+       /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */
+       if (IS_VALLEYVIEW(dev))
+               return 200;
+
+       clkcfg = I915_READ(CLKCFG);
+       switch (clkcfg & CLKCFG_FSB_MASK) {
+       case CLKCFG_FSB_400:
+               return 100;
+       case CLKCFG_FSB_533:
+               return 133;
+       case CLKCFG_FSB_667:
+               return 166;
+       case CLKCFG_FSB_800:
+               return 200;
+       case CLKCFG_FSB_1067:
+               return 266;
+       case CLKCFG_FSB_1333:
+               return 333;
+       /* these two are just a guess; one of them might be right */
+       case CLKCFG_FSB_1600:
+       case CLKCFG_FSB_1600_ALT:
+               return 400;
+       default:
+               return 133;
+       }
+}
+
+static void intel_update_czclk(struct drm_i915_private *dev_priv)
+{
+       if (!IS_VALLEYVIEW(dev_priv))
+               return;
+
+       dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk",
+                                                     CCK_CZ_CLOCK_CONTROL);
+
+       DRM_DEBUG_DRIVER("CZ clock rate: %d kHz\n", dev_priv->czclk_freq);
+}
+
 static inline u32 /* units of 100MHz */
 intel_fdi_link_freq(struct drm_device *dev)
 {
@@ -1061,54 +1148,6 @@ static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
        }
 }
 
-/*
- * ibx_digital_port_connected - is the specified port connected?
- * @dev_priv: i915 private structure
- * @port: the port to test
- *
- * Returns true if @port is connected, false otherwise.
- */
-bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
-                               struct intel_digital_port *port)
-{
-       u32 bit;
-
-       if (HAS_PCH_IBX(dev_priv->dev)) {
-               switch (port->port) {
-               case PORT_B:
-                       bit = SDE_PORTB_HOTPLUG;
-                       break;
-               case PORT_C:
-                       bit = SDE_PORTC_HOTPLUG;
-                       break;
-               case PORT_D:
-                       bit = SDE_PORTD_HOTPLUG;
-                       break;
-               default:
-                       return true;
-               }
-       } else {
-               switch (port->port) {
-               case PORT_B:
-                       bit = SDE_PORTB_HOTPLUG_CPT;
-                       break;
-               case PORT_C:
-                       bit = SDE_PORTC_HOTPLUG_CPT;
-                       break;
-               case PORT_D:
-                       bit = SDE_PORTD_HOTPLUG_CPT;
-                       break;
-               case PORT_E:
-                       bit = SDE_PORTE_HOTPLUG_SPT;
-                       break;
-               default:
-                       return true;
-               }
-       }
-
-       return I915_READ(SDEISR) & bit;
-}
-
 static const char *state_string(bool enabled)
 {
        return enabled ? "on" : "off";
@@ -1303,7 +1342,7 @@ static void assert_cursor(struct drm_i915_private *dev_priv,
        bool cur_state;
 
        if (IS_845G(dev) || IS_I865G(dev))
-               cur_state = I915_READ(_CURACNTR) & CURSOR_ENABLE;
+               cur_state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
        else
                cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
 
@@ -1585,26 +1624,6 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
        assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
 }
 
-static void intel_init_dpio(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
-       if (!IS_VALLEYVIEW(dev))
-               return;
-
-       /*
-        * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C),
-        * CHV x1 PHY (DP/HDMI D)
-        * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C)
-        */
-       if (IS_CHERRYVIEW(dev)) {
-               DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2;
-               DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO;
-       } else {
-               DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
-       }
-}
-
 static void vlv_enable_pll(struct intel_crtc *crtc,
                           const struct intel_crtc_state *pipe_config)
 {
@@ -1831,17 +1850,6 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
        val &= ~DPIO_DCLKP_EN;
        vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
 
-       /* disable left/right clock distribution */
-       if (pipe != PIPE_B) {
-               val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
-               val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
-               vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
-       } else {
-               val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
-               val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
-               vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
-       }
-
        mutex_unlock(&dev_priv->sb_lock);
 }
 
@@ -2042,9 +2050,9 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
        assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);
 
        /* Workaround: set timing override bit. */
-       val = I915_READ(_TRANSA_CHICKEN2);
+       val = I915_READ(TRANS_CHICKEN2(PIPE_A));
        val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
-       I915_WRITE(_TRANSA_CHICKEN2, val);
+       I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
 
        val = TRANS_ENABLE;
        pipeconf_val = I915_READ(PIPECONF(cpu_transcoder));
@@ -2102,9 +2110,9 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
                DRM_ERROR("Failed to disable PCH transcoder\n");
 
        /* Workaround: clear timing override bit. */
-       val = I915_READ(_TRANSA_CHICKEN2);
+       val = I915_READ(TRANS_CHICKEN2(PIPE_A));
        val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE;
-       I915_WRITE(_TRANSA_CHICKEN2, val);
+       I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
 }
 
 /**
@@ -2229,7 +2237,7 @@ static bool need_vtd_wa(struct drm_device *dev)
 
 unsigned int
 intel_tile_height(struct drm_device *dev, uint32_t pixel_format,
-                 uint64_t fb_format_modifier)
+                 uint64_t fb_format_modifier, unsigned int plane)
 {
        unsigned int tile_height;
        uint32_t pixel_bytes;
@@ -2245,7 +2253,7 @@ intel_tile_height(struct drm_device *dev, uint32_t pixel_format,
                tile_height = 32;
                break;
        case I915_FORMAT_MOD_Yf_TILED:
-               pixel_bytes = drm_format_plane_cpp(pixel_format, 0);
+               pixel_bytes = drm_format_plane_cpp(pixel_format, plane);
                switch (pixel_bytes) {
                default:
                case 1:
@@ -2279,7 +2287,7 @@ intel_fb_align_height(struct drm_device *dev, unsigned int height,
                      uint32_t pixel_format, uint64_t fb_format_modifier)
 {
        return ALIGN(height, intel_tile_height(dev, pixel_format,
-                                              fb_format_modifier));
+                                              fb_format_modifier, 0));
 }
 
 static int
@@ -2302,15 +2310,27 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb,
        info->height = fb->height;
        info->pixel_format = fb->pixel_format;
        info->pitch = fb->pitches[0];
+       info->uv_offset = fb->offsets[1];
        info->fb_modifier = fb->modifier[0];
 
        tile_height = intel_tile_height(fb->dev, fb->pixel_format,
-                                       fb->modifier[0]);
+                                       fb->modifier[0], 0);
        tile_pitch = PAGE_SIZE / tile_height;
        info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_pitch);
        info->height_pages = DIV_ROUND_UP(fb->height, tile_height);
        info->size = info->width_pages * info->height_pages * PAGE_SIZE;
 
+       if (info->pixel_format == DRM_FORMAT_NV12) {
+               tile_height = intel_tile_height(fb->dev, fb->pixel_format,
+                                               fb->modifier[0], 1);
+               tile_pitch = PAGE_SIZE / tile_height;
+               info->width_pages_uv = DIV_ROUND_UP(fb->pitches[0], tile_pitch);
+               info->height_pages_uv = DIV_ROUND_UP(fb->height / 2,
+                                                    tile_height);
+               info->size_uv = info->width_pages_uv * info->height_pages_uv *
+                               PAGE_SIZE;
+       }
+
        return 0;
 }
 
@@ -2769,6 +2789,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
                        (intel_crtc->config->pipe_src_w - 1) * pixel_size;
        }
 
+       intel_crtc->adjusted_x = x;
+       intel_crtc->adjusted_y = y;
+
        I915_WRITE(reg, dspcntr);
 
        I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
@@ -2869,6 +2892,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
                }
        }
 
+       intel_crtc->adjusted_x = x;
+       intel_crtc->adjusted_y = y;
+
        I915_WRITE(reg, dspcntr);
 
        I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
@@ -2918,14 +2944,29 @@ u32 intel_fb_stride_alignment(struct drm_device *dev, uint64_t fb_modifier,
 }
 
 unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
-                                    struct drm_i915_gem_object *obj)
+                                    struct drm_i915_gem_object *obj,
+                                    unsigned int plane)
 {
        const struct i915_ggtt_view *view = &i915_ggtt_view_normal;
+       struct i915_vma *vma;
+       unsigned char *offset;
 
        if (intel_rotation_90_or_270(intel_plane->base.state->rotation))
                view = &i915_ggtt_view_rotated;
 
-       return i915_gem_obj_ggtt_offset_view(obj, view);
+       vma = i915_gem_obj_to_ggtt_view(obj, view);
+       if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
+               view->type))
+               return -1;
+
+       offset = (unsigned char *)vma->node.start;
+
+       if (plane == 1) {
+               offset += vma->ggtt_view.rotation_info.uv_start_page *
+                         PAGE_SIZE;
+       }
+
+       return (unsigned long)offset;
 }
 
 static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
@@ -2936,8 +2977,6 @@ static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
        I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0);
        I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
        I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
-       DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
-               intel_crtc->base.base.id, intel_crtc->pipe, id);
 }
 
 /*
@@ -3083,7 +3122,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
        obj = intel_fb_obj(fb);
        stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
                                               fb->pixel_format);
-       surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
+       surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0);
 
        /*
         * FIXME: intel_plane_state->src, dst aren't set when transitional
@@ -3110,7 +3149,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
        if (intel_rotation_90_or_270(rotation)) {
                /* stride = Surface height in tiles */
                tile_height = intel_tile_height(dev, fb->pixel_format,
-                                               fb->modifier[0]);
+                                               fb->modifier[0], 0);
                stride = DIV_ROUND_UP(fb->height, tile_height);
                x_offset = stride * tile_height - y - src_h;
                y_offset = x;
@@ -3123,6 +3162,9 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
        }
        plane_offset = y_offset << 16 | x_offset;
 
+       intel_crtc->adjusted_x = x_offset;
+       intel_crtc->adjusted_y = y_offset;
+
        I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
        I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
        I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
@@ -3179,24 +3221,20 @@ static void intel_complete_page_flips(struct drm_device *dev)
 
 static void intel_update_primary_planes(struct drm_device *dev)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc;
 
        for_each_crtc(dev, crtc) {
-               struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+               struct intel_plane *plane = to_intel_plane(crtc->primary);
+               struct intel_plane_state *plane_state;
 
-               drm_modeset_lock(&crtc->mutex, NULL);
-               /*
-                * FIXME: Once we have proper support for primary planes (and
-                * disabling them without disabling the entire crtc) allow again
-                * a NULL crtc->primary->fb.
-                */
-               if (intel_crtc->active && crtc->primary->fb)
-                       dev_priv->display.update_primary_plane(crtc,
-                                                              crtc->primary->fb,
-                                                              crtc->x,
-                                                              crtc->y);
-               drm_modeset_unlock(&crtc->mutex);
+               drm_modeset_lock_crtc(crtc, &plane->base);
+
+               plane_state = to_intel_plane_state(plane->base.state);
+
+               if (plane_state->base.fb)
+                       plane->commit_plane(&plane->base, plane_state);
+
+               drm_modeset_unlock_crtc(crtc);
        }
 }
 
@@ -3240,6 +3278,9 @@ void intel_finish_reset(struct drm_device *dev)
                 * so update the base address of all primary
                 * planes to the the last fb to make sure we're
                 * showing the correct fb after a reset.
+                *
+                * FIXME: Atomic will make this obsolete since we won't schedule
+                * CS-based flips (which might get lost in gpu resets) any more.
                 */
                intel_update_primary_planes(dev);
                return;
@@ -3310,14 +3351,23 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
        return pending;
 }
 
-static void intel_update_pipe_size(struct intel_crtc *crtc)
+static void intel_update_pipe_config(struct intel_crtc *crtc,
+                                    struct intel_crtc_state *old_crtc_state)
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       const struct drm_display_mode *adjusted_mode;
+       struct intel_crtc_state *pipe_config =
+               to_intel_crtc_state(crtc->base.state);
 
-       if (!i915.fastboot)
-               return;
+       /* drm_atomic_helper_update_legacy_modeset_state might not be called. */
+       crtc->base.mode = crtc->base.state->mode;
+
+       DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n",
+                     old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
+                     pipe_config->pipe_src_w, pipe_config->pipe_src_h);
+
+       if (HAS_DDI(dev))
+               intel_set_pipe_csc(&crtc->base);
 
        /*
         * Update pipe size and adjust fitter if needed: the reason for this is
@@ -3326,27 +3376,24 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
         * fastboot case, we'll flip, but if we don't update the pipesrc and
         * pfit state, we'll end up with a big fb scanned out into the wrong
         * sized surface.
-        *
-        * To fix this properly, we need to hoist the checks up into
-        * compute_mode_changes (or above), check the actual pfit state and
-        * whether the platform allows pfit disable with pipe active, and only
-        * then update the pipesrc and pfit state, even on the flip path.
         */
 
-       adjusted_mode = &crtc->config->base.adjusted_mode;
-
        I915_WRITE(PIPESRC(crtc->pipe),
-                  ((adjusted_mode->crtc_hdisplay - 1) << 16) |
-                  (adjusted_mode->crtc_vdisplay - 1));
-       if (!crtc->config->pch_pfit.enabled &&
-           (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
-            intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
-               I915_WRITE(PF_CTL(crtc->pipe), 0);
-               I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
-               I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
+                  ((pipe_config->pipe_src_w - 1) << 16) |
+                  (pipe_config->pipe_src_h - 1));
+
+       /* on skylake this is done by detaching scalers */
+       if (INTEL_INFO(dev)->gen >= 9) {
+               skl_detach_scalers(crtc);
+
+               if (pipe_config->pch_pfit.enabled)
+                       skylake_pfit_enable(crtc);
+       } else if (HAS_PCH_SPLIT(dev)) {
+               if (pipe_config->pch_pfit.enabled)
+                       ironlake_pfit_enable(crtc);
+               else if (old_crtc_state->pch_pfit.enabled)
+                       ironlake_pfit_disable(crtc, true);
        }
-       crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
-       crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
 }
 
 static void intel_fdi_normal_train(struct drm_crtc *crtc)
@@ -4392,8 +4439,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 int skl_update_scaler_crtc(struct intel_crtc_state *state)
 {
        struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
-       struct drm_display_mode *adjusted_mode =
-               &state->base.adjusted_mode;
+       const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
 
        DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n",
                      intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
@@ -4401,7 +4447,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
        return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
                &state->scaler_state.scaler_id, DRM_ROTATE_0,
                state->pipe_src_w, state->pipe_src_h,
-               adjusted_mode->hdisplay, adjusted_mode->vdisplay);
+               adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
 }
 
 /**
@@ -4594,7 +4640,6 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        enum pipe pipe = intel_crtc->pipe;
-       int palreg = PALETTE(pipe);
        int i;
        bool reenable_ips = false;
 
@@ -4609,10 +4654,6 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
                        assert_pll_enabled(dev_priv, pipe);
        }
 
-       /* use legacy palette for Ironlake */
-       if (!HAS_GMCH_DISPLAY(dev))
-               palreg = LGC_PALETTE(pipe);
-
        /* Workaround : Do not read or write the pipe palette/gamma data while
         * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
         */
@@ -4624,7 +4665,14 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
        }
 
        for (i = 0; i < 256; i++) {
-               I915_WRITE(palreg + 4 * i,
+               u32 palreg;
+
+               if (HAS_GMCH_DISPLAY(dev))
+                       palreg = PALETTE(pipe, i);
+               else
+                       palreg = LGC_PALETTE(pipe, i);
+
+               I915_WRITE(palreg,
                           (intel_crtc->lut_r[i] << 16) |
                           (intel_crtc->lut_g[i] << 8) |
                           intel_crtc->lut_b[i]);
@@ -4963,12 +5011,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
        intel_ddi_enable_pipe_clock(intel_crtc);
 
-       if (INTEL_INFO(dev)->gen == 9)
+       if (INTEL_INFO(dev)->gen >= 9)
                skylake_pfit_enable(intel_crtc);
-       else if (INTEL_INFO(dev)->gen < 9)
-               ironlake_pfit_enable(intel_crtc);
        else
-               MISSING_CASE(INTEL_INFO(dev)->gen);
+               ironlake_pfit_enable(intel_crtc);
 
        /*
         * On ILK+ LUT must be loaded before the pipe is running but with
@@ -5005,7 +5051,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
        }
 }
 
-static void ironlake_pfit_disable(struct intel_crtc *crtc)
+static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force)
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5013,7 +5059,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
 
        /* To avoid upsetting the power well on haswell only disable the pfit if
         * it's in use. The hw state code will make sure we get this right. */
-       if (crtc->config->pch_pfit.enabled) {
+       if (force || crtc->config->pch_pfit.enabled) {
                I915_WRITE(PF_CTL(pipe), 0);
                I915_WRITE(PF_WIN_POS(pipe), 0);
                I915_WRITE(PF_WIN_SZ(pipe), 0);
@@ -5040,7 +5086,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 
        intel_disable_pipe(intel_crtc);
 
-       ironlake_pfit_disable(intel_crtc);
+       ironlake_pfit_disable(intel_crtc, false);
 
        if (intel_crtc->config->has_pch_encoder)
                ironlake_fdi_disable(crtc);
@@ -5069,9 +5115,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 
                ironlake_fdi_pll_disable(intel_crtc);
        }
-
-       intel_crtc->active = false;
-       intel_update_watermarks(crtc);
 }
 
 static void haswell_crtc_disable(struct drm_crtc *crtc)
@@ -5100,12 +5143,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 
        intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
-       if (INTEL_INFO(dev)->gen == 9)
+       if (INTEL_INFO(dev)->gen >= 9)
                skylake_scaler_disable(intel_crtc);
-       else if (INTEL_INFO(dev)->gen < 9)
-               ironlake_pfit_disable(intel_crtc);
        else
-               MISSING_CASE(INTEL_INFO(dev)->gen);
+               ironlake_pfit_disable(intel_crtc, false);
 
        intel_ddi_disable_pipe_clock(intel_crtc);
 
@@ -5117,9 +5158,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->post_disable)
                        encoder->post_disable(encoder);
-
-       intel_crtc->active = false;
-       intel_update_watermarks(crtc);
 }
 
 static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -5277,6 +5315,21 @@ static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
                        modeset_put_power_domains(dev_priv, put_domains[i]);
 }
 
+static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
+{
+       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;
+}
+
 static void intel_update_max_cdclk(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5316,8 +5369,13 @@ static void intel_update_max_cdclk(struct drm_device *dev)
                dev_priv->max_cdclk_freq = dev_priv->cdclk_freq;
        }
 
+       dev_priv->max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
+
        DRM_DEBUG_DRIVER("Max CD clock rate: %d kHz\n",
                         dev_priv->max_cdclk_freq);
+
+       DRM_DEBUG_DRIVER("Max dotclock rate: %d kHz\n",
+                        dev_priv->max_dotclk_freq);
 }
 
 static void intel_update_cdclk(struct drm_device *dev)
@@ -5693,10 +5751,16 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
        if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE)
                DRM_ERROR("DBuf power disable timeout\n");
 
-       /* disable DPLL0 */
-       I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
-       if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1))
-               DRM_ERROR("Couldn't disable DPLL0\n");
+       /*
+        * DMC assumes ownership of LCPLL and will get confused if we touch it.
+        */
+       if (dev_priv->csr.dmc_payload) {
+               /* disable DPLL0 */
+               I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) &
+                                       ~LCPLL_PLL_ENABLE);
+               if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1))
+                       DRM_ERROR("Couldn't disable DPLL0\n");
+       }
 
        intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
 }
@@ -5733,20 +5797,6 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv)
                DRM_ERROR("DBuf power enable timeout\n");
 }
 
-/* returns HPLL frequency in kHz */
-static int valleyview_get_vco(struct drm_i915_private *dev_priv)
-{
-       int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
-
-       /* Obtain SKU information */
-       mutex_lock(&dev_priv->sb_lock);
-       hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
-               CCK_FUSE_HPLL_FREQ_MASK;
-       mutex_unlock(&dev_priv->sb_lock);
-
-       return vco_freq[hpll_freq] * 1000;
-}
-
 /* Adjust CDclk dividers to allow high res or save power if possible */
 static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
 {
@@ -5784,12 +5834,12 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
 
                /* adjust cdclk divider */
                val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
-               val &= ~DISPLAY_FREQUENCY_VALUES;
+               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) &
-                             DISPLAY_FREQUENCY_STATUS) == (divider << DISPLAY_FREQUENCY_STATUS_SHIFT),
+                             CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),
                             50))
                        DRM_ERROR("timed out waiting for CDclk change\n");
        }
@@ -5967,7 +6017,7 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
        else
                default_credits = PFI_CREDIT(8);
 
-       if (DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 1000) >= dev_priv->rps.cz_freq) {
+       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;
@@ -6035,13 +6085,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 
        is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
 
-       if (!is_dsi) {
-               if (IS_CHERRYVIEW(dev))
-                       chv_prepare_pll(intel_crtc, intel_crtc->config);
-               else
-                       vlv_prepare_pll(intel_crtc, intel_crtc->config);
-       }
-
        if (intel_crtc->config->has_dp_encoder)
                intel_dp_set_m_n(intel_crtc, M1_N1);
 
@@ -6065,10 +6108,13 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
                        encoder->pre_pll_enable(encoder);
 
        if (!is_dsi) {
-               if (IS_CHERRYVIEW(dev))
+               if (IS_CHERRYVIEW(dev)) {
+                       chv_prepare_pll(intel_crtc, intel_crtc->config);
                        chv_enable_pll(intel_crtc, intel_crtc->config);
-               else
+               } else {
+                       vlv_prepare_pll(intel_crtc, intel_crtc->config);
                        vlv_enable_pll(intel_crtc, intel_crtc->config);
+               }
        }
 
        for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -6196,11 +6242,12 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
                        i9xx_disable_pll(intel_crtc);
        }
 
+       for_each_encoder_on_crtc(dev, crtc, encoder)
+               if (encoder->post_pll_disable)
+                       encoder->post_pll_disable(encoder);
+
        if (!IS_GEN2(dev))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
-
-       intel_crtc->active = false;
-       intel_update_watermarks(crtc);
 }
 
 static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
@@ -6220,6 +6267,8 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
 
        intel_crtc_disable_planes(crtc, crtc->state->plane_mask);
        dev_priv->display.crtc_disable(crtc);
+       intel_crtc->active = false;
+       intel_update_watermarks(crtc);
        intel_disable_shared_dpll(intel_crtc);
 
        domains = intel_crtc->enabled_power_domains;
@@ -6456,7 +6505,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
                                       struct intel_crtc_state *pipe_config)
 {
        struct drm_device *dev = intel_crtc->base.dev;
-       struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+       const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
        int lane, link_bw, fdi_dotclock, ret;
        bool needs_recompute = false;
 
@@ -6535,7 +6584,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+       const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 
        /* FIXME should check pixel clock limits on all platforms */
        if (INTEL_INFO(dev)->gen < 4) {
@@ -6572,7 +6621,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
         * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
         */
        if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) &&
-               adjusted_mode->hsync_start == adjusted_mode->hdisplay)
+               adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
                return -EINVAL;
 
        if (HAS_IPS(dev))
@@ -6699,24 +6748,8 @@ static int haswell_get_display_clock_speed(struct drm_device *dev)
 
 static int valleyview_get_display_clock_speed(struct drm_device *dev)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 val;
-       int divider;
-
-       if (dev_priv->hpll_freq == 0)
-               dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
-
-       mutex_lock(&dev_priv->sb_lock);
-       val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
-       mutex_unlock(&dev_priv->sb_lock);
-
-       divider = val & DISPLAY_FREQUENCY_VALUES;
-
-       WARN((val & DISPLAY_FREQUENCY_STATUS) !=
-            (divider << DISPLAY_FREQUENCY_STATUS_SHIFT),
-            "cdclk change in progress\n");
-
-       return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1);
+       return vlv_get_cck_clock_hpll(to_i915(dev), "cdclk",
+                                     CCK_DISPLAY_CLOCK_CONTROL);
 }
 
 static int ilk_get_display_clock_speed(struct drm_device *dev)
@@ -7377,8 +7410,7 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
                        1 << DPIO_CHV_N_DIV_SHIFT);
 
        /* M2 fraction division */
-       if (bestm2_frac)
-               vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
+       vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
 
        /* M2 fraction division enable */
        dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
@@ -7604,8 +7636,7 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe = intel_crtc->pipe;
        enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
-       struct drm_display_mode *adjusted_mode =
-               &intel_crtc->config->base.adjusted_mode;
+       const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
        uint32_t crtc_vtotal, crtc_vblank_end;
        int vsyncshift = 0;
 
@@ -8119,6 +8150,14 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
        else
                i9xx_crtc_clock_get(crtc, pipe_config);
 
+       /*
+        * Normally the dotclock is filled in by the encoder .get_config()
+        * but in case the pipe is enabled w/o any ports we need a sane
+        * default.
+        */
+       pipe_config->base.adjusted_mode.crtc_clock =
+               pipe_config->port_clock / pipe_config->pixel_multiplier;
+
        return true;
 }
 
@@ -8380,8 +8419,7 @@ static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread,
 
        if (WARN(with_fdi && !with_spread, "FDI requires downspread\n"))
                with_spread = true;
-       if (WARN(dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE &&
-                with_fdi, "LP PCH doesn't have FDI\n"))
+       if (WARN(HAS_PCH_LPT_LP(dev) && with_fdi, "LP PCH doesn't have FDI\n"))
                with_fdi = false;
 
        mutex_lock(&dev_priv->sb_lock);
@@ -8404,8 +8442,7 @@ static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread,
                }
        }
 
-       reg = (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) ?
-              SBI_GEN0 : SBI_DBUFF0;
+       reg = HAS_PCH_LPT_LP(dev) ? SBI_GEN0 : SBI_DBUFF0;
        tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
        tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE;
        intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
@@ -8421,8 +8458,7 @@ static void lpt_disable_clkout_dp(struct drm_device *dev)
 
        mutex_lock(&dev_priv->sb_lock);
 
-       reg = (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) ?
-              SBI_GEN0 : SBI_DBUFF0;
+       reg = HAS_PCH_LPT_LP(dev) ? SBI_GEN0 : SBI_DBUFF0;
        tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
        tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE;
        intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
@@ -9434,7 +9470,7 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv)
 
        DRM_DEBUG_KMS("Enabling package C8+\n");
 
-       if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
+       if (HAS_PCH_LPT_LP(dev)) {
                val = I915_READ(SOUTH_DSPCLK_GATE_D);
                val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
                I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
@@ -9454,7 +9490,7 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv)
        hsw_restore_lcpll(dev_priv);
        lpt_init_pch_refclk(dev);
 
-       if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
+       if (HAS_PCH_LPT_LP(dev)) {
                val = I915_READ(SOUTH_DSPCLK_GATE_D);
                val |= PCH_LP_PARTITION_LEVEL_DISABLE;
                I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
@@ -9804,12 +9840,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
        }
 
        if (intel_display_power_is_enabled(dev_priv, pfit_domain)) {
-               if (INTEL_INFO(dev)->gen == 9)
+               if (INTEL_INFO(dev)->gen >= 9)
                        skylake_get_pfit_config(crtc, pipe_config);
-               else if (INTEL_INFO(dev)->gen < 9)
-                       ironlake_get_pfit_config(crtc, pipe_config);
                else
-                       MISSING_CASE(INTEL_INFO(dev)->gen);
+                       ironlake_get_pfit_config(crtc, pipe_config);
        }
 
        if (IS_HASWELL(dev))
@@ -9866,13 +9900,13 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
                /* On these chipsets we can only modify the base/size/stride
                 * whilst the cursor is disabled.
                 */
-               I915_WRITE(_CURACNTR, 0);
-               POSTING_READ(_CURACNTR);
+               I915_WRITE(CURCNTR(PIPE_A), 0);
+               POSTING_READ(CURCNTR(PIPE_A));
                intel_crtc->cursor_cntl = 0;
        }
 
        if (intel_crtc->cursor_base != base) {
-               I915_WRITE(_CURABASE, base);
+               I915_WRITE(CURBASE(PIPE_A), base);
                intel_crtc->cursor_base = base;
        }
 
@@ -9882,8 +9916,8 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
        }
 
        if (intel_crtc->cursor_cntl != cntl) {
-               I915_WRITE(_CURACNTR, cntl);
-               POSTING_READ(_CURACNTR);
+               I915_WRITE(CURCNTR(PIPE_A), cntl);
+               POSTING_READ(CURCNTR(PIPE_A));
                intel_crtc->cursor_cntl = cntl;
        }
 }
@@ -9943,8 +9977,9 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
-       int x = crtc->cursor_x;
-       int y = crtc->cursor_y;
+       struct drm_plane_state *cursor_state = crtc->cursor->state;
+       int x = cursor_state->crtc_x;
+       int y = cursor_state->crtc_y;
        u32 base = 0, pos = 0;
 
        if (on)
@@ -9957,7 +9992,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
                base = 0;
 
        if (x < 0) {
-               if (x + intel_crtc->base.cursor->state->crtc_w <= 0)
+               if (x + cursor_state->crtc_w <= 0)
                        base = 0;
 
                pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
@@ -9966,7 +10001,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
        pos |= x << CURSOR_X_SHIFT;
 
        if (y < 0) {
-               if (y + intel_crtc->base.cursor->state->crtc_h <= 0)
+               if (y + cursor_state->crtc_h <= 0)
                        base = 0;
 
                pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
@@ -9982,8 +10017,8 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
        /* ILK+ do this automagically */
        if (HAS_GMCH_DISPLAY(dev) &&
            crtc->cursor->state->rotation == BIT(DRM_ROTATE_180)) {
-               base += (intel_crtc->base.cursor->state->crtc_h *
-                       intel_crtc->base.cursor->state->crtc_w - 1) * 4;
+               base += (cursor_state->crtc_h *
+                        cursor_state->crtc_w - 1) * 4;
        }
 
        if (IS_845G(dev) || IS_I865G(dev))
@@ -11034,10 +11069,10 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
                                        DERRMR_PIPEB_PRI_FLIP_DONE |
                                        DERRMR_PIPEC_PRI_FLIP_DONE));
                if (IS_GEN8(dev))
-                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) |
+                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8 |
                                              MI_SRM_LRM_GLOBAL_GTT);
                else
-                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1) |
+                       intel_ring_emit(ring, MI_STORE_REGISTER_MEM |
                                              MI_SRM_LRM_GLOBAL_GTT);
                intel_ring_emit(ring, DERRMR);
                intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
@@ -11161,11 +11196,10 @@ static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc)
 static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
 {
        struct drm_device *dev = intel_crtc->base.dev;
-       u32 start_vbl_count;
 
        intel_mark_page_flip_active(intel_crtc);
 
-       intel_pipe_update_start(intel_crtc, &start_vbl_count);
+       intel_pipe_update_start(intel_crtc);
 
        if (INTEL_INFO(dev)->gen >= 9)
                skl_do_mmio_flip(intel_crtc);
@@ -11173,7 +11207,7 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
                /* use_mmio_flip() retricts MMIO flips to ilk+ */
                ilk_do_mmio_flip(intel_crtc);
 
-       intel_pipe_update_end(intel_crtc, start_vbl_count);
+       intel_pipe_update_end(intel_crtc);
 }
 
 static void intel_mmio_flip_work_func(struct work_struct *work)
@@ -11237,6 +11271,9 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
        if (atomic_read(&work->pending) >= INTEL_FLIP_COMPLETE)
                return true;
 
+       if (atomic_read(&work->pending) < INTEL_FLIP_PENDING)
+               return false;
+
        if (!work->enable_stall_check)
                return false;
 
@@ -11417,8 +11454,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        if (ret)
                goto cleanup_pending;
 
-       work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary), obj)
-                                                 + intel_crtc->dspaddr_offset;
+       work->gtt_offset = intel_plane_obj_offset(to_intel_plane(primary),
+                                                 obj, 0);
+       work->gtt_offset += intel_crtc->dspaddr_offset;
 
        if (mmio_flip) {
                ret = intel_queue_mmio_flip(dev, crtc, fb, obj, ring,
@@ -11627,7 +11665,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
                intel_crtc->atomic.update_wm_pre = true;
        }
 
-       if (visible)
+       if (visible || was_visible)
                intel_crtc->atomic.fb_bits |=
                        to_intel_plane(plane)->frontbuffer_bit;
 
@@ -11900,14 +11938,16 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
                      pipe_config->fdi_m_n.gmch_m, pipe_config->fdi_m_n.gmch_n,
                      pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n,
                      pipe_config->fdi_m_n.tu);
-       DRM_DEBUG_KMS("dp: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
+       DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
                      pipe_config->has_dp_encoder,
+                     pipe_config->lane_count,
                      pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n,
                      pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n,
                      pipe_config->dp_m_n.tu);
 
-       DRM_DEBUG_KMS("dp: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n",
+       DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n",
                      pipe_config->has_dp_encoder,
+                     pipe_config->lane_count,
                      pipe_config->dp_m2_n2.gmch_m,
                      pipe_config->dp_m2_n2.gmch_n,
                      pipe_config->dp_m2_n2.link_m,
@@ -12119,10 +12159,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
              (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
                pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
 
-       /* Compute a starting value for pipe_config->pipe_bpp taking the source
-        * plane pixel format and any sink constraints into account. Returns the
-        * source plane bpp so that dithering can be selected on mismatches
-        * after encoders and crtc also have had their say. */
        base_bpp = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
                                             pipe_config);
        if (base_bpp < 0)
@@ -12191,7 +12227,7 @@ 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;
-       DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
+       DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
                      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
 fail:
@@ -12241,7 +12277,6 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
                            base.head) \
                if (mask & (1 <<(intel_crtc)->pipe))
 
-
 static bool
 intel_compare_m_n(unsigned int m, unsigned int n,
                  unsigned int m2, unsigned int n2,
@@ -12414,6 +12449,7 @@ intel_pipe_config_compare(struct drm_device *dev,
        PIPE_CONF_CHECK_M_N(fdi_m_n);
 
        PIPE_CONF_CHECK_I(has_dp_encoder);
+       PIPE_CONF_CHECK_I(lane_count);
 
        if (INTEL_INFO(dev)->gen < 8) {
                PIPE_CONF_CHECK_M_N(dp_m_n);
@@ -12461,22 +12497,24 @@ intel_pipe_config_compare(struct drm_device *dev,
                                      DRM_MODE_FLAG_NVSYNC);
        }
 
-       PIPE_CONF_CHECK_I(pipe_src_w);
-       PIPE_CONF_CHECK_I(pipe_src_h);
-
-       PIPE_CONF_CHECK_I(gmch_pfit.control);
+       PIPE_CONF_CHECK_X(gmch_pfit.control);
        /* pfit ratios are autocomputed by the hw on gen4+ */
        if (INTEL_INFO(dev)->gen < 4)
                PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
-       PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
+       PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
 
-       PIPE_CONF_CHECK_I(pch_pfit.enabled);
-       if (current_config->pch_pfit.enabled) {
-               PIPE_CONF_CHECK_I(pch_pfit.pos);
-               PIPE_CONF_CHECK_I(pch_pfit.size);
-       }
+       if (!adjust) {
+               PIPE_CONF_CHECK_I(pipe_src_w);
+               PIPE_CONF_CHECK_I(pipe_src_h);
 
-       PIPE_CONF_CHECK_I(scaler_state.scaler_id);
+               PIPE_CONF_CHECK_I(pch_pfit.enabled);
+               if (current_config->pch_pfit.enabled) {
+                       PIPE_CONF_CHECK_X(pch_pfit.pos);
+                       PIPE_CONF_CHECK_X(pch_pfit.size);
+               }
+
+               PIPE_CONF_CHECK_I(scaler_state.scaler_id);
+       }
 
        /* BDW+ don't expose a synchronous way to read the state */
        if (IS_HASWELL(dev))
@@ -12638,7 +12676,8 @@ check_crtc_state(struct drm_device *dev, struct drm_atomic_state *old_state)
                struct intel_crtc_state *pipe_config, *sw_config;
                bool active;
 
-               if (!needs_modeset(crtc->state))
+               if (!needs_modeset(crtc->state) &&
+                   !to_intel_crtc_state(crtc->state)->update_pipe)
                        continue;
 
                __drm_atomic_helper_crtc_destroy_state(crtc, old_crtc_state);
@@ -12792,11 +12831,11 @@ static void update_scanline_offset(struct intel_crtc *crtc)
         * one to the value.
         */
        if (IS_GEN2(dev)) {
-               const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
+               const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
                int vtotal;
 
-               vtotal = mode->crtc_vtotal;
-               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               vtotal = adjusted_mode->crtc_vtotal;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
                        vtotal /= 2;
 
                crtc->scanline_offset = vtotal - 1;
@@ -12934,7 +12973,6 @@ static int intel_modeset_all_pipes(struct drm_atomic_state *state)
        return ret;
 }
 
-
 static int intel_modeset_checks(struct drm_atomic_state *state)
 {
        struct drm_device *dev = state->dev;
@@ -13020,11 +13058,11 @@ static int intel_atomic_check(struct drm_device *dev,
                if (ret)
                        return ret;
 
-               if (i915.fastboot &&
-                   intel_pipe_config_compare(state->dev,
+               if (intel_pipe_config_compare(state->dev,
                                        to_intel_crtc_state(crtc->state),
                                        pipe_config, true)) {
                        crtc_state->mode_changed = false;
+                       to_intel_crtc_state(crtc_state)->update_pipe = true;
                }
 
                if (needs_modeset(crtc_state)) {
@@ -13122,16 +13160,30 @@ static int intel_atomic_commit(struct drm_device *dev,
        for_each_crtc_in_state(state, crtc, crtc_state, i) {
                struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
                bool modeset = needs_modeset(crtc->state);
+               bool update_pipe = !modeset &&
+                       to_intel_crtc_state(crtc->state)->update_pipe;
+               unsigned long put_domains = 0;
 
                if (modeset && crtc->state->active) {
                        update_scanline_offset(to_intel_crtc(crtc));
                        dev_priv->display.crtc_enable(crtc);
                }
 
+               if (update_pipe) {
+                       put_domains = modeset_get_crtc_power_domains(crtc);
+
+                       /* make sure intel_modeset_check_state runs */
+                       any_ms = true;
+               }
+
                if (!modeset)
                        intel_pre_plane_update(intel_crtc);
 
                drm_atomic_helper_commit_planes_on_crtc(crtc_state);
+
+               if (put_domains)
+                       modeset_put_power_domains(dev_priv, put_domains);
+
                intel_post_plane_update(intel_crtc);
        }
 
@@ -13287,8 +13339,6 @@ static void intel_shared_dpll_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       intel_update_cdclk(dev);
-
        if (HAS_DDI(dev))
                intel_ddi_pll_init(dev);
        else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
@@ -13313,10 +13363,10 @@ static void intel_shared_dpll_init(struct drm_device *dev)
  */
 int
 intel_prepare_plane_fb(struct drm_plane *plane,
-                      struct drm_framebuffer *fb,
                       const struct drm_plane_state *new_state)
 {
        struct drm_device *dev = plane->dev;
+       struct drm_framebuffer *fb = new_state->fb;
        struct intel_plane *intel_plane = to_intel_plane(plane);
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
@@ -13354,19 +13404,18 @@ intel_prepare_plane_fb(struct drm_plane *plane,
  */
 void
 intel_cleanup_plane_fb(struct drm_plane *plane,
-                      struct drm_framebuffer *fb,
                       const struct drm_plane_state *old_state)
 {
        struct drm_device *dev = plane->dev;
-       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+       struct drm_i915_gem_object *obj = intel_fb_obj(old_state->fb);
 
-       if (WARN_ON(!obj))
+       if (!obj)
                return;
 
        if (plane->type != DRM_PLANE_TYPE_CURSOR ||
            !INTEL_INFO(dev)->cursor_needs_physical) {
                mutex_lock(&dev->struct_mutex);
-               intel_unpin_fb_obj(fb, old_state);
+               intel_unpin_fb_obj(old_state->fb, old_state);
                mutex_unlock(&dev->struct_mutex);
        }
 }
@@ -13448,11 +13497,9 @@ intel_commit_primary_plane(struct drm_plane *plane,
        if (!crtc->state->active)
                return;
 
-       if (state->visible)
-               /* FIXME: kill this fastboot hack */
-               intel_update_pipe_size(intel_crtc);
-
-       dev_priv->display.update_primary_plane(crtc, fb, crtc->x, crtc->y);
+       dev_priv->display.update_primary_plane(crtc, fb,
+                                              state->src.x1 >> 16,
+                                              state->src.y1 >> 16);
 }
 
 static void
@@ -13470,15 +13517,23 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
 {
        struct drm_device *dev = crtc->dev;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc_state *old_intel_state =
+               to_intel_crtc_state(old_crtc_state);
+       bool modeset = needs_modeset(crtc->state);
 
        if (intel_crtc->atomic.update_wm_pre)
                intel_update_watermarks(crtc);
 
        /* Perform vblank evasion around commit operation */
        if (crtc->state->active)
-               intel_pipe_update_start(intel_crtc, &intel_crtc->start_vbl_count);
+               intel_pipe_update_start(intel_crtc);
+
+       if (modeset)
+               return;
 
-       if (!needs_modeset(crtc->state) && INTEL_INFO(dev)->gen >= 9)
+       if (to_intel_crtc_state(crtc->state)->update_pipe)
+               intel_update_pipe_config(intel_crtc, old_intel_state);
+       else if (INTEL_INFO(dev)->gen >= 9)
                skl_detach_scalers(intel_crtc);
 }
 
@@ -13488,7 +13543,7 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc,
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
        if (crtc->state->active)
-               intel_pipe_update_end(intel_crtc, intel_crtc->start_vbl_count);
+               intel_pipe_update_end(intel_crtc);
 }
 
 /**
@@ -13657,10 +13712,6 @@ intel_commit_cursor_plane(struct drm_plane *plane,
        crtc = crtc ? crtc : plane->crtc;
        intel_crtc = to_intel_crtc(crtc);
 
-       plane->fb = state->base.fb;
-       crtc->cursor_x = state->base.crtc_x;
-       crtc->cursor_y = state->base.crtc_y;
-
        if (intel_crtc->cursor_bo == obj)
                goto update;
 
@@ -13946,7 +13997,7 @@ static void intel_setup_outputs(struct drm_device *dev)
                 * On SKL pre-D0 the strap isn't connected, so we assume
                 * it's there.
                 */
-               found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED;
+               found = I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
                /* WaIgnoreDDIAStrap: skl */
                if (found || IS_SKYLAKE(dev))
                        intel_ddi_init(dev, PORT_A);
@@ -14007,29 +14058,26 @@ static void intel_setup_outputs(struct drm_device *dev)
                 * eDP ports. Consult the VBT as well as DP_DETECTED to
                 * detect eDP ports.
                 */
-               if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED &&
+               if (I915_READ(VLV_HDMIB) & SDVO_DETECTED &&
                    !intel_dp_is_edp(dev, PORT_B))
-                       intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB,
-                                       PORT_B);
-               if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED ||
+                       intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
+               if (I915_READ(VLV_DP_B) & DP_DETECTED ||
                    intel_dp_is_edp(dev, PORT_B))
-                       intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B);
+                       intel_dp_init(dev, VLV_DP_B, PORT_B);
 
-               if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED &&
+               if (I915_READ(VLV_HDMIC) & SDVO_DETECTED &&
                    !intel_dp_is_edp(dev, PORT_C))
-                       intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC,
-                                       PORT_C);
-               if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED ||
+                       intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
+               if (I915_READ(VLV_DP_C) & DP_DETECTED ||
                    intel_dp_is_edp(dev, PORT_C))
-                       intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C);
+                       intel_dp_init(dev, VLV_DP_C, PORT_C);
 
                if (IS_CHERRYVIEW(dev)) {
-                       if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED)
-                               intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID,
-                                               PORT_D);
                        /* eDP not supported on port D, so don't check VBT */
-                       if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED)
-                               intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D);
+                       if (I915_READ(CHV_HDMID) & SDVO_DETECTED)
+                               intel_hdmi_init(dev, CHV_HDMID, PORT_D);
+                       if (I915_READ(CHV_DP_D) & DP_DETECTED)
+                               intel_dp_init(dev, CHV_DP_D, PORT_D);
                }
 
                intel_dsi_init(dev);
@@ -14520,8 +14568,6 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.queue_flip = intel_default_queue_flip;
        }
 
-       intel_panel_init_backlight_funcs(dev);
-
        mutex_init(&dev_priv->pps_mutex);
 }
 
@@ -14799,7 +14845,8 @@ void intel_modeset_init(struct drm_device *dev)
                }
        }
 
-       intel_init_dpio(dev);
+       intel_update_czclk(dev_priv);
+       intel_update_cdclk(dev);
 
        intel_shared_dpll_init(dev);
 
@@ -14882,13 +14929,22 @@ intel_check_plane_mapping(struct intel_crtc *crtc)
        return true;
 }
 
+static bool intel_crtc_has_encoders(struct intel_crtc *crtc)
+{
+       struct drm_device *dev = crtc->base.dev;
+       struct intel_encoder *encoder;
+
+       for_each_encoder_on_crtc(dev, &crtc->base, encoder)
+               return true;
+
+       return false;
+}
+
 static void intel_sanitize_crtc(struct intel_crtc *crtc)
 {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_encoder *encoder;
        u32 reg;
-       bool enable;
 
        /* Clear any frame start delays used for debugging left by the BIOS */
        reg = PIPECONF(crtc->config->cpu_transcoder);
@@ -14897,9 +14953,17 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
        /* restore vblank interrupts to correct state */
        drm_crtc_vblank_reset(&crtc->base);
        if (crtc->active) {
-               drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
-               update_scanline_offset(crtc);
+               struct intel_plane *plane;
+
                drm_crtc_vblank_on(&crtc->base);
+
+               /* Disable everything but the primary plane */
+               for_each_intel_plane_on_crtc(dev, crtc, plane) {
+                       if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+                               continue;
+
+                       plane->disable_plane(&plane->base, &crtc->base);
+               }
        }
 
        /* We need to sanitize the plane -> pipe mapping first because this will
@@ -14932,16 +14996,11 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 
        /* Adjust the state of the output pipe according to whether we
         * have active connectors/encoders. */
-       enable = false;
-       for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
-               enable = true;
-               break;
-       }
-
-       if (!enable)
+       if (!intel_crtc_has_encoders(crtc))
                intel_crtc_disable_noatomic(&crtc->base);
 
        if (crtc->active != crtc->base.state->active) {
+               struct intel_encoder *encoder;
 
                /* This can happen either due to bugs in the get_hw_state
                 * functions or because of calls to intel_crtc_disable_noatomic,
@@ -15067,38 +15126,25 @@ void i915_redisable_vga(struct drm_device *dev)
        i915_redisable_vga_power_on(dev);
 }
 
-static bool primary_get_hw_state(struct intel_crtc *crtc)
+static bool primary_get_hw_state(struct intel_plane *plane)
 {
-       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 
-       return !!(I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE);
+       return I915_READ(DSPCNTR(plane->plane)) & DISPLAY_PLANE_ENABLE;
 }
 
-static void readout_plane_state(struct intel_crtc *crtc,
-                               struct intel_crtc_state *crtc_state)
+/* FIXME read out full plane state for all planes */
+static void readout_plane_state(struct intel_crtc *crtc)
 {
-       struct intel_plane *p;
-       struct intel_plane_state *plane_state;
-       bool active = crtc_state->base.active;
-
-       for_each_intel_plane(crtc->base.dev, p) {
-               if (crtc->pipe != p->pipe)
-                       continue;
-
-               plane_state = to_intel_plane_state(p->base.state);
+       struct drm_plane *primary = crtc->base.primary;
+       struct intel_plane_state *plane_state =
+               to_intel_plane_state(primary->state);
 
-               if (p->base.type == DRM_PLANE_TYPE_PRIMARY) {
-                       plane_state->visible = primary_get_hw_state(crtc);
-                       if (plane_state->visible)
-                               crtc->base.state->plane_mask |=
-                                       1 << drm_plane_index(&p->base);
-               } else {
-                       if (active)
-                               p->disable_plane(&p->base, &crtc->base);
+       plane_state->visible =
+               primary_get_hw_state(to_intel_plane(primary));
 
-                       plane_state->visible = false;
-               }
-       }
+       if (plane_state->visible)
+               crtc->base.state->plane_mask |= 1 << drm_plane_index(primary);
 }
 
 static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -15121,34 +15167,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                crtc->base.state->active = crtc->active;
                crtc->base.enabled = crtc->active;
 
-               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);
-                       WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
-
-                       /*
-                        * The initial mode needs to be set in order to keep
-                        * 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.
-                        */
-                       crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
-               }
-
-               crtc->base.hwmode = crtc->config->base.adjusted_mode;
-               readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
+               readout_plane_state(crtc);
 
                DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
                              crtc->base.base.id,
@@ -15207,6 +15226,39 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                              connector->base.name,
                              connector->base.encoder ? "enabled" : "disabled");
        }
+
+       for_each_intel_crtc(dev, crtc) {
+               crtc->base.hwmode = crtc->config->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);
+                       WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
+
+                       /*
+                        * The initial mode needs to be set in order to keep
+                        * 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.
+                        */
+                       crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
+
+                       drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
+                       update_scanline_offset(crtc);
+               }
+       }
 }
 
 /* Scan out the current hw modeset state,