]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/gpu/drm/i915/intel_display.c
Merge tag 'drm-intel-next-2017-03-06' of git://anongit.freedesktop.org/git/drm-intel...
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / i915 / intel_display.c
index 9908bba5b3d351d9ac8046643677c61f6f6fb0f4..7369ee31ad914ac8726413bc3d1cec755ae08c2b 100644 (file)
@@ -2670,6 +2670,29 @@ update_state_fb(struct drm_plane *plane)
                drm_framebuffer_reference(plane->state->fb);
 }
 
+static void
+intel_set_plane_visible(struct intel_crtc_state *crtc_state,
+                       struct intel_plane_state *plane_state,
+                       bool visible)
+{
+       struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+
+       plane_state->base.visible = visible;
+
+       /* FIXME pre-g4x don't work like this */
+       if (visible) {
+               crtc_state->base.plane_mask |= BIT(drm_plane_index(&plane->base));
+               crtc_state->active_planes |= BIT(plane->id);
+       } else {
+               crtc_state->base.plane_mask &= ~BIT(drm_plane_index(&plane->base));
+               crtc_state->active_planes &= ~BIT(plane->id);
+       }
+
+       DRM_DEBUG_KMS("%s active planes 0x%x\n",
+                     crtc_state->base.crtc->name,
+                     crtc_state->active_planes);
+}
+
 static void
 intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
                             struct intel_initial_plane_config *plane_config)
@@ -2727,9 +2750,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
         * simplest solution is to just disable the primary plane now and
         * pretend the BIOS never had it enabled.
         */
-       plane_state->visible = false;
-       crtc_state->plane_mask &= ~(1 << drm_plane_index(primary));
+       intel_set_plane_visible(to_intel_crtc_state(crtc_state),
+                               to_intel_plane_state(plane_state),
+                               false);
        intel_pre_disable_primary_noatomic(&intel_crtc->base);
+       trace_intel_disable_plane(primary, intel_crtc);
        intel_plane->disable_plane(primary, &intel_crtc->base);
 
        return;
@@ -2768,7 +2793,11 @@ valid_fb:
        drm_framebuffer_reference(fb);
        primary->fb = primary->state->fb = fb;
        primary->crtc = primary->state->crtc = &intel_crtc->base;
-       intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
+
+       intel_set_plane_visible(to_intel_crtc_state(crtc_state),
+                               to_intel_plane_state(plane_state),
+                               true);
+
        atomic_or(to_intel_plane(primary)->frontbuffer_bit,
                  &obj->frontbuffer_bits);
 }
@@ -3419,16 +3448,21 @@ static void intel_update_primary_planes(struct drm_device *dev)
                struct intel_plane_state *plane_state =
                        to_intel_plane_state(plane->base.state);
 
-               if (plane_state->base.visible)
+               if (plane_state->base.visible) {
+                       trace_intel_update_plane(&plane->base,
+                                                to_intel_crtc(crtc));
+
                        plane->update_plane(&plane->base,
                                            to_intel_crtc_state(crtc->state),
                                            plane_state);
+               }
        }
 }
 
 static int
 __intel_display_resume(struct drm_device *dev,
-                      struct drm_atomic_state *state)
+                      struct drm_atomic_state *state,
+                      struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_crtc_state *crtc_state;
        struct drm_crtc *crtc;
@@ -3450,9 +3484,10 @@ __intel_display_resume(struct drm_device *dev,
        }
 
        /* ignore any reset values/BIOS leftovers in the WM registers */
-       to_intel_atomic_state(state)->skip_intermediate_wm = true;
+       if (!HAS_GMCH_DISPLAY(to_i915(dev)))
+               to_intel_atomic_state(state)->skip_intermediate_wm = true;
 
-       ret = drm_atomic_commit(state);
+       ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
 
        WARN_ON(ret == -EDEADLK);
        return ret;
@@ -3542,7 +3577,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
                         */
                        intel_update_primary_planes(dev);
                } else {
-                       ret = __intel_display_resume(dev, state);
+                       ret = __intel_display_resume(dev, state, ctx);
                        if (ret)
                                DRM_ERROR("Restoring old state failed with %i\n", ret);
                }
@@ -3562,7 +3597,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
                        dev_priv->display.hpd_irq_setup(dev_priv);
                spin_unlock_irq(&dev_priv->irq_lock);
 
-               ret = __intel_display_resume(dev, state);
+               ret = __intel_display_resume(dev, state, ctx);
                if (ret)
                        DRM_ERROR("Restoring old state failed with %i\n", ret);
 
@@ -3646,12 +3681,11 @@ static void intel_update_pipe_config(struct intel_crtc *crtc,
        }
 }
 
-static void intel_fdi_normal_train(struct drm_crtc *crtc)
+static void intel_fdi_normal_train(struct intel_crtc *crtc)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp;
 
@@ -3689,12 +3723,12 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
 }
 
 /* The FDI link training functions for ILK/Ibexpeak. */
-static void ironlake_fdi_link_train(struct drm_crtc *crtc)
+static void ironlake_fdi_link_train(struct intel_crtc *crtc,
+                                   const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp, tries;
 
@@ -3715,7 +3749,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
        reg = FDI_TX_CTL(pipe);
        temp = I915_READ(reg);
        temp &= ~FDI_DP_PORT_WIDTH_MASK;
-       temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+       temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
        temp &= ~FDI_LINK_TRAIN_NONE;
        temp |= FDI_LINK_TRAIN_PATTERN_1;
        I915_WRITE(reg, temp | FDI_TX_ENABLE);
@@ -3790,12 +3824,12 @@ static const int snb_b_fdi_train_param[] = {
 };
 
 /* The FDI link training functions for SNB/Cougarpoint. */
-static void gen6_fdi_link_train(struct drm_crtc *crtc)
+static void gen6_fdi_link_train(struct intel_crtc *crtc,
+                               const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp, i, retry;
 
@@ -3814,7 +3848,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
        reg = FDI_TX_CTL(pipe);
        temp = I915_READ(reg);
        temp &= ~FDI_DP_PORT_WIDTH_MASK;
-       temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+       temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
        temp &= ~FDI_LINK_TRAIN_NONE;
        temp |= FDI_LINK_TRAIN_PATTERN_1;
        temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
@@ -3923,12 +3957,12 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
 }
 
 /* Manual link training for Ivy Bridge A0 parts */
-static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
+static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
+                                     const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        i915_reg_t reg;
        u32 temp, i, j;
 
@@ -3966,7 +4000,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
                reg = FDI_TX_CTL(pipe);
                temp = I915_READ(reg);
                temp &= ~FDI_DP_PORT_WIDTH_MASK;
-               temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+               temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
                temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
                temp |= snb_b_fdi_train_param[j/2];
@@ -4253,10 +4287,10 @@ void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
 }
 
 /* Program iCLKIP clock to the desired frequency */
-static void lpt_program_iclkip(struct drm_crtc *crtc)
+static void lpt_program_iclkip(struct intel_crtc *crtc)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc->dev);
-       int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       int clock = crtc->config->base.adjusted_mode.crtc_clock;
        u32 divsel, phaseinc, auxdiv, phasedir = 0;
        u32 temp;
 
@@ -4437,12 +4471,12 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
 
 /* Return which DP Port should be selected for Transcoder DP control */
 static enum port
-intel_trans_dp_port_sel(struct drm_crtc *crtc)
+intel_trans_dp_port_sel(struct intel_crtc *crtc)
 {
-       struct drm_device *dev = crtc->dev;
+       struct drm_device *dev = crtc->base.dev;
        struct intel_encoder *encoder;
 
-       for_each_encoder_on_crtc(dev, crtc, encoder) {
+       for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
                if (encoder->type == INTEL_OUTPUT_DP ||
                    encoder->type == INTEL_OUTPUT_EDP)
                        return enc_to_dig_port(&encoder->base)->port;
@@ -4459,18 +4493,18 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
  *   - DP transcoding bits
  *   - transcoder
  */
-static void ironlake_pch_enable(struct drm_crtc *crtc)
+static void ironlake_pch_enable(const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
+       int pipe = crtc->pipe;
        u32 temp;
 
        assert_pch_transcoder_disabled(dev_priv, pipe);
 
        if (IS_IVYBRIDGE(dev_priv))
-               ivybridge_update_fdi_bc_bifurcation(intel_crtc);
+               ivybridge_update_fdi_bc_bifurcation(crtc);
 
        /* Write the TU size bits before fdi link training, so that error
         * detection works. */
@@ -4478,7 +4512,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
                   I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
 
        /* For PCH output, training FDI link */
-       dev_priv->display.fdi_link_train(crtc);
+       dev_priv->display.fdi_link_train(crtc, crtc_state);
 
        /* We need to program the right clock selection before writing the pixel
         * mutliplier into the DPLL. */
@@ -4488,7 +4522,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
                temp = I915_READ(PCH_DPLL_SEL);
                temp |= TRANS_DPLL_ENABLE(pipe);
                sel = TRANS_DPLLB_SEL(pipe);
-               if (intel_crtc->config->shared_dpll ==
+               if (crtc_state->shared_dpll ==
                    intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B))
                        temp |= sel;
                else
@@ -4503,19 +4537,19 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
         * Note that enable_shared_dpll tries to do the right thing, but
         * get_shared_dpll unconditionally resets the pll - we need that to have
         * the right LVDS enable sequence. */
-       intel_enable_shared_dpll(intel_crtc);
+       intel_enable_shared_dpll(crtc);
 
        /* set transcoder timing, panel must allow it */
        assert_panel_unlocked(dev_priv, pipe);
-       ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
+       ironlake_pch_transcoder_set_timings(crtc, pipe);
 
        intel_fdi_normal_train(crtc);
 
        /* For PCH DP, enable TRANS_DP_CTL */
        if (HAS_PCH_CPT(dev_priv) &&
-           intel_crtc_has_dp_encoder(intel_crtc->config)) {
+           intel_crtc_has_dp_encoder(crtc_state)) {
                const struct drm_display_mode *adjusted_mode =
-                       &intel_crtc->config->base.adjusted_mode;
+                       &crtc_state->base.adjusted_mode;
                u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
                i915_reg_t reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
@@ -4550,19 +4584,18 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
        ironlake_enable_pch_transcoder(dev_priv, pipe);
 }
 
-static void lpt_pch_enable(struct drm_crtc *crtc)
+static void lpt_pch_enable(const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
        assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
 
        lpt_program_iclkip(crtc);
 
        /* Set transcoder timing. */
-       ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
+       ironlake_pch_transcoder_set_timings(crtc, PIPE_A);
 
        lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
 }
@@ -4971,8 +5004,6 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
 
        intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits);
 
-       crtc->wm.cxsr_allowed = true;
-
        if (pipe_config->update_wm_post && pipe_config->base.active)
                intel_update_watermarks(crtc);
 
@@ -5019,22 +5050,18 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
                        intel_pre_disable_primary(&crtc->base);
        }
 
-       if (pipe_config->disable_cxsr && HAS_GMCH_DISPLAY(dev_priv)) {
-               crtc->wm.cxsr_allowed = false;
-
-               /*
-                * Vblank time updates from the shadow to live plane control register
-                * are blocked if the memory self-refresh mode is active at that
-                * moment. So to make sure the plane gets truly disabled, disable
-                * first the self-refresh mode. The self-refresh enable bit in turn
-                * will be checked/applied by the HW only at the next frame start
-                * event which is after the vblank start event, so we need to have a
-                * wait-for-vblank between disabling the plane and the pipe.
-                */
-               if (old_crtc_state->base.active &&
-                   intel_set_memory_cxsr(dev_priv, false))
-                       intel_wait_for_vblank(dev_priv, crtc->pipe);
-       }
+       /*
+        * Vblank time updates from the shadow to live plane control register
+        * are blocked if the memory self-refresh mode is active at that
+        * moment. So to make sure the plane gets truly disabled, disable
+        * first the self-refresh mode. The self-refresh enable bit in turn
+        * will be checked/applied by the HW only at the next frame start
+        * event which is after the vblank start event, so we need to have a
+        * wait-for-vblank between disabling the plane and the pipe.
+        */
+       if (HAS_GMCH_DISPLAY(dev_priv) && old_crtc_state->base.active &&
+           pipe_config->disable_cxsr && intel_set_memory_cxsr(dev_priv, false))
+               intel_wait_for_vblank(dev_priv, crtc->pipe);
 
        /*
         * IVB workaround: must disable low power watermarks for at least
@@ -5289,7 +5316,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
        intel_enable_pipe(intel_crtc);
 
        if (intel_crtc->config->has_pch_encoder)
-               ironlake_pch_enable(crtc);
+               ironlake_pch_enable(pipe_config);
 
        assert_vblank_disabled(crtc);
        drm_crtc_vblank_on(crtc);
@@ -5371,10 +5398,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
        intel_encoders_pre_enable(crtc, pipe_config, old_state);
 
        if (intel_crtc->config->has_pch_encoder)
-               dev_priv->display.fdi_link_train(crtc);
+               dev_priv->display.fdi_link_train(intel_crtc, pipe_config);
 
        if (!transcoder_is_dsi(cpu_transcoder))
-               intel_ddi_enable_pipe_clock(intel_crtc);
+               intel_ddi_enable_pipe_clock(pipe_config);
 
        if (INTEL_GEN(dev_priv) >= 9)
                skylake_pfit_enable(intel_crtc);
@@ -5387,9 +5414,9 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
         */
        intel_color_load_luts(&pipe_config->base);
 
-       intel_ddi_set_pipe_settings(crtc);
+       intel_ddi_set_pipe_settings(pipe_config);
        if (!transcoder_is_dsi(cpu_transcoder))
-               intel_ddi_enable_transcoder_func(crtc);
+               intel_ddi_enable_transcoder_func(pipe_config);
 
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state, pipe_config);
@@ -5399,10 +5426,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
                intel_enable_pipe(intel_crtc);
 
        if (intel_crtc->config->has_pch_encoder)
-               lpt_pch_enable(crtc);
+               lpt_pch_enable(pipe_config);
 
        if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DP_MST))
-               intel_ddi_set_vc_payload_alloc(crtc, true);
+               intel_ddi_set_vc_payload_alloc(pipe_config, true);
 
        assert_vblank_disabled(crtc);
        drm_crtc_vblank_on(crtc);
@@ -5524,7 +5551,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
                intel_disable_pipe(intel_crtc);
 
        if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DP_MST))
-               intel_ddi_set_vc_payload_alloc(crtc, false);
+               intel_ddi_set_vc_payload_alloc(intel_crtc->config, false);
 
        if (!transcoder_is_dsi(cpu_transcoder))
                intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
@@ -5535,7 +5562,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
                ironlake_pfit_disable(intel_crtc, false);
 
        if (!transcoder_is_dsi(cpu_transcoder))
-               intel_ddi_disable_pipe_clock(intel_crtc);
+               intel_ddi_disable_pipe_clock(intel_crtc->config);
 
        intel_encoders_post_disable(crtc, old_crtc_state, old_state);
 
@@ -5655,6 +5682,8 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
 static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
                                   struct drm_atomic_state *old_state)
 {
+       struct intel_atomic_state *old_intel_state =
+               to_intel_atomic_state(old_state);
        struct drm_crtc *crtc = pipe_config->base.crtc;
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -5699,7 +5728,8 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 
        intel_color_load_luts(&pipe_config->base);
 
-       intel_update_watermarks(intel_crtc);
+       dev_priv->display.initial_watermarks(old_intel_state,
+                                            pipe_config);
        intel_enable_pipe(intel_crtc);
 
        assert_vblank_disabled(crtc);
@@ -5816,6 +5846,9 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
 
        if (!IS_GEN2(dev_priv))
                intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+
+       if (!dev_priv->display.initial_watermarks)
+               intel_update_watermarks(intel_crtc);
 }
 
 static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
@@ -9657,7 +9690,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
        if (!state)
                return;
 
-       ret = drm_atomic_commit(state);
+       ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
        if (ret)
                DRM_DEBUG_KMS("Couldn't release load detect pipe: %i\n", ret);
        drm_atomic_state_put(state);
@@ -10758,11 +10791,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
        struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
        struct drm_crtc *crtc = crtc_state->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct drm_plane *plane = plane_state->plane;
+       struct intel_plane *plane = to_intel_plane(plane_state->plane);
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane_state *old_plane_state =
-               to_intel_plane_state(plane->state);
+               to_intel_plane_state(plane->base.state);
        bool mode_changed = needs_modeset(crtc_state);
        bool was_crtc_enabled = crtc->state->active;
        bool is_crtc_enabled = crtc_state->active;
@@ -10770,7 +10803,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
        struct drm_framebuffer *fb = plane_state->fb;
        int ret;
 
-       if (INTEL_GEN(dev_priv) >= 9 && plane->type != DRM_PLANE_TYPE_CURSOR) {
+       if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
                ret = skl_update_scaler_plane(
                        to_intel_crtc_state(crtc_state),
                        to_intel_plane_state(plane_state));
@@ -10794,8 +10827,10 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
         * per-plane wm computation to the .check_plane() hook, and
         * only combine the results from all planes in the current place?
         */
-       if (!is_crtc_enabled)
+       if (!is_crtc_enabled) {
                plane_state->visible = visible = false;
+               to_intel_crtc_state(crtc_state)->active_planes &= ~BIT(plane->id);
+       }
 
        if (!was_visible && !visible)
                return 0;
@@ -10807,41 +10842,39 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
        turn_on = visible && (!was_visible || mode_changed);
 
        DRM_DEBUG_ATOMIC("[CRTC:%d:%s] has [PLANE:%d:%s] with fb %i\n",
-                        intel_crtc->base.base.id,
-                        intel_crtc->base.name,
-                        plane->base.id, plane->name,
+                        intel_crtc->base.base.id, intel_crtc->base.name,
+                        plane->base.base.id, plane->base.name,
                         fb ? fb->base.id : -1);
 
        DRM_DEBUG_ATOMIC("[PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
-                        plane->base.id, plane->name,
+                        plane->base.base.id, plane->base.name,
                         was_visible, visible,
                         turn_off, turn_on, mode_changed);
 
        if (turn_on) {
-               pipe_config->update_wm_pre = true;
+               if (INTEL_GEN(dev_priv) < 5)
+                       pipe_config->update_wm_pre = true;
 
                /* must disable cxsr around plane enable/disable */
-               if (plane->type != DRM_PLANE_TYPE_CURSOR)
+               if (plane->id != PLANE_CURSOR)
                        pipe_config->disable_cxsr = true;
        } else if (turn_off) {
-               pipe_config->update_wm_post = true;
+               if (INTEL_GEN(dev_priv) < 5)
+                       pipe_config->update_wm_post = true;
 
                /* must disable cxsr around plane enable/disable */
-               if (plane->type != DRM_PLANE_TYPE_CURSOR)
+               if (plane->id != PLANE_CURSOR)
                        pipe_config->disable_cxsr = true;
-       } else if (intel_wm_need_update(plane, plane_state)) {
-               /* FIXME bollocks */
-               pipe_config->update_wm_pre = true;
-               pipe_config->update_wm_post = true;
+       } else if (intel_wm_need_update(&plane->base, plane_state)) {
+               if (INTEL_GEN(dev_priv) < 5) {
+                       /* FIXME bollocks */
+                       pipe_config->update_wm_pre = true;
+                       pipe_config->update_wm_post = true;
+               }
        }
 
-       /* Pre-gen9 platforms need two-step watermark updates */
-       if ((pipe_config->update_wm_pre || pipe_config->update_wm_post) &&
-           INTEL_GEN(dev_priv) < 9 && dev_priv->display.optimize_watermarks)
-               to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true;
-
        if (visible || was_visible)
-               pipe_config->fb_bits |= to_intel_plane(plane)->frontbuffer_bit;
+               pipe_config->fb_bits |= plane->frontbuffer_bit;
 
        /*
         * WaCxSRDisabledForSpriteScaling:ivb
@@ -10849,7 +10882,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
         * cstate->update_wm was already set above, so this flag will
         * take effect when we commit and program watermarks.
         */
-       if (plane->type == DRM_PLANE_TYPE_OVERLAY && IS_IVYBRIDGE(dev_priv) &&
+       if (plane->id == PLANE_SPRITE0 && IS_IVYBRIDGE(dev_priv) &&
            needs_scaling(to_intel_plane_state(plane_state)) &&
            !needs_scaling(old_plane_state))
                pipe_config->disable_lp_wm = true;
@@ -11238,10 +11271,13 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
 static void
 clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 {
+       struct drm_i915_private *dev_priv =
+               to_i915(crtc_state->base.crtc->dev);
        struct drm_crtc_state tmp_state;
        struct intel_crtc_scaler_state scaler_state;
        struct intel_dpll_hw_state dpll_hw_state;
        struct intel_shared_dpll *shared_dpll;
+       struct intel_crtc_wm_state wm_state;
        bool force_thru;
 
        /* FIXME: before the switch to atomic started, a new pipe_config was
@@ -11254,6 +11290,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
        shared_dpll = crtc_state->shared_dpll;
        dpll_hw_state = crtc_state->dpll_hw_state;
        force_thru = crtc_state->pch_pfit.force_thru;
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               wm_state = crtc_state->wm;
 
        memset(crtc_state, 0, sizeof *crtc_state);
 
@@ -11262,6 +11300,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
        crtc_state->shared_dpll = shared_dpll;
        crtc_state->dpll_hw_state = dpll_hw_state;
        crtc_state->pch_pfit.force_thru = force_thru;
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+               crtc_state->wm = wm_state;
 }
 
 static int
@@ -12576,12 +12616,7 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
        if (crtc_state->update_wm_post)
                return true;
 
-       /*
-        * cxsr is re-enabled after vblank.
-        * This is already handled by crtc_state->update_wm_post,
-        * but added for clarity.
-        */
-       if (crtc_state->disable_cxsr)
+       if (crtc_state->wm.need_postvbl_update)
                return true;
 
        return false;
@@ -12774,12 +12809,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
                                /*
                                 * Make sure we don't call initial_watermarks
                                 * for ILK-style watermark updates.
+                                *
+                                * No clue what this is supposed to achieve.
                                 */
-                               if (dev_priv->display.atomic_update_watermarks)
+                               if (INTEL_GEN(dev_priv) >= 9)
                                        dev_priv->display.initial_watermarks(intel_state,
                                                                             to_intel_crtc_state(crtc->state));
-                               else
-                                       intel_update_watermarks(intel_crtc);
                        }
                }
        }
@@ -13462,12 +13497,15 @@ intel_legacy_cursor_update(struct drm_plane *plane,
        new_plane_state->fb = old_fb;
        to_intel_plane_state(new_plane_state)->vma = old_vma;
 
-       if (plane->state->visible)
+       if (plane->state->visible) {
+               trace_intel_update_plane(plane, to_intel_crtc(crtc));
                intel_plane->update_plane(plane,
                                          to_intel_crtc_state(crtc->state),
                                          to_intel_plane_state(plane->state));
-       else
+       } else {
+               trace_intel_disable_plane(plane, to_intel_crtc(crtc));
                intel_plane->disable_plane(plane, crtc);
+       }
 
        intel_cleanup_plane_fb(plane, new_plane_state);
 
@@ -13850,8 +13888,6 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
        intel_crtc->cursor_cntl = ~0;
        intel_crtc->cursor_size = ~0;
 
-       intel_crtc->wm.cxsr_allowed = true;
-
        /* initialize shared scalers */
        intel_crtc_init_scalers(intel_crtc, crtc_state);
 
@@ -14851,7 +14887,8 @@ retry:
         * intermediate watermarks (since we don't trust the current
         * watermarks).
         */
-       intel_state->skip_intermediate_wm = true;
+       if (!HAS_GMCH_DISPLAY(dev_priv))
+               intel_state->skip_intermediate_wm = true;
 
        ret = intel_atomic_check(dev, state);
        if (ret) {
@@ -14970,12 +15007,11 @@ int intel_modeset_init(struct drm_device *dev)
                }
        }
 
-       intel_update_czclk(dev_priv);
-       intel_update_cdclk(dev_priv);
-       dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw;
-
        intel_shared_dpll_init(dev);
 
+       intel_update_czclk(dev_priv);
+       intel_modeset_init_hw(dev);
+
        if (dev_priv->max_cdclk_freq == 0)
                intel_update_max_cdclk(dev_priv);
 
@@ -15015,7 +15051,8 @@ int intel_modeset_init(struct drm_device *dev)
         * Note that we need to do this after reconstructing the BIOS fb's
         * since the watermark calculation done here will use pstate->fb.
         */
-       sanitize_watermarks(dev);
+       if (!HAS_GMCH_DISPLAY(dev_priv))
+               sanitize_watermarks(dev);
 
        return 0;
 }
@@ -15117,6 +15154,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                        if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
                                continue;
 
+                       trace_intel_disable_plane(&plane->base, crtc);
                        plane->disable_plane(&plane->base, &crtc->base);
                }
        }
@@ -15263,15 +15301,14 @@ static bool primary_get_hw_state(struct intel_plane *plane)
 /* FIXME read out full plane state for all planes */
 static void readout_plane_state(struct intel_crtc *crtc)
 {
-       struct drm_plane *primary = crtc->base.primary;
-       struct intel_plane_state *plane_state =
-               to_intel_plane_state(primary->state);
+       struct intel_plane *primary = to_intel_plane(crtc->base.primary);
+       bool visible;
 
-       plane_state->base.visible = crtc->active &&
-               primary_get_hw_state(to_intel_plane(primary));
+       visible = crtc->active && primary_get_hw_state(primary);
 
-       if (plane_state->base.visible)
-               crtc->base.state->plane_mask |= 1 << drm_plane_index(primary);
+       intel_set_plane_visible(to_intel_crtc_state(crtc->base.state),
+                               to_intel_plane_state(primary->base.state),
+                               visible);
 }
 
 static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -15487,12 +15524,14 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
                pll->on = false;
        }
 
-       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                vlv_wm_get_hw_state(dev);
-       else if (IS_GEN9(dev_priv))
+               vlv_wm_sanitize(dev_priv);
+       } else if (IS_GEN9(dev_priv)) {
                skl_wm_get_hw_state(dev);
-       else if (HAS_PCH_SPLIT(dev_priv))
+       } else if (HAS_PCH_SPLIT(dev_priv)) {
                ilk_wm_get_hw_state(dev);
+       }
 
        for_each_intel_crtc(dev, crtc) {
                u64 put_domains;
@@ -15537,7 +15576,7 @@ void intel_display_resume(struct drm_device *dev)
        }
 
        if (!ret)
-               ret = __intel_display_resume(dev, state);
+               ret = __intel_display_resume(dev, state, &ctx);
 
        drm_modeset_drop_locks(&ctx);
        drm_modeset_acquire_fini(&ctx);
@@ -15555,8 +15594,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
 
        intel_init_gt_powersave(dev_priv);
 
-       intel_modeset_init_hw(dev);
-
        intel_setup_overlay(dev_priv);
 }