drm/i915: Init lspcon after HPD in intel_dp_detect()
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_ddi.c
index a49ff3a..b4c5203 100644 (file)
@@ -572,13 +572,13 @@ static const struct cnl_ddi_buf_trans ehl_combo_phy_ddi_translations_dp[] = {
                                                /* NT mV Trans mV db    */
        { 0xA, 0x33, 0x3F, 0x00, 0x00 },        /* 350   350      0.0   */
        { 0xA, 0x47, 0x36, 0x00, 0x09 },        /* 350   500      3.1   */
-       { 0xC, 0x64, 0x30, 0x00, 0x0F },        /* 350   700      6.0   */
-       { 0x6, 0x7F, 0x2C, 0x00, 0x13 },        /* 350   900      8.2   */
+       { 0xC, 0x64, 0x34, 0x00, 0x0B },        /* 350   700      6.0   */
+       { 0x6, 0x7F, 0x30, 0x00, 0x0F },        /* 350   900      8.2   */
        { 0xA, 0x46, 0x3F, 0x00, 0x00 },        /* 500   500      0.0   */
-       { 0xC, 0x64, 0x36, 0x00, 0x09 },        /* 500   700      2.9   */
-       { 0x6, 0x7F, 0x30, 0x00, 0x0F },        /* 500   900      5.1   */
+       { 0xC, 0x64, 0x38, 0x00, 0x07 },        /* 500   700      2.9   */
+       { 0x6, 0x7F, 0x32, 0x00, 0x0D },        /* 500   900      5.1   */
        { 0xC, 0x61, 0x3F, 0x00, 0x00 },        /* 650   700      0.6   */
-       { 0x6, 0x7F, 0x37, 0x00, 0x08 },        /* 600   900      3.5   */
+       { 0x6, 0x7F, 0x38, 0x00, 0x07 },        /* 600   900      3.5   */
        { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 900   900      0.0   */
 };
 
@@ -706,6 +706,42 @@ static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2[] =
        { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 900   900      0.0   */
 };
 
+static const struct cnl_ddi_buf_trans tgl_uy_combo_phy_ddi_translations_dp_hbr2[] = {
+                                               /* NT mV Trans mV db    */
+       { 0xA, 0x35, 0x3F, 0x00, 0x00 },        /* 350   350      0.0   */
+       { 0xA, 0x4F, 0x36, 0x00, 0x09 },        /* 350   500      3.1   */
+       { 0xC, 0x60, 0x32, 0x00, 0x0D },        /* 350   700      6.0   */
+       { 0xC, 0x7F, 0x2D, 0x00, 0x12 },        /* 350   900      8.2   */
+       { 0xC, 0x47, 0x3F, 0x00, 0x00 },        /* 500   500      0.0   */
+       { 0xC, 0x6F, 0x36, 0x00, 0x09 },        /* 500   700      2.9   */
+       { 0x6, 0x7D, 0x32, 0x00, 0x0D },        /* 500   900      5.1   */
+       { 0x6, 0x60, 0x3C, 0x00, 0x03 },        /* 650   700      0.6   */
+       { 0x6, 0x7F, 0x34, 0x00, 0x0B },        /* 600   900      3.5   */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 900   900      0.0   */
+};
+
+/*
+ * Cloned the HOBL entry to comply with the voltage and pre-emphasis entries
+ * that DisplayPort specification requires
+ */
+static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_edp_hbr2_hobl[] = {
+                                               /* VS   pre-emp */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 0    0       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 0    1       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 0    2       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 0    3       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 1    0       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 1    1       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 1    2       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 2    0       */
+       { 0x6, 0x7F, 0x3F, 0x00, 0x00 },        /* 2    1       */
+};
+
+static bool is_hobl_buf_trans(const struct cnl_ddi_buf_trans *table)
+{
+       return table == tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
+}
+
 static const struct ddi_buf_trans *
 bdw_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
 {
@@ -998,86 +1034,240 @@ cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
 }
 
 static const struct cnl_ddi_buf_trans *
-icl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
-                       int *n_entries)
+icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
+                            const struct intel_crtc_state *crtc_state,
+                            int *n_entries)
+{
+       *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
+       return icl_combo_phy_ddi_translations_hdmi;
+}
+
+static const struct cnl_ddi_buf_trans *
+icl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+                          const struct intel_crtc_state *crtc_state,
+                          int *n_entries)
+{
+       *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
+       return icl_combo_phy_ddi_translations_dp_hbr2;
+}
+
+static const struct cnl_ddi_buf_trans *
+icl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+                           const struct intel_crtc_state *crtc_state,
+                           int *n_entries)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
-       if (type == INTEL_OUTPUT_HDMI) {
-               *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
-               return icl_combo_phy_ddi_translations_hdmi;
-       } else if (rate > 540000 && type == INTEL_OUTPUT_EDP) {
+       if (crtc_state->port_clock > 540000) {
                *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
                return icl_combo_phy_ddi_translations_edp_hbr3;
-       } else if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
+       } else if (dev_priv->vbt.edp.low_vswing) {
                *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
                return icl_combo_phy_ddi_translations_edp_hbr2;
        }
 
-       *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
-       return icl_combo_phy_ddi_translations_dp_hbr2;
+       return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct cnl_ddi_buf_trans *
+icl_get_combo_buf_trans(struct intel_encoder *encoder,
+                       const struct intel_crtc_state *crtc_state,
+                       int *n_entries)
+{
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+               return icl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+       else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+               return icl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+       else
+               return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
 }
 
 static const struct icl_mg_phy_ddi_buf_trans *
-icl_get_mg_buf_trans(struct intel_encoder *encoder, int type, int rate,
-                    int *n_entries)
+icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder,
+                         const struct intel_crtc_state *crtc_state,
+                         int *n_entries)
 {
-       if (type == INTEL_OUTPUT_HDMI) {
-               *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
-               return icl_mg_phy_ddi_translations_hdmi;
-       } else if (rate > 270000) {
+       *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
+       return icl_mg_phy_ddi_translations_hdmi;
+}
+
+static const struct icl_mg_phy_ddi_buf_trans *
+icl_get_mg_buf_trans_dp(struct intel_encoder *encoder,
+                       const struct intel_crtc_state *crtc_state,
+                       int *n_entries)
+{
+       if (crtc_state->port_clock > 270000) {
                *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3);
                return icl_mg_phy_ddi_translations_hbr2_hbr3;
+       } else {
+               *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
+               return icl_mg_phy_ddi_translations_rbr_hbr;
        }
+}
 
-       *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
-       return icl_mg_phy_ddi_translations_rbr_hbr;
+static const struct icl_mg_phy_ddi_buf_trans *
+icl_get_mg_buf_trans(struct intel_encoder *encoder,
+                    const struct intel_crtc_state *crtc_state,
+                    int *n_entries)
+{
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+               return icl_get_mg_buf_trans_hdmi(encoder, crtc_state, n_entries);
+       else
+               return icl_get_mg_buf_trans_dp(encoder, crtc_state, n_entries);
 }
 
 static const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
-                       int *n_entries)
+ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
+                            const struct intel_crtc_state *crtc_state,
+                            int *n_entries)
+{
+       *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
+       return icl_combo_phy_ddi_translations_hdmi;
+}
+
+static const struct cnl_ddi_buf_trans *
+ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+                          const struct intel_crtc_state *crtc_state,
+                          int *n_entries)
 {
-       if (type != INTEL_OUTPUT_HDMI && type != INTEL_OUTPUT_EDP) {
-               *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
-               return ehl_combo_phy_ddi_translations_dp;
+       *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
+       return ehl_combo_phy_ddi_translations_dp;
+}
+
+static const struct cnl_ddi_buf_trans *
+ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+                           const struct intel_crtc_state *crtc_state,
+                           int *n_entries)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+       if (dev_priv->vbt.edp.low_vswing) {
+               if (crtc_state->port_clock > 540000) {
+                       *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
+                       return icl_combo_phy_ddi_translations_edp_hbr3;
+               } else {
+                       *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
+                       return icl_combo_phy_ddi_translations_edp_hbr2;
+               }
        }
 
-       return icl_get_combo_buf_trans(encoder, type, rate, n_entries);
+       return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
 }
 
 static const struct cnl_ddi_buf_trans *
-tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
+ehl_get_combo_buf_trans(struct intel_encoder *encoder,
+                       const struct intel_crtc_state *crtc_state,
                        int *n_entries)
 {
-       if (type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_EDP) {
-               return icl_get_combo_buf_trans(encoder, type, rate, n_entries);
-       } else if (rate > 270000) {
-               *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2);
-               return tgl_combo_phy_ddi_translations_dp_hbr2;
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+               return ehl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+       else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+               return ehl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+       else
+               return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
+                            const struct intel_crtc_state *crtc_state,
+                            int *n_entries)
+{
+       *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
+       return icl_combo_phy_ddi_translations_hdmi;
+}
+
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+                          const struct intel_crtc_state *crtc_state,
+                          int *n_entries)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+       if (crtc_state->port_clock > 270000) {
+               if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) {
+                       *n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2);
+                       return tgl_uy_combo_phy_ddi_translations_dp_hbr2;
+               } else {
+                       *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2);
+                       return tgl_combo_phy_ddi_translations_dp_hbr2;
+               }
+       } else {
+               *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
+               return tgl_combo_phy_ddi_translations_dp_hbr;
+       }
+}
+
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+                           const struct intel_crtc_state *crtc_state,
+                           int *n_entries)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+       if (crtc_state->port_clock > 540000) {
+               *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
+               return icl_combo_phy_ddi_translations_edp_hbr3;
+       } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) {
+               *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_edp_hbr2_hobl);
+               return tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
+       } else if (dev_priv->vbt.edp.low_vswing) {
+               *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
+               return icl_combo_phy_ddi_translations_edp_hbr2;
        }
 
-       *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
-       return tgl_combo_phy_ddi_translations_dp_hbr;
+       return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans(struct intel_encoder *encoder,
+                       const struct intel_crtc_state *crtc_state,
+                       int *n_entries)
+{
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+               return tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+       else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+               return tgl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+       else
+               return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
 }
 
 static const struct tgl_dkl_phy_ddi_buf_trans *
-tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int type, int rate,
-                     int *n_entries)
+tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder,
+                          const struct intel_crtc_state *crtc_state,
+                          int *n_entries)
+{
+       *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
+       return tgl_dkl_phy_hdmi_ddi_trans;
+}
+
+static const struct tgl_dkl_phy_ddi_buf_trans *
+tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder,
+                        const struct intel_crtc_state *crtc_state,
+                        int *n_entries)
 {
-       if (type == INTEL_OUTPUT_HDMI) {
-               *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
-               return tgl_dkl_phy_hdmi_ddi_trans;
-       } else if (rate > 270000) {
+       if (crtc_state->port_clock > 270000) {
                *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans_hbr2);
                return tgl_dkl_phy_dp_ddi_trans_hbr2;
+       } else {
+               *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
+               return tgl_dkl_phy_dp_ddi_trans;
        }
+}
 
-       *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
-       return tgl_dkl_phy_dp_ddi_trans;
+static const struct tgl_dkl_phy_ddi_buf_trans *
+tgl_get_dkl_buf_trans(struct intel_encoder *encoder,
+                     const struct intel_crtc_state *crtc_state,
+                     int *n_entries)
+{
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+               return tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, n_entries);
+       else
+               return tgl_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries);
 }
 
-static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
+static int intel_ddi_hdmi_level(struct intel_encoder *encoder,
+                               const struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        int n_entries, level, default_entry;
@@ -1085,19 +1275,15 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
 
        if (INTEL_GEN(dev_priv) >= 12) {
                if (intel_phy_is_combo(dev_priv, phy))
-                       tgl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI,
-                                               0, &n_entries);
+                       tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
                else
-                       tgl_get_dkl_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0,
-                                             &n_entries);
+                       tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, &n_entries);
                default_entry = n_entries - 1;
        } else if (INTEL_GEN(dev_priv) == 11) {
                if (intel_phy_is_combo(dev_priv, phy))
-                       icl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI,
-                                               0, &n_entries);
+                       icl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
                else
-                       icl_get_mg_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0,
-                                            &n_entries);
+                       icl_get_mg_buf_trans_hdmi(encoder, crtc_state, &n_entries);
                default_entry = n_entries - 1;
        } else if (IS_CANNONLAKE(dev_priv)) {
                cnl_get_buf_trans_hdmi(encoder, &n_entries);
@@ -1424,14 +1610,15 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
                       DP_TP_CTL_ENABLE);
 }
 
-static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
+static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
+                                     const struct intel_crtc_state *crtc_state)
 {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
        intel_dp->DP = dig_port->saved_port_bits |
                DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
-       intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
+       intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count);
 }
 
 static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
@@ -1738,6 +1925,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 
        ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 
+       drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING);
+
        ctl &= ~TRANS_DDI_FUNC_ENABLE;
 
        if (IS_GEN_RANGE(dev_priv, 8, 10))
@@ -1765,12 +1954,12 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 }
 
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
+                                    enum transcoder cpu_transcoder,
                                     bool enable)
 {
        struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        intel_wakeref_t wakeref;
-       enum pipe pipe = 0;
        int ret = 0;
        u32 tmp;
 
@@ -1779,19 +1968,12 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
        if (drm_WARN_ON(dev, !wakeref))
                return -ENXIO;
 
-       if (drm_WARN_ON(dev,
-                       !intel_encoder->get_hw_state(intel_encoder, &pipe))) {
-               ret = -EIO;
-               goto out;
-       }
-
-       tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe));
+       tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
        if (enable)
                tmp |= TRANS_DDI_HDCP_SIGNALLING;
        else
                tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
-       intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe), tmp);
-out:
+       intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), tmp);
        intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
        return ret;
 }
@@ -2100,13 +2282,14 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
 }
 
 static void skl_ddi_set_iboost(struct intel_encoder *encoder,
-                              int level, enum intel_output_type type)
+                              const struct intel_crtc_state *crtc_state,
+                              int level)
 {
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u8 iboost;
 
-       if (type == INTEL_OUTPUT_HDMI)
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
                iboost = intel_bios_hdmi_boost_level(encoder);
        else
                iboost = intel_bios_dp_boost_level(encoder);
@@ -2115,14 +2298,12 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
                const struct ddi_buf_trans *ddi_translations;
                int n_entries;
 
-               if (type == INTEL_OUTPUT_HDMI)
+               if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
                        ddi_translations = intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
-               else if (type == INTEL_OUTPUT_EDP)
-                       ddi_translations = intel_ddi_get_buf_trans_edp(encoder,
-                                                                      &n_entries);
+               else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+                       ddi_translations = intel_ddi_get_buf_trans_edp(encoder, &n_entries);
                else
-                       ddi_translations = intel_ddi_get_buf_trans_dp(encoder,
-                                                                     &n_entries);
+                       ddi_translations = intel_ddi_get_buf_trans_dp(encoder, &n_entries);
 
                if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
                        return;
@@ -2145,16 +2326,17 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
 }
 
 static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
-                                   int level, enum intel_output_type type)
+                                   const struct intel_crtc_state *crtc_state,
+                                   int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        const struct bxt_ddi_buf_trans *ddi_translations;
        enum port port = encoder->port;
        int n_entries;
 
-       if (type == INTEL_OUTPUT_HDMI)
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
                ddi_translations = bxt_get_buf_trans_hdmi(encoder, &n_entries);
-       else if (type == INTEL_OUTPUT_EDP)
+       else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
                ddi_translations = bxt_get_buf_trans_edp(encoder, &n_entries);
        else
                ddi_translations = bxt_get_buf_trans_dp(encoder, &n_entries);
@@ -2171,7 +2353,8 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
                                     ddi_translations[level].deemphasis);
 }
 
-static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
+static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
+                                  const struct intel_crtc_state *crtc_state)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2181,33 +2364,28 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
 
        if (INTEL_GEN(dev_priv) >= 12) {
                if (intel_phy_is_combo(dev_priv, phy))
-                       tgl_get_combo_buf_trans(encoder, encoder->type,
-                                               intel_dp->link_rate, &n_entries);
+                       tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
                else
-                       tgl_get_dkl_buf_trans(encoder, encoder->type,
-                                             intel_dp->link_rate, &n_entries);
+                       tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
        } else if (INTEL_GEN(dev_priv) == 11) {
                if (IS_ELKHARTLAKE(dev_priv))
-                       ehl_get_combo_buf_trans(encoder, encoder->type,
-                                               intel_dp->link_rate, &n_entries);
+                       ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
                else if (intel_phy_is_combo(dev_priv, phy))
-                       icl_get_combo_buf_trans(encoder, encoder->type,
-                                               intel_dp->link_rate, &n_entries);
+                       icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
                else
-                       icl_get_mg_buf_trans(encoder, encoder->type,
-                                            intel_dp->link_rate, &n_entries);
+                       icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
        } else if (IS_CANNONLAKE(dev_priv)) {
-               if (encoder->type == INTEL_OUTPUT_EDP)
+               if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
                        cnl_get_buf_trans_edp(encoder, &n_entries);
                else
                        cnl_get_buf_trans_dp(encoder, &n_entries);
        } else if (IS_GEN9_LP(dev_priv)) {
-               if (encoder->type == INTEL_OUTPUT_EDP)
+               if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
                        bxt_get_buf_trans_edp(encoder, &n_entries);
                else
                        bxt_get_buf_trans_dp(encoder, &n_entries);
        } else {
-               if (encoder->type == INTEL_OUTPUT_EDP)
+               if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
                        intel_ddi_get_buf_trans_edp(encoder, &n_entries);
                else
                        intel_ddi_get_buf_trans_dp(encoder, &n_entries);
@@ -2234,7 +2412,8 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
 }
 
 static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
-                                  int level, enum intel_output_type type)
+                                  const struct intel_crtc_state *crtc_state,
+                                  int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        const struct cnl_ddi_buf_trans *ddi_translations;
@@ -2242,9 +2421,9 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
        int n_entries, ln;
        u32 val;
 
-       if (type == INTEL_OUTPUT_HDMI)
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
                ddi_translations = cnl_get_buf_trans_hdmi(encoder, &n_entries);
-       else if (type == INTEL_OUTPUT_EDP)
+       else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
                ddi_translations = cnl_get_buf_trans_edp(encoder, &n_entries);
        else
                ddi_translations = cnl_get_buf_trans_dp(encoder, &n_entries);
@@ -2298,22 +2477,16 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
 }
 
 static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
-                                   int level, enum intel_output_type type)
+                                   const struct intel_crtc_state *crtc_state,
+                                   int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum port port = encoder->port;
        int width, rate, ln;
        u32 val;
 
-       if (type == INTEL_OUTPUT_HDMI) {
-               width = 4;
-               rate = 0; /* Rate is always < than 6GHz for HDMI */
-       } else {
-               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-               width = intel_dp->lane_count;
-               rate = intel_dp->link_rate;
-       }
+       width = crtc_state->lane_count;
+       rate = crtc_state->port_clock;
 
        /*
         * 1. If port type is eDP or DP,
@@ -2321,10 +2494,10 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
         * else clear to 0b.
         */
        val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port));
-       if (type != INTEL_OUTPUT_HDMI)
-               val |= COMMON_KEEPER_EN;
-       else
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
                val &= ~COMMON_KEEPER_EN;
+       else
+               val |= COMMON_KEEPER_EN;
        intel_de_write(dev_priv, CNL_PORT_PCS_DW1_GRP(port), val);
 
        /* 2. Program loadgen select */
@@ -2356,7 +2529,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
        intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
 
        /* 5. Program swing and de-emphasis */
-       cnl_ddi_vswing_program(encoder, level, type);
+       cnl_ddi_vswing_program(encoder, crtc_state, level);
 
        /* 6. Set training enable to trigger update */
        val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
@@ -2365,23 +2538,21 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
-                                        u32 level, int type, int rate)
+                                        const struct intel_crtc_state *crtc_state,
+                                        int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       const struct cnl_ddi_buf_trans *ddi_translations;
        enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
-       const struct cnl_ddi_buf_trans *ddi_translations = NULL;
-       u32 n_entries, val;
-       int ln;
+       int n_entries, ln;
+       u32 val;
 
        if (INTEL_GEN(dev_priv) >= 12)
-               ddi_translations = tgl_get_combo_buf_trans(encoder, type, rate,
-                                                          &n_entries);
+               ddi_translations = tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
        else if (IS_ELKHARTLAKE(dev_priv))
-               ddi_translations = ehl_get_combo_buf_trans(encoder, type, rate,
-                                                          &n_entries);
+               ddi_translations = ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
        else
-               ddi_translations = icl_get_combo_buf_trans(encoder, type, rate,
-                                                          &n_entries);
+               ddi_translations = icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
        if (!ddi_translations)
                return;
 
@@ -2392,6 +2563,15 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
                level = n_entries - 1;
        }
 
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
+               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+               val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED;
+               intel_dp->hobl_active = is_hobl_buf_trans(ddi_translations);
+               intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val,
+                            intel_dp->hobl_active ? val : 0);
+       }
+
        /* Set PORT_TX_DW5 */
        val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
        val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK |
@@ -2431,25 +2611,16 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
 }
 
 static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
-                                             u32 level,
-                                             enum intel_output_type type)
+                                             const struct intel_crtc_state *crtc_state,
+                                             int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
-       int width = 0;
-       int rate = 0;
+       int width, rate, ln;
        u32 val;
-       int ln = 0;
-
-       if (type == INTEL_OUTPUT_HDMI) {
-               width = 4;
-               /* Rate is always < than 6GHz for HDMI */
-       } else {
-               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-               width = intel_dp->lane_count;
-               rate = intel_dp->link_rate;
-       }
+       width = crtc_state->lane_count;
+       rate = crtc_state->port_clock;
 
        /*
         * 1. If port type is eDP or DP,
@@ -2457,7 +2628,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
         * else clear to 0b.
         */
        val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy));
-       if (type == INTEL_OUTPUT_HDMI)
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
                val &= ~COMMON_KEEPER_EN;
        else
                val |= COMMON_KEEPER_EN;
@@ -2492,7 +2663,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
        intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);
 
        /* 5. Program swing and de-emphasis */
-       icl_ddi_combo_vswing_program(encoder, level, type, rate);
+       icl_ddi_combo_vswing_program(encoder, crtc_state, level);
 
        /* 6. Set training enable to trigger update */
        val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
@@ -2501,23 +2672,16 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
-                                          int link_clock, u32 level,
-                                          enum intel_output_type type)
+                                          const struct intel_crtc_state *crtc_state,
+                                          int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
        const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
-       u32 n_entries, val;
-       int ln, rate = 0;
-
-       if (type != INTEL_OUTPUT_HDMI) {
-               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-               rate = intel_dp->link_rate;
-       }
+       int n_entries, ln;
+       u32 val;
 
-       ddi_translations = icl_get_mg_buf_trans(encoder, type, rate,
-                                               &n_entries);
+       ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
        /* The table does not have values for level 3 and level 9. */
        if (level >= n_entries || level == 3 || level == 9) {
                drm_dbg_kms(&dev_priv->drm,
@@ -2584,7 +2748,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
         */
        for (ln = 0; ln < 2; ln++) {
                val = intel_de_read(dev_priv, MG_CLKHUB(ln, tc_port));
-               if (link_clock < 300000)
+               if (crtc_state->port_clock < 300000)
                        val |= CFG_LOW_RATE_LKREN_EN;
                else
                        val &= ~CFG_LOW_RATE_LKREN_EN;
@@ -2595,7 +2759,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
        for (ln = 0; ln < 2; ln++) {
                val = intel_de_read(dev_priv, MG_TX1_DCC(ln, tc_port));
                val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
-               if (link_clock <= 500000) {
+               if (crtc_state->port_clock <= 500000) {
                        val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
                } else {
                        val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2605,7 +2769,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 
                val = intel_de_read(dev_priv, MG_TX2_DCC(ln, tc_port));
                val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
-               if (link_clock <= 500000) {
+               if (crtc_state->port_clock <= 500000) {
                        val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
                } else {
                        val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2631,38 +2795,30 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
-                                   int link_clock,
-                                   u32 level,
-                                   enum intel_output_type type)
+                                   const struct intel_crtc_state *crtc_state,
+                                   int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
        if (intel_phy_is_combo(dev_priv, phy))
-               icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+               icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
        else
-               icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level,
-                                              type);
+               icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
-                               u32 level, enum intel_output_type type)
+tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+                               const struct intel_crtc_state *crtc_state,
+                               int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
        const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
-       u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
-       int rate = 0;
-
-       if (type == INTEL_OUTPUT_HDMI) {
-               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-               rate = intel_dp->link_rate;
-       }
+       u32 val, dpcnt_mask, dpcnt_val;
+       int n_entries, ln;
 
-       ddi_translations = tgl_get_dkl_buf_trans(encoder, encoder->type, rate,
-                                                &n_entries);
+       ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
 
        if (level >= n_entries)
                level = n_entries - 1;
@@ -2698,20 +2854,20 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
 }
 
 static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
-                                   int link_clock,
-                                   u32 level,
-                                   enum intel_output_type type)
+                                   const struct intel_crtc_state *crtc_state,
+                                   int level)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
        if (intel_phy_is_combo(dev_priv, phy))
-               icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+               icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
        else
-               tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type);
+               tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
-static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
+static int translate_signal_level(struct intel_dp *intel_dp,
+                                 u8 signal_levels)
 {
        struct drm_i915_private *i915 = dp_to_i915(intel_dp);
        int i;
@@ -2728,55 +2884,58 @@ static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
        return 0;
 }
 
-static u32 intel_ddi_dp_level(struct intel_dp *intel_dp)
+static int intel_ddi_dp_level(struct intel_dp *intel_dp)
 {
        u8 train_set = intel_dp->train_set[0];
-       int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-                                        DP_TRAIN_PRE_EMPHASIS_MASK);
+       u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+                                       DP_TRAIN_PRE_EMPHASIS_MASK);
 
        return translate_signal_level(intel_dp, signal_levels);
 }
 
 static void
-tgl_set_signal_levels(struct intel_dp *intel_dp)
+tgl_set_signal_levels(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        int level = intel_ddi_dp_level(intel_dp);
 
-       tgl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
-                               level, encoder->type);
+       tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-icl_set_signal_levels(struct intel_dp *intel_dp)
+icl_set_signal_levels(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        int level = intel_ddi_dp_level(intel_dp);
 
-       icl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
-                               level, encoder->type);
+       icl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-cnl_set_signal_levels(struct intel_dp *intel_dp)
+cnl_set_signal_levels(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        int level = intel_ddi_dp_level(intel_dp);
 
-       cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+       cnl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-bxt_set_signal_levels(struct intel_dp *intel_dp)
+bxt_set_signal_levels(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        int level = intel_ddi_dp_level(intel_dp);
 
-       bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+       bxt_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-hsw_set_signal_levels(struct intel_dp *intel_dp)
+hsw_set_signal_levels(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2793,7 +2952,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp)
        intel_dp->DP |= signal_levels;
 
        if (IS_GEN9_BC(dev_priv))
-               skl_ddi_set_iboost(encoder, level, encoder->type);
+               skl_ddi_set_iboost(encoder, crtc_state, level);
 
        intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
        intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
@@ -2802,7 +2961,9 @@ hsw_set_signal_levels(struct intel_dp *intel_dp)
 static u32 icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv,
                                     enum phy phy)
 {
-       if (intel_phy_is_combo(dev_priv, phy)) {
+       if (IS_ROCKETLAKE(dev_priv)) {
+               return RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+       } else if (intel_phy_is_combo(dev_priv, phy)) {
                return ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
        } else if (intel_phy_is_tc(dev_priv, phy)) {
                enum tc_port tc_port = intel_port_to_tc(dev_priv,
@@ -2829,6 +2990,16 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
                    (val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0);
 
        if (intel_phy_is_combo(dev_priv, phy)) {
+               u32 mask, sel;
+
+               if (IS_ROCKETLAKE(dev_priv)) {
+                       mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+                       sel = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+               } else {
+                       mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+                       sel = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+               }
+
                /*
                 * Even though this register references DDIs, note that we
                 * want to pass the PHY rather than the port (DDI).  For
@@ -2839,8 +3010,8 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
                 *   Clock Select chooses the PLL for both DDIA and DDID and
                 *   drives port A in all cases."
                 */
-               val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
-               val |= ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+               val &= ~mask;
+               val |= sel;
                intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
                intel_de_posting_read(dev_priv, ICL_DPCLKA_CFGCR0);
        }
@@ -3124,6 +3295,37 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,
        }
 }
 
+static enum transcoder
+tgl_dp_tp_transcoder(const struct intel_crtc_state *crtc_state)
+{
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
+               return crtc_state->mst_master_transcoder;
+       else
+               return crtc_state->cpu_transcoder;
+}
+
+i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
+                        const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+       if (INTEL_GEN(dev_priv) >= 12)
+               return TGL_DP_TP_CTL(tgl_dp_tp_transcoder(crtc_state));
+       else
+               return DP_TP_CTL(encoder->port);
+}
+
+i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
+                           const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+       if (INTEL_GEN(dev_priv) >= 12)
+               return TGL_DP_TP_STATUS(tgl_dp_tp_transcoder(crtc_state));
+       else
+               return DP_TP_STATUS(encoder->port);
+}
+
 static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
                                        const struct intel_crtc_state *crtc_state)
 {
@@ -3148,11 +3350,12 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder,
                return;
 
        intel_dp = enc_to_intel_dp(encoder);
-       val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+       val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
        val |= DP_TP_CTL_FEC_ENABLE;
-       intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+       intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
 
-       if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+       if (intel_de_wait_for_set(dev_priv,
+                                 dp_tp_status_reg(encoder, crtc_state),
                                  DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
                drm_err(&dev_priv->drm,
                        "Timed out waiting for FEC Enable Status\n");
@@ -3169,10 +3372,10 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
                return;
 
        intel_dp = enc_to_intel_dp(encoder);
-       val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+       val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
        val &= ~DP_TP_CTL_FEC_ENABLE;
-       intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
-       intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+       intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
+       intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 }
 
 static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
@@ -3186,13 +3389,10 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
        int level = intel_ddi_dp_level(intel_dp);
-       enum transcoder transcoder = crtc_state->cpu_transcoder;
-
-       intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
-                                crtc_state->lane_count, is_mst);
 
-       intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
-       intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
+       intel_dp_set_link_params(intel_dp,
+                                crtc_state->port_clock,
+                                crtc_state->lane_count);
 
        /*
         * 1. Enable Power Wells
@@ -3261,8 +3461,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
         */
 
        /* 7.e Configure voltage swing and related IO settings */
-       tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, level,
-                               encoder->type);
+       tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 
        /*
         * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
@@ -3285,7 +3484,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
         * We only configure what the register value will be here.  Actual
         * enabling happens during link training farther down.
         */
-       intel_ddi_init_dp_buf_reg(encoder);
+       intel_ddi_init_dp_buf_reg(encoder, crtc_state);
 
        if (!is_mst)
                intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
@@ -3305,11 +3504,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
         *     Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
         *     (timeout after 800 us)
         */
-       intel_dp_start_link_train(intel_dp);
+       intel_dp_start_link_train(intel_dp, crtc_state);
 
        /* 7.k Set DP_TP_CTL link training to Normal */
        if (!is_trans_port_sync_mode(crtc_state))
-               intel_dp_stop_link_train(intel_dp);
+               intel_dp_stop_link_train(intel_dp, crtc_state);
 
        /* 7.l Configure and enable FEC if needed */
        intel_ddi_enable_fec(encoder, crtc_state);
@@ -3335,8 +3534,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
        else
                drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A);
 
-       intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
-                                crtc_state->lane_count, is_mst);
+       intel_dp_set_link_params(intel_dp,
+                                crtc_state->port_clock,
+                                crtc_state->lane_count);
 
        intel_edp_panel_on(intel_dp);
 
@@ -3350,12 +3550,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
        icl_program_mg_dp_mode(dig_port, crtc_state);
 
        if (INTEL_GEN(dev_priv) >= 11)
-               icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-                                       level, encoder->type);
+               icl_ddi_vswing_sequence(encoder, crtc_state, level);
        else if (IS_CANNONLAKE(dev_priv))
-               cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+               cnl_ddi_vswing_sequence(encoder, crtc_state, level);
        else if (IS_GEN9_LP(dev_priv))
-               bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+               bxt_ddi_vswing_sequence(encoder, crtc_state, level);
        else
                intel_prepare_dp_ddi_buffers(encoder, crtc_state);
 
@@ -3368,16 +3567,17 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
                                               lane_reversal);
        }
 
-       intel_ddi_init_dp_buf_reg(encoder);
+       intel_ddi_init_dp_buf_reg(encoder, crtc_state);
        if (!is_mst)
                intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+       intel_dp_configure_protocol_converter(intel_dp);
        intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
                                              true);
        intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
-       intel_dp_start_link_train(intel_dp);
+       intel_dp_start_link_train(intel_dp, crtc_state);
        if ((port != PORT_A || INTEL_GEN(dev_priv) >= 9) &&
            !is_trans_port_sync_mode(crtc_state))
-               intel_dp_stop_link_train(intel_dp);
+               intel_dp_stop_link_train(intel_dp, crtc_state);
 
        intel_ddi_enable_fec(encoder, crtc_state);
 
@@ -3417,7 +3617,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       int level = intel_ddi_hdmi_level(encoder);
+       int level = intel_ddi_hdmi_level(encoder, crtc_state);
 
        intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
        intel_ddi_clk_select(encoder, crtc_state);
@@ -3427,20 +3627,18 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
        icl_program_mg_dp_mode(dig_port, crtc_state);
 
        if (INTEL_GEN(dev_priv) >= 12)
-               tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-                                       level, INTEL_OUTPUT_HDMI);
+               tgl_ddi_vswing_sequence(encoder, crtc_state, level);
        else if (INTEL_GEN(dev_priv) == 11)
-               icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-                                       level, INTEL_OUTPUT_HDMI);
+               icl_ddi_vswing_sequence(encoder, crtc_state, level);
        else if (IS_CANNONLAKE(dev_priv))
-               cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+               cnl_ddi_vswing_sequence(encoder, crtc_state, level);
        else if (IS_GEN9_LP(dev_priv))
-               bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+               bxt_ddi_vswing_sequence(encoder, crtc_state, level);
        else
                intel_prepare_hdmi_ddi_buffers(encoder, level);
 
        if (IS_GEN9_BC(dev_priv))
-               skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI);
+               skl_ddi_set_iboost(encoder, crtc_state, level);
 
        intel_ddi_enable_pipe_clock(encoder, crtc_state);
 
@@ -3482,19 +3680,17 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state,
                intel_ddi_pre_enable_hdmi(state, encoder, crtc_state,
                                          conn_state);
        } else {
-               struct intel_lspcon *lspcon =
-                               enc_to_intel_lspcon(encoder);
+               struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
                intel_ddi_pre_enable_dp(state, encoder, crtc_state,
                                        conn_state);
-               if (lspcon->active) {
-                       struct intel_digital_port *dig_port =
-                                       enc_to_dig_port(encoder);
 
+               /* FIXME precompute everything properly */
+               /* FIXME how do we turn infoframes off again? */
+               if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
                        dig_port->set_infoframes(encoder,
                                                 crtc_state->has_infoframe,
                                                 crtc_state, conn_state);
-               }
        }
 }
 
@@ -3514,12 +3710,10 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder,
        }
 
        if (intel_crtc_has_dp_encoder(crtc_state)) {
-               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-               val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+               val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
                val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
                val |= DP_TP_CTL_LINK_TRAIN_PAT1;
-               intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+               intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
        }
 
        /* Disable FEC in DP Sink */
@@ -3732,12 +3926,14 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state,
                    crtc_state->cpu_transcoder)
                        continue;
 
-               intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder));
+               intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder),
+                                        slave_crtc_state);
        }
 
        usleep_range(200, 400);
 
-       intel_dp_stop_link_train(enc_to_intel_dp(encoder));
+       intel_dp_stop_link_train(enc_to_intel_dp(encoder),
+                                crtc_state);
 }
 
 static void intel_enable_ddi_dp(struct intel_atomic_state *state,
@@ -3750,7 +3946,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
        enum port port = encoder->port;
 
        if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
-               intel_dp_stop_link_train(intel_dp);
+               intel_dp_stop_link_train(intel_dp, crtc_state);
 
        intel_edp_backlight_on(crtc_state, conn_state);
        intel_psr_enable(intel_dp, crtc_state, conn_state);
@@ -3938,18 +4134,19 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
 
        intel_psr_update(intel_dp, crtc_state, conn_state);
        intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
-       intel_edp_drrs_enable(intel_dp, crtc_state);
+       intel_edp_drrs_update(intel_dp, crtc_state);
 
        intel_panel_update_backlight(state, encoder, crtc_state, conn_state);
 }
 
-static void intel_ddi_update_pipe(struct intel_atomic_state *state,
-                                 struct intel_encoder *encoder,
-                                 const struct intel_crtc_state *crtc_state,
-                                 const struct drm_connector_state *conn_state)
+void intel_ddi_update_pipe(struct intel_atomic_state *state,
+                          struct intel_encoder *encoder,
+                          const struct intel_crtc_state *crtc_state,
+                          const struct drm_connector_state *conn_state)
 {
 
-       if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+       if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
+           !intel_encoder_is_mst(encoder))
                intel_ddi_update_pipe_dp(state, encoder, crtc_state,
                                         conn_state);
 
@@ -4010,15 +4207,16 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
                                                crtc_state->lane_lat_optim_mask);
 }
 
-static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
+static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
+                                          const struct intel_crtc_state *crtc_state)
 {
-       struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-       enum port port = dig_port->base.port;
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       enum port port = encoder->port;
        u32 dp_tp_ctl, ddi_buf_ctl;
        bool wait = false;
 
-       dp_tp_ctl = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+       dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
        if (dp_tp_ctl & DP_TP_CTL_ENABLE) {
                ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port));
@@ -4030,24 +4228,23 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 
                dp_tp_ctl &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
                dp_tp_ctl |= DP_TP_CTL_LINK_TRAIN_PAT1;
-               intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
-               intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+               intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
+               intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
                if (wait)
                        intel_wait_ddi_buf_idle(dev_priv, port);
        }
 
-       dp_tp_ctl = DP_TP_CTL_ENABLE |
-                   DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
-       if (intel_dp->link_mst)
+       dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1;
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
                dp_tp_ctl |= DP_TP_CTL_MODE_MST;
-       else {
+       else {
                dp_tp_ctl |= DP_TP_CTL_MODE_SST;
                if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
                        dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
        }
-       intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
-       intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+       intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
+       intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
        intel_dp->DP |= DDI_BUF_CTL_ENABLE;
        intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
@@ -4057,19 +4254,15 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 }
 
 static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
+                                    const struct intel_crtc_state *crtc_state,
                                     u8 dp_train_pat)
 {
-       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        u8 train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd);
-       enum port port = dp_to_dig_port(intel_dp)->base.port;
        u32 temp;
 
-       temp = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
-
-       if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
-               temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
-       else
-               temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE;
+       temp = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
        temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
        switch (dp_train_pat & train_pat_mask) {
@@ -4090,23 +4283,21 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
                break;
        }
 
-       intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, temp);
-
-       intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
-       intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
+       intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), temp);
 }
 
-static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp)
+static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
+                                         const struct intel_crtc_state *crtc_state)
 {
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum port port = encoder->port;
        u32 val;
 
-       val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+       val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
        val &= ~DP_TP_CTL_LINK_TRAIN_MASK;
        val |= DP_TP_CTL_LINK_TRAIN_IDLE;
-       intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+       intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
 
        /*
         * Until TGL on PORT_A we can have only eDP in SST mode. There the only
@@ -4118,7 +4309,8 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp)
        if (port == PORT_A && INTEL_GEN(dev_priv) < 12)
                return;
 
-       if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+       if (intel_de_wait_for_set(dev_priv,
+                                 dp_tp_status_reg(encoder, crtc_state),
                                  DP_TP_STATUS_IDLE_DONE, 1))
                drm_err(&dev_priv->drm,
                        "Timed out waiting for DP idle patterns\n");
@@ -4216,7 +4408,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
        enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
-       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        u32 temp, flags = 0;
 
        /* XXX: DSI transcoder paranoia */
@@ -4286,12 +4477,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
                intel_dp_get_m_n(intel_crtc, pipe_config);
 
                if (INTEL_GEN(dev_priv) >= 11) {
-                       i915_reg_t dp_tp_ctl;
-
-                       if (IS_GEN(dev_priv, 11))
-                               dp_tp_ctl = DP_TP_CTL(encoder->port);
-                       else
-                               dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
+                       i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config);
 
                        pipe_config->fec_enable =
                                intel_de_read(dev_priv, dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
@@ -4324,16 +4510,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
                break;
        }
 
-       if (INTEL_GEN(dev_priv) >= 12) {
-               enum transcoder transcoder =
-                       intel_dp_mst_is_slave_trans(pipe_config) ?
-                       pipe_config->mst_master_transcoder :
-                       pipe_config->cpu_transcoder;
-
-               intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
-               intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
-       }
-
        pipe_config->has_audio =
                intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
 
@@ -4598,11 +4774,6 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
        dig_port->dp.voltage_max = intel_ddi_dp_voltage_max;
        dig_port->dp.preemph_max = intel_ddi_dp_preemph_max;
 
-       if (INTEL_GEN(dev_priv) < 12) {
-               dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
-               dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
-       }
-
        if (!intel_dp_init_connector(dig_port, connector)) {
                kfree(connector);
                return NULL;
@@ -4878,13 +5049,83 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port)
        return max_lanes;
 }
 
+static bool hti_uses_phy(struct drm_i915_private *i915, enum phy phy)
+{
+       return i915->hti_state & HDPORT_ENABLED &&
+               (i915->hti_state & HDPORT_PHY_USED_DP(phy) ||
+                i915->hti_state & HDPORT_PHY_USED_HDMI(phy));
+}
+
+static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv,
+                               enum port port)
+{
+       if (port >= PORT_D)
+               return HPD_PORT_TC1 + port - PORT_D;
+       else
+               return HPD_PORT_A + port - PORT_A;
+}
+
+static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv,
+                               enum port port)
+{
+       if (HAS_PCH_TGP(dev_priv))
+               return tgl_hpd_pin(dev_priv, port);
+
+       if (port >= PORT_D)
+               return HPD_PORT_C + port - PORT_D;
+       else
+               return HPD_PORT_A + port - PORT_A;
+}
+
+static enum hpd_pin icl_hpd_pin(struct drm_i915_private *dev_priv,
+                               enum port port)
+{
+       if (port >= PORT_C)
+               return HPD_PORT_TC1 + port - PORT_C;
+       else
+               return HPD_PORT_A + port - PORT_A;
+}
+
+static enum hpd_pin ehl_hpd_pin(struct drm_i915_private *dev_priv,
+                               enum port port)
+{
+       if (port == PORT_D)
+               return HPD_PORT_A;
+
+       if (HAS_PCH_MCC(dev_priv))
+               return icl_hpd_pin(dev_priv, port);
+
+       return HPD_PORT_A + port - PORT_A;
+}
+
+static enum hpd_pin cnl_hpd_pin(struct drm_i915_private *dev_priv,
+                               enum port port)
+{
+       if (port == PORT_F)
+               return HPD_PORT_E;
+
+       return HPD_PORT_A + port - PORT_A;
+}
+
 void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 {
        struct intel_digital_port *dig_port;
        struct intel_encoder *encoder;
-       bool init_hdmi, init_dp, init_lspcon = false;
+       bool init_hdmi, init_dp;
        enum phy phy = intel_port_to_phy(dev_priv, port);
 
+       /*
+        * On platforms with HTI (aka HDPORT), if it's enabled at boot it may
+        * have taken over some of the PHYs and made them unavailable to the
+        * driver.  In that case we should skip initializing the corresponding
+        * outputs.
+        */
+       if (hti_uses_phy(dev_priv, phy)) {
+               drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n",
+                           port_name(port), phy_name(phy));
+               return;
+       }
+
        init_hdmi = intel_bios_port_supports_dvi(dev_priv, port) ||
                intel_bios_port_supports_hdmi(dev_priv, port);
        init_dp = intel_bios_port_supports_dp(dev_priv, port);
@@ -4896,7 +5137,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
                 * is initialized before lspcon.
                 */
                init_dp = true;
-               init_lspcon = true;
                init_hdmi = false;
                drm_dbg_kms(&dev_priv->drm, "VBT says port %c has lspcon\n",
                            port_name(port));
@@ -4918,6 +5158,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
        drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
                         DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
 
+       mutex_init(&dig_port->hdcp_mutex);
+       dig_port->num_hdcp_streams = 0;
+
        encoder->hotplug = intel_ddi_hotplug;
        encoder->compute_output_type = intel_ddi_compute_output_type;
        encoder->compute_config = intel_ddi_compute_config;
@@ -4939,6 +5182,19 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
        encoder->cloneable = 0;
        encoder->pipe_mask = ~0;
 
+       if (IS_ROCKETLAKE(dev_priv))
+               encoder->hpd_pin = rkl_hpd_pin(dev_priv, port);
+       else if (INTEL_GEN(dev_priv) >= 12)
+               encoder->hpd_pin = tgl_hpd_pin(dev_priv, port);
+       else if (IS_ELKHARTLAKE(dev_priv))
+               encoder->hpd_pin = ehl_hpd_pin(dev_priv, port);
+       else if (IS_GEN(dev_priv, 11))
+               encoder->hpd_pin = icl_hpd_pin(dev_priv, port);
+       else if (IS_GEN(dev_priv, 10))
+               encoder->hpd_pin = cnl_hpd_pin(dev_priv, port);
+       else
+               encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
+
        if (INTEL_GEN(dev_priv) >= 11)
                dig_port->saved_port_bits =
                        intel_de_read(dev_priv, DDI_BUF_CTL(port))
@@ -4981,22 +5237,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
                        goto err;
        }
 
-       if (init_lspcon) {
-               if (lspcon_init(dig_port))
-                       /* TODO: handle hdmi info frame part */
-                       drm_dbg_kms(&dev_priv->drm,
-                                   "LSPCON init success on port %c\n",
-                                   port_name(port));
-               else
-                       /*
-                        * LSPCON init faied, but DP init was success, so
-                        * lets try to drive as DP++ port.
-                        */
-                       drm_err(&dev_priv->drm,
-                               "LSPCON init failed on port %c\n",
-                               port_name(port));
-       }
-
        if (INTEL_GEN(dev_priv) >= 11) {
                if (intel_phy_is_tc(dev_priv, phy))
                        dig_port->connected = intel_tc_port_connected;