drm/i915: move intel_hrawclk() to intel_display.c
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / intel_display.c
index 9e4ced583ef02bdcea9d44d47e5a8924335eb242..3f60cf4fe6fd8a2b6589893c7971ec7ccae9e58b 100644 (file)
@@ -102,8 +102,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
                            const struct intel_crtc_state *pipe_config);
 static void chv_prepare_pll(struct intel_crtc *crtc,
                            const struct intel_crtc_state *pipe_config);
-static void intel_begin_crtc_commit(struct drm_crtc *crtc);
-static void intel_finish_crtc_commit(struct drm_crtc *crtc);
+static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
+static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
 static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
        struct intel_crtc_state *crtc_state);
 static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
@@ -135,6 +135,39 @@ 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 inline u32 /* units of 100MHz */
 intel_fdi_link_freq(struct drm_device *dev)
 {
@@ -413,7 +446,7 @@ static const intel_limit_t intel_limits_bxt = {
 static bool
 needs_modeset(struct drm_crtc_state *state)
 {
-       return state->mode_changed || state->active_changed;
+       return drm_atomic_crtc_needs_modeset(state);
 }
 
 /**
@@ -1061,51 +1094,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;
-               default:
-                       return true;
-               }
-       }
-
-       return I915_READ(SDEISR) & bit;
-}
-
 static const char *state_string(bool enabled)
 {
        return enabled ? "on" : "off";
@@ -1582,26 +1570,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)
 {
@@ -1828,17 +1796,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);
 }
 
@@ -2397,7 +2354,18 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane,
         * a fence as the cost is not that onerous.
         */
        ret = i915_gem_object_get_fence(obj);
-       if (ret)
+       if (ret == -EDEADLK) {
+               /*
+                * -EDEADLK means there are no free fences
+                * no pending flips.
+                *
+                * This is propagated to atomic, but it uses
+                * -EDEADLK to force a locking recovery, so
+                * change the returned error to -EBUSY.
+                */
+               ret = -EBUSY;
+               goto err_unpin;
+       } else if (ret)
                goto err_unpin;
 
        i915_gem_object_pin_fence(obj);
@@ -2922,8 +2890,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);
 }
 
 /*
@@ -5136,6 +5102,7 @@ static enum intel_display_power_domain port_to_power_domain(enum port port)
 {
        switch (port) {
        case PORT_A:
+       case PORT_E:
                return POWER_DOMAIN_PORT_DDI_A_4_LANES;
        case PORT_B:
                return POWER_DOMAIN_PORT_DDI_B_4_LANES;
@@ -5261,6 +5228,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;
@@ -5300,8 +5282,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)
@@ -6022,13 +6009,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);
 
@@ -6052,10 +6032,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)
@@ -6183,6 +6166,10 @@ 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);
 
@@ -6273,67 +6260,6 @@ free:
        return ret;
 }
 
-/* Master function to enable/disable CRTC and corresponding power wells */
-int intel_crtc_control(struct drm_crtc *crtc, bool enable)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_mode_config *config = &dev->mode_config;
-       struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_crtc_state *pipe_config;
-       struct drm_atomic_state *state;
-       int ret;
-
-       if (enable == intel_crtc->active)
-               return 0;
-
-       if (enable && !crtc->state->enable)
-               return 0;
-
-       /* this function should be called with drm_modeset_lock_all for now */
-       if (WARN_ON(!ctx))
-               return -EIO;
-       lockdep_assert_held(&ctx->ww_ctx);
-
-       state = drm_atomic_state_alloc(dev);
-       if (WARN_ON(!state))
-               return -ENOMEM;
-
-       state->acquire_ctx = ctx;
-       state->allow_modeset = true;
-
-       pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
-       if (IS_ERR(pipe_config)) {
-               ret = PTR_ERR(pipe_config);
-               goto err;
-       }
-       pipe_config->base.active = enable;
-
-       ret = drm_atomic_commit(state);
-       if (!ret)
-               return ret;
-
-err:
-       DRM_ERROR("Updating crtc active failed with %i\n", ret);
-       drm_atomic_state_free(state);
-       return ret;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- */
-void intel_crtc_update_dpms(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct intel_encoder *intel_encoder;
-       bool enable = false;
-
-       for_each_encoder_on_crtc(dev, crtc, intel_encoder)
-               enable |= intel_encoder->connectors_active;
-
-       intel_crtc_control(crtc, enable);
-}
-
 void intel_encoder_destroy(struct drm_encoder *encoder)
 {
        struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
@@ -6342,62 +6268,42 @@ void intel_encoder_destroy(struct drm_encoder *encoder)
        kfree(intel_encoder);
 }
 
-/* Simple dpms helper for encoders with just one connector, no cloning and only
- * one kind of off state. It clamps all !ON modes to fully OFF and changes the
- * state of the entire output pipe. */
-static void intel_encoder_dpms(struct intel_encoder *encoder, int mode)
-{
-       if (mode == DRM_MODE_DPMS_ON) {
-               encoder->connectors_active = true;
-
-               intel_crtc_update_dpms(encoder->base.crtc);
-       } else {
-               encoder->connectors_active = false;
-
-               intel_crtc_update_dpms(encoder->base.crtc);
-       }
-}
-
 /* Cross check the actual hw state with our own modeset state tracking (and it's
  * internal consistency). */
 static void intel_connector_check_state(struct intel_connector *connector)
 {
+       struct drm_crtc *crtc = connector->base.state->crtc;
+
+       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+                     connector->base.base.id,
+                     connector->base.name);
+
        if (connector->get_hw_state(connector)) {
-               struct intel_encoder *encoder = connector->encoder;
-               struct drm_crtc *crtc;
-               bool encoder_enabled;
-               enum pipe pipe;
+               struct drm_encoder *encoder = &connector->encoder->base;
+               struct drm_connector_state *conn_state = connector->base.state;
 
-               DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-                             connector->base.base.id,
-                             connector->base.name);
+               I915_STATE_WARN(!crtc,
+                        "connector enabled without attached crtc\n");
 
-               /* there is no real hw state for MST connectors */
-               if (connector->mst_port)
+               if (!crtc)
                        return;
 
-               I915_STATE_WARN(connector->base.dpms == DRM_MODE_DPMS_OFF,
-                    "wrong connector dpms state\n");
-               I915_STATE_WARN(connector->base.encoder != &encoder->base,
-                    "active connector not linked to encoder\n");
-
-               if (encoder) {
-                       I915_STATE_WARN(!encoder->connectors_active,
-                            "encoder->connectors_active not set\n");
+               I915_STATE_WARN(!crtc->state->active,
+                     "connector is active, but attached crtc isn't\n");
 
-                       encoder_enabled = encoder->get_hw_state(encoder, &pipe);
-                       I915_STATE_WARN(!encoder_enabled, "encoder not enabled\n");
-                       if (I915_STATE_WARN_ON(!encoder->base.crtc))
-                               return;
+               if (!encoder)
+                       return;
 
-                       crtc = encoder->base.crtc;
+               I915_STATE_WARN(conn_state->best_encoder != encoder,
+                       "atomic encoder doesn't match attached encoder\n");
 
-                       I915_STATE_WARN(!crtc->state->enable,
-                                       "crtc not enabled\n");
-                       I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
-                       I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe,
-                            "encoder active on the wrong pipe\n");
-               }
+               I915_STATE_WARN(conn_state->crtc != encoder->crtc,
+                       "attached encoder crtc differs from connector crtc\n");
+       } else {
+               I915_STATE_WARN(crtc && crtc->state->active,
+                       "attached crtc is active, but connector isn't\n");
+               I915_STATE_WARN(!crtc && connector->base.state->best_encoder,
+                       "best encoder set without crtc!\n");
        }
 }
 
@@ -6429,26 +6335,6 @@ struct intel_connector *intel_connector_alloc(void)
        return connector;
 }
 
-/* Even simpler default implementation, if there's really no special case to
- * consider. */
-void intel_connector_dpms(struct drm_connector *connector, int mode)
-{
-       /* All the simple cases only support two dpms states. */
-       if (mode != DRM_MODE_DPMS_ON)
-               mode = DRM_MODE_DPMS_OFF;
-
-       if (mode == connector->dpms)
-               return;
-
-       connector->dpms = mode;
-
-       /* Only need to change hw state when actually enabled */
-       if (connector->encoder)
-               intel_encoder_dpms(to_intel_encoder(connector->encoder), mode);
-
-       intel_modeset_check_state(connector->dev);
-}
-
 /* Simple connector->get_hw_state implementation for encoders that support only
  * one connector and no cloning and hence the encoder state determines the state
  * of the connector. */
@@ -7465,8 +7351,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));
@@ -8207,6 +8092,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;
 }
 
@@ -11122,10 +11015,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);
@@ -11325,6 +11218,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;
 
@@ -11715,7 +11611,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;
 
@@ -11837,7 +11733,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
        struct intel_crtc_state *pipe_config =
                to_intel_crtc_state(crtc_state);
        struct drm_atomic_state *state = crtc_state->state;
-       int ret, idx = crtc->base.id;
+       int ret;
        bool mode_changed = needs_modeset(crtc_state);
 
        if (mode_changed && !check_encoder_cloning(state, intel_crtc)) {
@@ -11845,10 +11741,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
                return -EINVAL;
        }
 
-       I915_STATE_WARN(crtc->state->active != intel_crtc->active,
-               "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n",
-               idx, crtc->state->active, intel_crtc->active);
-
        if (mode_changed && !crtc_state->active)
                intel_crtc->atomic.update_wm_post = true;
 
@@ -11992,14 +11884,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,
@@ -12157,6 +12051,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
        struct intel_dpll_hw_state dpll_hw_state;
        enum intel_dpll_id shared_dpll;
        uint32_t ddi_pll_sel;
+       bool force_thru;
 
        /* FIXME: before the switch to atomic started, a new pipe_config was
         * kzalloc'd. Code that depends on any field being zero should be
@@ -12168,6 +12063,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
        shared_dpll = crtc_state->shared_dpll;
        dpll_hw_state = crtc_state->dpll_hw_state;
        ddi_pll_sel = crtc_state->ddi_pll_sel;
+       force_thru = crtc_state->pch_pfit.force_thru;
 
        memset(crtc_state, 0, sizeof *crtc_state);
 
@@ -12176,6 +12072,7 @@ 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->ddi_pll_sel = ddi_pll_sel;
+       crtc_state->pch_pfit.force_thru = force_thru;
 }
 
 static int
@@ -12277,7 +12174,9 @@ encoder_retry:
                goto encoder_retry;
        }
 
-       pipe_config->dither = pipe_config->pipe_bpp != base_bpp;
+       /* 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",
                      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
@@ -12285,48 +12184,15 @@ fail:
        return ret;
 }
 
-static bool intel_crtc_in_use(struct drm_crtc *crtc)
-{
-       struct drm_encoder *encoder;
-       struct drm_device *dev = crtc->dev;
-
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-               if (encoder->crtc == crtc)
-                       return true;
-
-       return false;
-}
-
 static void
-intel_modeset_update_state(struct drm_atomic_state *state)
+intel_modeset_update_crtc_state(struct drm_atomic_state *state)
 {
-       struct drm_device *dev = state->dev;
-       struct intel_encoder *intel_encoder;
        struct drm_crtc *crtc;
        struct drm_crtc_state *crtc_state;
-       struct drm_connector *connector;
        int i;
 
-       intel_shared_dpll_commit(state);
-
-       for_each_intel_encoder(dev, intel_encoder) {
-               if (!intel_encoder->base.crtc)
-                       continue;
-
-               crtc = intel_encoder->base.crtc;
-               crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
-               if (!crtc_state || !needs_modeset(crtc->state))
-                       continue;
-
-               intel_encoder->connectors_active = false;
-       }
-
-       drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
-
        /* Double check state. */
        for_each_crtc_in_state(state, crtc, crtc_state, i) {
-               WARN_ON(crtc->state->enable != intel_crtc_in_use(crtc));
-
                to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
 
                /* Update hwmode for vblank functions */
@@ -12335,28 +12201,6 @@ intel_modeset_update_state(struct drm_atomic_state *state)
                else
                        crtc->hwmode.crtc_clock = 0;
        }
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               if (!connector->encoder || !connector->encoder->crtc)
-                       continue;
-
-               crtc = connector->encoder->crtc;
-               crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
-               if (!crtc_state || !needs_modeset(crtc->state))
-                       continue;
-
-               if (crtc->state->active) {
-                       struct drm_property *dpms_property =
-                               dev->mode_config.dpms_property;
-
-                       connector->dpms = DRM_MODE_DPMS_ON;
-                       drm_object_property_set_value(&connector->base, dpms_property, DRM_MODE_DPMS_ON);
-
-                       intel_encoder = to_intel_encoder(connector->encoder);
-                       intel_encoder->connectors_active = true;
-               } else
-                       connector->dpms = DRM_MODE_DPMS_OFF;
-       }
 }
 
 static bool intel_fuzzy_clock_check(int clock1, int clock2)
@@ -12556,6 +12400,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);
@@ -12706,20 +12551,23 @@ static void check_wm_state(struct drm_device *dev)
 }
 
 static void
-check_connector_state(struct drm_device *dev)
+check_connector_state(struct drm_device *dev,
+                     struct drm_atomic_state *old_state)
 {
-       struct intel_connector *connector;
+       struct drm_connector_state *old_conn_state;
+       struct drm_connector *connector;
+       int i;
 
-       for_each_intel_connector(dev, connector) {
-               struct drm_encoder *encoder = connector->base.encoder;
-               struct drm_connector_state *state = connector->base.state;
+       for_each_connector_in_state(old_state, connector, old_conn_state, i) {
+               struct drm_encoder *encoder = connector->encoder;
+               struct drm_connector_state *state = connector->state;
 
                /* This also checks the encoder/connector hw state with the
                 * ->get_hw_state callbacks. */
-               intel_connector_check_state(connector);
+               intel_connector_check_state(to_intel_connector(connector));
 
                I915_STATE_WARN(state->best_encoder != encoder,
-                    "connector's staged encoder doesn't match current encoder\n");
+                    "connector's atomic encoder doesn't match legacy encoder\n");
        }
 }
 
@@ -12731,133 +12579,106 @@ check_encoder_state(struct drm_device *dev)
 
        for_each_intel_encoder(dev, encoder) {
                bool enabled = false;
-               bool active = false;
-               enum pipe pipe, tracked_pipe;
+               enum pipe pipe;
 
                DRM_DEBUG_KMS("[ENCODER:%d:%s]\n",
                              encoder->base.base.id,
                              encoder->base.name);
 
-               I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
-                    "encoder's active_connectors set, but no crtc\n");
-
                for_each_intel_connector(dev, connector) {
-                       if (connector->base.encoder != &encoder->base)
+                       if (connector->base.state->best_encoder != &encoder->base)
                                continue;
                        enabled = true;
-                       if (connector->base.dpms != DRM_MODE_DPMS_OFF)
-                               active = true;
 
                        I915_STATE_WARN(connector->base.state->crtc !=
                                        encoder->base.crtc,
                             "connector's crtc doesn't match encoder crtc\n");
                }
-               /*
-                * for MST connectors if we unplug the connector is gone
-                * away but the encoder is still connected to a crtc
-                * until a modeset happens in response to the hotplug.
-                */
-               if (!enabled && encoder->base.encoder_type == DRM_MODE_ENCODER_DPMST)
-                       continue;
 
                I915_STATE_WARN(!!encoder->base.crtc != enabled,
                     "encoder's enabled state mismatch "
                     "(expected %i, found %i)\n",
                     !!encoder->base.crtc, enabled);
-               I915_STATE_WARN(active && !encoder->base.crtc,
-                    "active encoder with no crtc\n");
-
-               I915_STATE_WARN(encoder->connectors_active != active,
-                    "encoder's computed active state doesn't match tracked active state "
-                    "(expected %i, found %i)\n", active, encoder->connectors_active);
-
-               active = encoder->get_hw_state(encoder, &pipe);
-               I915_STATE_WARN(active != encoder->connectors_active,
-                    "encoder's hw state doesn't match sw tracking "
-                    "(expected %i, found %i)\n",
-                    encoder->connectors_active, active);
 
-               if (!encoder->base.crtc)
-                       continue;
-
-               tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe;
-               I915_STATE_WARN(active && pipe != tracked_pipe,
-                    "active encoder's pipe doesn't match"
-                    "(expected %i, found %i)\n",
-                    tracked_pipe, pipe);
+               if (!encoder->base.crtc) {
+                       bool active;
 
+                       active = encoder->get_hw_state(encoder, &pipe);
+                       I915_STATE_WARN(active,
+                            "encoder detached but still enabled on pipe %c.\n",
+                            pipe_name(pipe));
+               }
        }
 }
 
 static void
-check_crtc_state(struct drm_device *dev)
+check_crtc_state(struct drm_device *dev, struct drm_atomic_state *old_state)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *crtc;
        struct intel_encoder *encoder;
-       struct intel_crtc_state pipe_config;
+       struct drm_crtc_state *old_crtc_state;
+       struct drm_crtc *crtc;
+       int i;
 
-       for_each_intel_crtc(dev, crtc) {
-               bool enabled = false;
-               bool active = false;
+       for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+               struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+               struct intel_crtc_state *pipe_config, *sw_config;
+               bool active;
 
-               memset(&pipe_config, 0, sizeof(pipe_config));
+               if (!needs_modeset(crtc->state))
+                       continue;
 
-               DRM_DEBUG_KMS("[CRTC:%d]\n",
-                             crtc->base.base.id);
+               __drm_atomic_helper_crtc_destroy_state(crtc, old_crtc_state);
+               pipe_config = to_intel_crtc_state(old_crtc_state);
+               memset(pipe_config, 0, sizeof(*pipe_config));
+               pipe_config->base.crtc = crtc;
+               pipe_config->base.state = old_state;
 
-               I915_STATE_WARN(crtc->active && !crtc->base.state->enable,
-                    "active crtc, but not enabled in sw tracking\n");
+               DRM_DEBUG_KMS("[CRTC:%d]\n",
+                             crtc->base.id);
 
-               for_each_intel_encoder(dev, encoder) {
-                       if (encoder->base.crtc != &crtc->base)
-                               continue;
-                       enabled = true;
-                       if (encoder->connectors_active)
-                               active = true;
-               }
+               active = dev_priv->display.get_pipe_config(intel_crtc,
+                                                          pipe_config);
 
-               I915_STATE_WARN(active != crtc->active,
-                    "crtc's computed active state doesn't match tracked active state "
-                    "(expected %i, found %i)\n", active, crtc->active);
-               I915_STATE_WARN(enabled != crtc->base.state->enable,
-                    "crtc's computed enabled state doesn't match tracked enabled state "
-                    "(expected %i, found %i)\n", enabled,
-                               crtc->base.state->enable);
+               /* hw state is inconsistent with the pipe quirk */
+               if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+                   (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+                       active = crtc->state->active;
 
-               active = dev_priv->display.get_pipe_config(crtc,
-                                                          &pipe_config);
+               I915_STATE_WARN(crtc->state->active != active,
+                    "crtc active state doesn't match with hw state "
+                    "(expected %i, found %i)\n", crtc->state->active, active);
 
-               /* hw state is inconsistent with the pipe quirk */
-               if ((crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
-                   (crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
-                       active = crtc->active;
+               I915_STATE_WARN(intel_crtc->active != crtc->state->active,
+                    "transitional active state does not match atomic hw state "
+                    "(expected %i, found %i)\n", crtc->state->active, intel_crtc->active);
 
-               for_each_intel_encoder(dev, encoder) {
+               for_each_encoder_on_crtc(dev, crtc, encoder) {
                        enum pipe pipe;
-                       if (encoder->base.crtc != &crtc->base)
-                               continue;
-                       if (encoder->get_hw_state(encoder, &pipe))
-                               encoder->get_config(encoder, &pipe_config);
-               }
 
-               I915_STATE_WARN(crtc->active != active,
-                    "crtc active state doesn't match with hw state "
-                    "(expected %i, found %i)\n", crtc->active, active);
+                       active = encoder->get_hw_state(encoder, &pipe);
+                       I915_STATE_WARN(active != crtc->state->active,
+                               "[ENCODER:%i] active %i with crtc active %i\n",
+                               encoder->base.base.id, active, crtc->state->active);
 
-               I915_STATE_WARN(crtc->active != crtc->base.state->active,
-                    "transitional active state does not match atomic hw state "
-                    "(expected %i, found %i)\n", crtc->base.state->active, crtc->active);
+                       I915_STATE_WARN(active && intel_crtc->pipe != pipe,
+                                       "Encoder connected to wrong pipe %c\n",
+                                       pipe_name(pipe));
 
-               if (!active)
+                       if (active)
+                               encoder->get_config(encoder, pipe_config);
+               }
+
+               if (!crtc->state->active)
                        continue;
 
-               if (!intel_pipe_config_compare(dev, crtc->config,
-                                              &pipe_config, false)) {
+               sw_config = to_intel_crtc_state(crtc->state);
+               if (!intel_pipe_config_compare(dev, sw_config,
+                                              pipe_config, false)) {
                        I915_STATE_WARN(1, "pipe state doesn't match!\n");
-                       intel_dump_pipe_config(crtc, &pipe_config,
+                       intel_dump_pipe_config(intel_crtc, pipe_config,
                                               "[hw state]");
-                       intel_dump_pipe_config(crtc, crtc->config,
+                       intel_dump_pipe_config(intel_crtc, sw_config,
                                               "[sw state]");
                }
        }
@@ -12912,13 +12733,14 @@ check_shared_dpll_state(struct drm_device *dev)
        }
 }
 
-void
-intel_modeset_check_state(struct drm_device *dev)
+static void
+intel_modeset_check_state(struct drm_device *dev,
+                         struct drm_atomic_state *old_state)
 {
        check_wm_state(dev);
-       check_connector_state(dev);
+       check_connector_state(dev, old_state);
        check_encoder_state(dev);
-       check_crtc_state(dev);
+       check_crtc_state(dev, old_state);
        check_shared_dpll_state(dev);
 }
 
@@ -13274,12 +13096,14 @@ static int intel_atomic_commit(struct drm_device *dev,
 
        /* Only after disabling all output pipelines that will be changed can we
         * update the the output configuration. */
-       intel_modeset_update_state(state);
+       intel_modeset_update_crtc_state(state);
 
-       /* The state has been swaped above, so state actually contains the
-        * old state now. */
-       if (any_ms)
+       if (any_ms) {
+               intel_shared_dpll_commit(state);
+
+               drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
                modeset_update_crtc_power_domains(state);
+       }
 
        /* Now enable the clocks, plane, pipe, and connectors that we set up. */
        for_each_crtc_in_state(state, crtc, crtc_state, i) {
@@ -13302,10 +13126,11 @@ static int intel_atomic_commit(struct drm_device *dev,
 
        drm_atomic_helper_wait_for_vblanks(dev, state);
        drm_atomic_helper_cleanup_planes(dev, state);
-       drm_atomic_state_free(state);
 
        if (any_ms)
-               intel_modeset_check_state(dev);
+               intel_modeset_check_state(dev, state);
+
+       drm_atomic_state_free(state);
 
        return 0;
 }
@@ -13627,7 +13452,8 @@ intel_disable_primary_plane(struct drm_plane *plane,
        dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
 }
 
-static void intel_begin_crtc_commit(struct drm_crtc *crtc)
+static void intel_begin_crtc_commit(struct drm_crtc *crtc,
+                                   struct drm_crtc_state *old_crtc_state)
 {
        struct drm_device *dev = crtc->dev;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -13643,7 +13469,8 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
                skl_detach_scalers(intel_crtc);
 }
 
-static void intel_finish_crtc_commit(struct drm_crtc *crtc)
+static void intel_finish_crtc_commit(struct drm_crtc *crtc,
+                                    struct drm_crtc_state *old_crtc_state)
 {
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
@@ -14108,8 +13935,7 @@ static void intel_setup_outputs(struct drm_device *dev)
                 */
                found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED;
                /* WaIgnoreDDIAStrap: skl */
-               if (found ||
-                   (IS_SKYLAKE(dev) && INTEL_REVID(dev) < SKL_REVID_D0))
+               if (found || IS_SKYLAKE(dev))
                        intel_ddi_init(dev, PORT_A);
 
                /* DDI B, C and D detection is indicated by the SFUSE_STRAP
@@ -14933,8 +14759,6 @@ void intel_modeset_init(struct drm_device *dev)
                }
        }
 
-       intel_init_dpio(dev);
-
        intel_shared_dpll_init(dev);
 
        /* Just disable it once at startup */
@@ -15016,13 +14840,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);
@@ -15066,14 +14899,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 |= encoder->connectors_active;
-
-       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,
@@ -15095,10 +14925,8 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                 *  actually up, hence no need to break them. */
                WARN_ON(crtc->active);
 
-               for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
-                       WARN_ON(encoder->connectors_active);
+               for_each_encoder_on_crtc(dev, &crtc->base, encoder)
                        encoder->base.crtc = NULL;
-               }
        }
 
        if (crtc->active || HAS_GMCH_DISPLAY(dev)) {
@@ -15124,6 +14952,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
 {
        struct intel_connector *connector;
        struct drm_device *dev = encoder->base.dev;
+       bool active = false;
 
        /* We need to check both for a crtc link (meaning that the
         * encoder is active and trying to read from a pipe) and the
@@ -15131,7 +14960,15 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
        bool has_active_crtc = encoder->base.crtc &&
                to_intel_crtc(encoder->base.crtc)->active;
 
-       if (encoder->connectors_active && !has_active_crtc) {
+       for_each_intel_connector(dev, connector) {
+               if (connector->base.encoder != &encoder->base)
+                       continue;
+
+               active = true;
+               break;
+       }
+
+       if (active && !has_active_crtc) {
                DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
                              encoder->base.base.id,
                              encoder->base.name);
@@ -15148,7 +14985,6 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
                                encoder->post_disable(encoder);
                }
                encoder->base.crtc = NULL;
-               encoder->connectors_active = false;
 
                /* Inconsistent output/port/pipe state happens presumably due to
                 * a bug in one of the get_hw_state functions. Or someplace else
@@ -15310,7 +15146,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                        encoder->base.crtc = NULL;
                }
 
-               encoder->connectors_active = false;
                DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
                              encoder->base.base.id,
                              encoder->base.name,
@@ -15321,7 +15156,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
        for_each_intel_connector(dev, connector) {
                if (connector->get_hw_state(connector)) {
                        connector->base.dpms = DRM_MODE_DPMS_ON;
-                       connector->encoder->connectors_active = true;
                        connector->base.encoder = &connector->encoder->base;
                } else {
                        connector->base.dpms = DRM_MODE_DPMS_OFF;