]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/gpu/drm/i915/intel_dp.c
drm/i915: Pass dev_priv to intel_wait_for_vblank()
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / i915 / intel_dp.c
index 14a3cf0b72133a2734cb98059fbdd524578dc392..9c1921a2e2398f1dd93ee1decb7eae138eb6c1bb 100644 (file)
@@ -213,6 +213,81 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
        return max_dotclk;
 }
 
+static int
+intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
+{
+       if (intel_dp->num_sink_rates) {
+               *sink_rates = intel_dp->sink_rates;
+               return intel_dp->num_sink_rates;
+       }
+
+       *sink_rates = default_rates;
+
+       return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
+}
+
+static int
+intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
+{
+       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);
+       int size;
+
+       if (IS_BROXTON(dev_priv)) {
+               *source_rates = bxt_rates;
+               size = ARRAY_SIZE(bxt_rates);
+       } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+               *source_rates = skl_rates;
+               size = ARRAY_SIZE(skl_rates);
+       } else {
+               *source_rates = default_rates;
+               size = ARRAY_SIZE(default_rates);
+       }
+
+       /* This depends on the fact that 5.4 is last value in the array */
+       if (!intel_dp_source_supports_hbr2(intel_dp))
+               size--;
+
+       return size;
+}
+
+static int intersect_rates(const int *source_rates, int source_len,
+                          const int *sink_rates, int sink_len,
+                          int *common_rates)
+{
+       int i = 0, j = 0, k = 0;
+
+       while (i < source_len && j < sink_len) {
+               if (source_rates[i] == sink_rates[j]) {
+                       if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
+                               return k;
+                       common_rates[k] = source_rates[i];
+                       ++k;
+                       ++i;
+                       ++j;
+               } else if (source_rates[i] < sink_rates[j]) {
+                       ++i;
+               } else {
+                       ++j;
+               }
+       }
+       return k;
+}
+
+static int intel_dp_common_rates(struct intel_dp *intel_dp,
+                                int *common_rates)
+{
+       const int *source_rates, *sink_rates;
+       int source_len, sink_len;
+
+       sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
+       source_len = intel_dp_source_rates(intel_dp, &source_rates);
+
+       return intersect_rates(source_rates, source_len,
+                              sink_rates, sink_len,
+                              common_rates);
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
@@ -344,7 +419,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
        DP |= DP_PORT_WIDTH(1);
        DP |= DP_LINK_TRAIN_PAT_1;
 
-       if (IS_CHERRYVIEW(dev))
+       if (IS_CHERRYVIEW(dev_priv))
                DP |= DP_PIPE_SELECT_CHV(pipe);
        else if (pipe == PIPE_B)
                DP |= DP_PIPEB_SELECT;
@@ -356,10 +431,10 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
         * So enable temporarily it if it's not already enabled.
         */
        if (!pll_enabled) {
-               release_cl_override = IS_CHERRYVIEW(dev) &&
+               release_cl_override = IS_CHERRYVIEW(dev_priv) &&
                        !chv_phy_powergate_ch(dev_priv, phy, ch, true);
 
-               if (vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ?
+               if (vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev_priv) ?
                                     &chv_dpll[0].dpll : &vlv_dpll[0].dpll)) {
                        DRM_ERROR("Failed to force on pll for pipe %c!\n",
                                  pipe_name(pipe));
@@ -570,8 +645,8 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv)
        struct drm_device *dev = &dev_priv->drm;
        struct intel_encoder *encoder;
 
-       if (WARN_ON(!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) &&
-                   !IS_BROXTON(dev)))
+       if (WARN_ON(!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
+                   !IS_BROXTON(dev_priv)))
                return;
 
        /*
@@ -591,7 +666,7 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv)
                        continue;
 
                intel_dp = enc_to_intel_dp(&encoder->base);
-               if (IS_BROXTON(dev))
+               if (IS_BROXTON(dev_priv))
                        intel_dp->pps_reset = true;
                else
                        intel_dp->pps_pipe = INVALID_PIPE;
@@ -664,7 +739,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code,
 
        pps_lock(intel_dp);
 
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
                i915_reg_t pp_ctrl_reg, pp_div_reg;
                u32 pp_div;
@@ -692,7 +767,7 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp)
 
        lockdep_assert_held(&dev_priv->pps_mutex);
 
-       if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+       if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
            intel_dp->pps_pipe == INVALID_PIPE)
                return false;
 
@@ -706,7 +781,7 @@ static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
 
        lockdep_assert_held(&dev_priv->pps_mutex);
 
-       if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+       if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
            intel_dp->pps_pipe == INVALID_PIPE)
                return false;
 
@@ -821,15 +896,16 @@ static uint32_t g4x_get_aux_send_ctl(struct intel_dp *intel_dp,
                                     uint32_t aux_clock_divider)
 {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = intel_dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv =
+                       to_i915(intel_dig_port->base.base.dev);
        uint32_t precharge, timeout;
 
-       if (IS_GEN6(dev))
+       if (IS_GEN6(dev_priv))
                precharge = 3;
        else
                precharge = 5;
 
-       if (IS_BROADWELL(dev) && intel_dig_port->port == PORT_A)
+       if (IS_BROADWELL(dev_priv) && intel_dig_port->port == PORT_A)
                timeout = DP_AUX_CH_CTL_TIME_OUT_600us;
        else
                timeout = DP_AUX_CH_CTL_TIME_OUT_400us;
@@ -1108,8 +1184,46 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
        return ret;
 }
 
+static enum port intel_aux_port(struct drm_i915_private *dev_priv,
+                               enum port port)
+{
+       const struct ddi_vbt_port_info *info =
+               &dev_priv->vbt.ddi_port_info[port];
+       enum port aux_port;
+
+       if (!info->alternate_aux_channel) {
+               DRM_DEBUG_KMS("using AUX %c for port %c (platform default)\n",
+                             port_name(port), port_name(port));
+               return port;
+       }
+
+       switch (info->alternate_aux_channel) {
+       case DP_AUX_A:
+               aux_port = PORT_A;
+               break;
+       case DP_AUX_B:
+               aux_port = PORT_B;
+               break;
+       case DP_AUX_C:
+               aux_port = PORT_C;
+               break;
+       case DP_AUX_D:
+               aux_port = PORT_D;
+               break;
+       default:
+               MISSING_CASE(info->alternate_aux_channel);
+               aux_port = PORT_A;
+               break;
+       }
+
+       DRM_DEBUG_KMS("using AUX %c for port %c (VBT)\n",
+                     port_name(aux_port), port_name(port));
+
+       return aux_port;
+}
+
 static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
-                                      enum port port)
+                                 enum port port)
 {
        switch (port) {
        case PORT_B:
@@ -1123,7 +1237,7 @@ static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
 }
 
 static i915_reg_t g4x_aux_data_reg(struct drm_i915_private *dev_priv,
-                                       enum port port, int index)
+                                  enum port port, int index)
 {
        switch (port) {
        case PORT_B:
@@ -1137,7 +1251,7 @@ static i915_reg_t g4x_aux_data_reg(struct drm_i915_private *dev_priv,
 }
 
 static i915_reg_t ilk_aux_ctl_reg(struct drm_i915_private *dev_priv,
-                                      enum port port)
+                                 enum port port)
 {
        switch (port) {
        case PORT_A:
@@ -1153,7 +1267,7 @@ static i915_reg_t ilk_aux_ctl_reg(struct drm_i915_private *dev_priv,
 }
 
 static i915_reg_t ilk_aux_data_reg(struct drm_i915_private *dev_priv,
-                                       enum port port, int index)
+                                  enum port port, int index)
 {
        switch (port) {
        case PORT_A:
@@ -1168,36 +1282,9 @@ static i915_reg_t ilk_aux_data_reg(struct drm_i915_private *dev_priv,
        }
 }
 
-/*
- * On SKL we don't have Aux for port E so we rely
- * on VBT to set a proper alternate aux channel.
- */
-static enum port skl_porte_aux_port(struct drm_i915_private *dev_priv)
-{
-       const struct ddi_vbt_port_info *info =
-               &dev_priv->vbt.ddi_port_info[PORT_E];
-
-       switch (info->alternate_aux_channel) {
-       case DP_AUX_A:
-               return PORT_A;
-       case DP_AUX_B:
-               return PORT_B;
-       case DP_AUX_C:
-               return PORT_C;
-       case DP_AUX_D:
-               return PORT_D;
-       default:
-               MISSING_CASE(info->alternate_aux_channel);
-               return PORT_A;
-       }
-}
-
 static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
-                                      enum port port)
+                                 enum port port)
 {
-       if (port == PORT_E)
-               port = skl_porte_aux_port(dev_priv);
-
        switch (port) {
        case PORT_A:
        case PORT_B:
@@ -1211,11 +1298,8 @@ static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
 }
 
 static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv,
-                                       enum port port, int index)
+                                  enum port port, int index)
 {
-       if (port == PORT_E)
-               port = skl_porte_aux_port(dev_priv);
-
        switch (port) {
        case PORT_A:
        case PORT_B:
@@ -1229,7 +1313,7 @@ static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv,
 }
 
 static i915_reg_t intel_aux_ctl_reg(struct drm_i915_private *dev_priv,
-                                        enum port port)
+                                   enum port port)
 {
        if (INTEL_INFO(dev_priv)->gen >= 9)
                return skl_aux_ctl_reg(dev_priv, port);
@@ -1240,7 +1324,7 @@ static i915_reg_t intel_aux_ctl_reg(struct drm_i915_private *dev_priv,
 }
 
 static i915_reg_t intel_aux_data_reg(struct drm_i915_private *dev_priv,
-                                         enum port port, int index)
+                                    enum port port, int index)
 {
        if (INTEL_INFO(dev_priv)->gen >= 9)
                return skl_aux_data_reg(dev_priv, port, index);
@@ -1253,7 +1337,8 @@ static i915_reg_t intel_aux_data_reg(struct drm_i915_private *dev_priv,
 static void intel_aux_reg_init(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
-       enum port port = dp_to_dig_port(intel_dp)->port;
+       enum port port = intel_aux_port(dev_priv,
+                                       dp_to_dig_port(intel_dp)->port);
        int i;
 
        intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port);
@@ -1281,78 +1366,37 @@ intel_dp_aux_init(struct intel_dp *intel_dp)
        intel_dp->aux.transfer = intel_dp_aux_transfer;
 }
 
-static int
-intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
-{
-       if (intel_dp->num_sink_rates) {
-               *sink_rates = intel_dp->sink_rates;
-               return intel_dp->num_sink_rates;
-       }
-
-       *sink_rates = default_rates;
-
-       return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
-}
-
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
 {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = dig_port->base.base.dev;
-
-       /* WaDisableHBR2:skl */
-       if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
-               return false;
+       struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
 
-       if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||
-           (INTEL_INFO(dev)->gen >= 9))
+       if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) ||
+           IS_BROADWELL(dev_priv) || (INTEL_GEN(dev_priv) >= 9))
                return true;
        else
                return false;
 }
 
-static int
-intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
-{
-       struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = dig_port->base.base.dev;
-       int size;
-
-       if (IS_BROXTON(dev)) {
-               *source_rates = bxt_rates;
-               size = ARRAY_SIZE(bxt_rates);
-       } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
-               *source_rates = skl_rates;
-               size = ARRAY_SIZE(skl_rates);
-       } else {
-               *source_rates = default_rates;
-               size = ARRAY_SIZE(default_rates);
-       }
-
-       /* This depends on the fact that 5.4 is last value in the array */
-       if (!intel_dp_source_supports_hbr2(intel_dp))
-               size--;
-
-       return size;
-}
-
 static void
 intel_dp_set_clock(struct intel_encoder *encoder,
                   struct intel_crtc_state *pipe_config)
 {
        struct drm_device *dev = encoder->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
        const struct dp_link_dpll *divisor = NULL;
        int i, count = 0;
 
-       if (IS_G4X(dev)) {
+       if (IS_G4X(dev_priv)) {
                divisor = gen4_dpll;
                count = ARRAY_SIZE(gen4_dpll);
-       } else if (HAS_PCH_SPLIT(dev)) {
+       } else if (HAS_PCH_SPLIT(dev_priv)) {
                divisor = pch_dpll;
                count = ARRAY_SIZE(pch_dpll);
-       } else if (IS_CHERRYVIEW(dev)) {
+       } else if (IS_CHERRYVIEW(dev_priv)) {
                divisor = chv_dpll;
                count = ARRAY_SIZE(chv_dpll);
-       } else if (IS_VALLEYVIEW(dev)) {
+       } else if (IS_VALLEYVIEW(dev_priv)) {
                divisor = vlv_dpll;
                count = ARRAY_SIZE(vlv_dpll);
        }
@@ -1368,43 +1412,6 @@ intel_dp_set_clock(struct intel_encoder *encoder,
        }
 }
 
-static int intersect_rates(const int *source_rates, int source_len,
-                          const int *sink_rates, int sink_len,
-                          int *common_rates)
-{
-       int i = 0, j = 0, k = 0;
-
-       while (i < source_len && j < sink_len) {
-               if (source_rates[i] == sink_rates[j]) {
-                       if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
-                               return k;
-                       common_rates[k] = source_rates[i];
-                       ++k;
-                       ++i;
-                       ++j;
-               } else if (source_rates[i] < sink_rates[j]) {
-                       ++i;
-               } else {
-                       ++j;
-               }
-       }
-       return k;
-}
-
-static int intel_dp_common_rates(struct intel_dp *intel_dp,
-                                int *common_rates)
-{
-       const int *source_rates, *sink_rates;
-       int source_len, sink_len;
-
-       sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
-       source_len = intel_dp_source_rates(intel_dp, &source_rates);
-
-       return intersect_rates(source_rates, source_len,
-                              sink_rates, sink_len,
-                              common_rates);
-}
-
 static void snprintf_int_array(char *str, size_t len,
                               const int *array, int nelem)
 {
@@ -1444,42 +1451,35 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
        DRM_DEBUG_KMS("common rates: %s\n", str);
 }
 
-static void intel_dp_print_hw_revision(struct intel_dp *intel_dp)
+bool
+__intel_dp_read_desc(struct intel_dp *intel_dp, struct intel_dp_desc *desc)
 {
-       uint8_t rev;
-       int len;
-
-       if ((drm_debug & DRM_UT_KMS) == 0)
-               return;
+       u32 base = drm_dp_is_branch(intel_dp->dpcd) ? DP_BRANCH_OUI :
+                                                     DP_SINK_OUI;
 
-       if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
-             DP_DWN_STRM_PORT_PRESENT))
-               return;
-
-       len = drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_HW_REV, &rev, 1);
-       if (len < 0)
-               return;
-
-       DRM_DEBUG_KMS("sink hw revision: %d.%d\n", (rev & 0xf0) >> 4, rev & 0xf);
+       return drm_dp_dpcd_read(&intel_dp->aux, base, desc, sizeof(*desc)) ==
+              sizeof(*desc);
 }
 
-static void intel_dp_print_sw_revision(struct intel_dp *intel_dp)
+bool intel_dp_read_desc(struct intel_dp *intel_dp)
 {
-       uint8_t rev[2];
-       int len;
+       struct intel_dp_desc *desc = &intel_dp->desc;
+       bool oui_sup = intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] &
+                      DP_OUI_SUPPORT;
+       int dev_id_len;
 
-       if ((drm_debug & DRM_UT_KMS) == 0)
-               return;
-
-       if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
-             DP_DWN_STRM_PORT_PRESENT))
-               return;
+       if (!__intel_dp_read_desc(intel_dp, desc))
+               return false;
 
-       len = drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_SW_REV, &rev, 2);
-       if (len < 0)
-               return;
+       dev_id_len = strnlen(desc->device_id, sizeof(desc->device_id));
+       DRM_DEBUG_KMS("DP %s: OUI %*phD%s dev-ID %*pE HW-rev %d.%d SW-rev %d.%d\n",
+                     drm_dp_is_branch(intel_dp->dpcd) ? "branch" : "sink",
+                     (int)sizeof(desc->oui), desc->oui, oui_sup ? "" : "(NS)",
+                     dev_id_len, desc->device_id,
+                     desc->hw_rev >> 4, desc->hw_rev & 0xf,
+                     desc->sw_major_rev, desc->sw_minor_rev);
 
-       DRM_DEBUG_KMS("sink sw revision: %d.%d\n", rev[0], rev[1]);
+       return true;
 }
 
 static int rate_to_index(int find, const int *rates)
@@ -1569,7 +1569,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 
        max_clock = common_len - 1;
 
-       if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
+       if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
                pipe_config->has_pch_encoder = true;
 
        pipe_config->has_drrs = false;
@@ -1586,7 +1586,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
                                return ret;
                }
 
-               if (HAS_GMCH_DISPLAY(dev))
+               if (HAS_GMCH_DISPLAY(dev_priv))
                        intel_gmch_panel_fitting(intel_crtc, pipe_config,
                                                 intel_connector->panel.fitting_mode);
                else
@@ -1711,7 +1711,7 @@ found:
                to_intel_atomic_state(pipe_config->base.state)->cdclk_pll_vco = vco;
        }
 
-       if (!HAS_DDI(dev))
+       if (!HAS_DDI(dev_priv))
                intel_dp_set_clock(encoder, pipe_config);
 
        return true;
@@ -1769,7 +1769,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
 
        /* Split out the IBX/CPU vs CPT settings */
 
-       if (IS_GEN7(dev) && port == PORT_A) {
+       if (IS_GEN7(dev_priv) && port == PORT_A) {
                if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
                        intel_dp->DP |= DP_SYNC_HS_HIGH;
                if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
@@ -1780,7 +1780,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
 
                intel_dp->DP |= crtc->pipe << 29;
-       } else if (HAS_PCH_CPT(dev) && port != PORT_A) {
+       } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
                u32 trans_dp;
 
                intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
@@ -1792,8 +1792,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
                        trans_dp &= ~TRANS_DP_ENH_FRAMING;
                I915_WRITE(TRANS_DP_CTL(crtc->pipe), trans_dp);
        } else {
-               if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) &&
-                   !IS_CHERRYVIEW(dev) && pipe_config->limited_color_range)
+               if (!HAS_PCH_SPLIT(dev_priv) && !IS_VALLEYVIEW(dev_priv) &&
+                   !IS_CHERRYVIEW(dev_priv) &&
+                   pipe_config->limited_color_range)
                        intel_dp->DP |= DP_COLOR_RANGE_16_235;
 
                if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
@@ -1805,7 +1806,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
                if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
 
-               if (IS_CHERRYVIEW(dev))
+               if (IS_CHERRYVIEW(dev_priv))
                        intel_dp->DP |= DP_PIPE_SELECT_CHV(crtc->pipe);
                else if (crtc->pipe == PIPE_B)
                        intel_dp->DP |= DP_PIPEB_SELECT;
@@ -2114,7 +2115,7 @@ static void edp_panel_on(struct intel_dp *intel_dp)
 
        pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
        pp = ironlake_get_pp_control(intel_dp);
-       if (IS_GEN5(dev)) {
+       if (IS_GEN5(dev_priv)) {
                /* ILK workaround: disable reset around power sequence */
                pp &= ~PANEL_POWER_RESET;
                I915_WRITE(pp_ctrl_reg, pp);
@@ -2122,7 +2123,7 @@ static void edp_panel_on(struct intel_dp *intel_dp)
        }
 
        pp |= PANEL_POWER_ON;
-       if (!IS_GEN5(dev))
+       if (!IS_GEN5(dev_priv))
                pp |= PANEL_POWER_RESET;
 
        I915_WRITE(pp_ctrl_reg, pp);
@@ -2131,7 +2132,7 @@ static void edp_panel_on(struct intel_dp *intel_dp)
        wait_panel_on(intel_dp);
        intel_dp->last_power_on = jiffies;
 
-       if (IS_GEN5(dev)) {
+       if (IS_GEN5(dev_priv)) {
                pp |= PANEL_POWER_RESET; /* restore panel reset bit */
                I915_WRITE(pp_ctrl_reg, pp);
                POSTING_READ(pp_ctrl_reg);
@@ -2363,7 +2364,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp,
         * 2. Program DP PLL enable
         */
        if (IS_GEN5(dev_priv))
-               intel_wait_for_vblank_if_active(&dev_priv->drm, !crtc->pipe);
+               intel_wait_for_vblank_if_active(dev_priv, !crtc->pipe);
 
        intel_dp->DP |= DP_PLL_ENABLE;
 
@@ -2444,9 +2445,9 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
        if (!(tmp & DP_PORT_EN))
                goto out;
 
-       if (IS_GEN7(dev) && port == PORT_A) {
+       if (IS_GEN7(dev_priv) && port == PORT_A) {
                *pipe = PORT_TO_PIPE_CPT(tmp);
-       } else if (HAS_PCH_CPT(dev) && port != PORT_A) {
+       } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
                enum pipe p;
 
                for_each_pipe(dev_priv, p) {
@@ -2461,7 +2462,7 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
 
                DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n",
                              i915_mmio_reg_offset(intel_dp->output_reg));
-       } else if (IS_CHERRYVIEW(dev)) {
+       } else if (IS_CHERRYVIEW(dev_priv)) {
                *pipe = DP_PORT_TO_PIPE_CHV(tmp);
        } else {
                *pipe = PORT_TO_PIPE(tmp);
@@ -2489,7 +2490,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 
        pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A;
 
-       if (HAS_PCH_CPT(dev) && port != PORT_A) {
+       if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
                u32 trans_dp = I915_READ(TRANS_DP_CTL(crtc->pipe));
 
                if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)
@@ -2515,8 +2516,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 
        pipe_config->base.adjusted_mode.flags |= flags;
 
-       if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) &&
-           !IS_CHERRYVIEW(dev) && tmp & DP_COLOR_RANGE_16_235)
+       if (!HAS_PCH_SPLIT(dev_priv) && !IS_VALLEYVIEW(dev_priv) &&
+           !IS_CHERRYVIEW(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
                pipe_config->limited_color_range = true;
 
        pipe_config->lane_count =
@@ -2636,7 +2637,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
                DRM_DEBUG_KMS("Using DP training pattern TPS%d\n",
                              dp_train_pat & DP_TRAINING_PATTERN_MASK);
 
-       if (HAS_DDI(dev)) {
+       if (HAS_DDI(dev_priv)) {
                uint32_t temp = I915_READ(DP_TP_CTL(port));
 
                if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
@@ -2662,8 +2663,8 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
                }
                I915_WRITE(DP_TP_CTL(port), temp);
 
-       } else if ((IS_GEN7(dev) && port == PORT_A) ||
-                  (HAS_PCH_CPT(dev) && port != PORT_A)) {
+       } else if ((IS_GEN7(dev_priv) && port == PORT_A) ||
+                  (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
                *DP &= ~DP_LINK_TRAIN_MASK_CPT;
 
                switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
@@ -2683,7 +2684,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
                }
 
        } else {
-               if (IS_CHERRYVIEW(dev))
+               if (IS_CHERRYVIEW(dev_priv))
                        *DP &= ~DP_LINK_TRAIN_MASK_CHV;
                else
                        *DP &= ~DP_LINK_TRAIN_MASK;
@@ -2699,7 +2700,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
                        *DP |= DP_LINK_TRAIN_PAT_2;
                        break;
                case DP_TRAINING_PATTERN_3:
-                       if (IS_CHERRYVIEW(dev)) {
+                       if (IS_CHERRYVIEW(dev_priv)) {
                                *DP |= DP_LINK_TRAIN_PAT_3_CHV;
                        } else {
                                DRM_DEBUG_KMS("TPS3 not supported, using TPS2 instead\n");
@@ -2749,7 +2750,7 @@ static void intel_enable_dp(struct intel_encoder *encoder,
 
        pps_lock(intel_dp);
 
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                vlv_init_panel_power_sequencer(intel_dp);
 
        intel_dp_enable_port(intel_dp, pipe_config);
@@ -2760,10 +2761,10 @@ static void intel_enable_dp(struct intel_encoder *encoder,
 
        pps_unlock(intel_dp);
 
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                unsigned int lane_mask = 0x0;
 
-               if (IS_CHERRYVIEW(dev))
+               if (IS_CHERRYVIEW(dev_priv))
                        lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count);
 
                vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
@@ -2983,17 +2984,17 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
        struct drm_i915_private *dev_priv = to_i915(dev);
        enum port port = dp_to_dig_port(intel_dp)->port;
 
-       if (IS_BROXTON(dev))
+       if (IS_BROXTON(dev_priv))
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
        else if (INTEL_INFO(dev)->gen >= 9) {
                if (dev_priv->vbt.edp.low_vswing && port == PORT_A)
                        return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-       } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
+       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-       else if (IS_GEN7(dev) && port == PORT_A)
+       else if (IS_GEN7(dev_priv) && port == PORT_A)
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-       else if (HAS_PCH_CPT(dev) && port != PORT_A)
+       else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
        else
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
@@ -3002,10 +3003,10 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
-       struct drm_device *dev = intel_dp_to_dev(intel_dp);
+       struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
        enum port port = dp_to_dig_port(intel_dp)->port;
 
-       if (INTEL_INFO(dev)->gen >= 9) {
+       if (INTEL_GEN(dev_priv) >= 9) {
                switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
                case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
                        return DP_TRAIN_PRE_EMPH_LEVEL_3;
@@ -3018,7 +3019,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
                default:
                        return DP_TRAIN_PRE_EMPH_LEVEL_0;
                }
-       } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+       } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
                switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
                case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
                        return DP_TRAIN_PRE_EMPH_LEVEL_3;
@@ -3030,7 +3031,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
                default:
                        return DP_TRAIN_PRE_EMPH_LEVEL_0;
                }
-       } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
                case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
                        return DP_TRAIN_PRE_EMPH_LEVEL_3;
@@ -3042,7 +3043,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
                default:
                        return DP_TRAIN_PRE_EMPH_LEVEL_0;
                }
-       } else if (IS_GEN7(dev) && port == PORT_A) {
+       } else if (IS_GEN7(dev_priv) && port == PORT_A) {
                switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
                case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
                        return DP_TRAIN_PRE_EMPH_LEVEL_2;
@@ -3343,21 +3344,21 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
        uint32_t signal_levels, mask = 0;
        uint8_t train_set = intel_dp->train_set[0];
 
-       if (HAS_DDI(dev)) {
+       if (HAS_DDI(dev_priv)) {
                signal_levels = ddi_signal_levels(intel_dp);
 
-               if (IS_BROXTON(dev))
+               if (IS_BROXTON(dev_priv))
                        signal_levels = 0;
                else
                        mask = DDI_BUF_EMP_MASK;
-       } else if (IS_CHERRYVIEW(dev)) {
+       } else if (IS_CHERRYVIEW(dev_priv)) {
                signal_levels = chv_signal_levels(intel_dp);
-       } else if (IS_VALLEYVIEW(dev)) {
+       } else if (IS_VALLEYVIEW(dev_priv)) {
                signal_levels = vlv_signal_levels(intel_dp);
-       } else if (IS_GEN7(dev) && port == PORT_A) {
+       } else if (IS_GEN7(dev_priv) && port == PORT_A) {
                signal_levels = gen7_edp_signal_levels(train_set);
                mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
-       } else if (IS_GEN6(dev) && port == PORT_A) {
+       } else if (IS_GEN6(dev_priv) && port == PORT_A) {
                signal_levels = gen6_edp_signal_levels(train_set);
                mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
        } else {
@@ -3402,7 +3403,7 @@ void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
        enum port port = intel_dig_port->port;
        uint32_t val;
 
-       if (!HAS_DDI(dev))
+       if (!HAS_DDI(dev_priv))
                return;
 
        val = I915_READ(DP_TP_CTL(port));
@@ -3437,7 +3438,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
        struct drm_i915_private *dev_priv = to_i915(dev);
        uint32_t DP = intel_dp->DP;
 
-       if (WARN_ON(HAS_DDI(dev)))
+       if (WARN_ON(HAS_DDI(dev_priv)))
                return;
 
        if (WARN_ON((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0))
@@ -3445,12 +3446,12 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        DRM_DEBUG_KMS("\n");
 
-       if ((IS_GEN7(dev) && port == PORT_A) ||
-           (HAS_PCH_CPT(dev) && port != PORT_A)) {
+       if ((IS_GEN7(dev_priv) && port == PORT_A) ||
+           (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
                DP &= ~DP_LINK_TRAIN_MASK_CPT;
                DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
        } else {
-               if (IS_CHERRYVIEW(dev))
+               if (IS_CHERRYVIEW(dev_priv))
                        DP &= ~DP_LINK_TRAIN_MASK_CHV;
                else
                        DP &= ~DP_LINK_TRAIN_MASK;
@@ -3468,7 +3469,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
         * to transcoder A after disabling it to allow the
         * matching HDMI port to be enabled on transcoder A.
         */
-       if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B && port != PORT_A) {
+       if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B && port != PORT_A) {
                /*
                 * We get CPU/PCH FIFO underruns on the other pipe when
                 * doing the workaround. Sweep them under the rug.
@@ -3486,7 +3487,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
                I915_WRITE(intel_dp->output_reg, DP);
                POSTING_READ(intel_dp->output_reg);
 
-               intel_wait_for_vblank_if_active(&dev_priv->drm, PIPE_A);
+               intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
                intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
                intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
        }
@@ -3496,7 +3497,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
        intel_dp->DP = DP;
 }
 
-static bool
+bool
 intel_dp_read_dpcd(struct intel_dp *intel_dp)
 {
        if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
@@ -3520,6 +3521,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
        if (!intel_dp_read_dpcd(intel_dp))
                return false;
 
+       intel_dp_read_desc(intel_dp);
+
        if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
                dev_priv->no_aux_handshake = intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
                        DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
@@ -3551,8 +3554,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
        /* Read the eDP Display control capabilities registers */
        if ((intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_DPCD_DISPLAY_CONTROL_CAPABLE) &&
            drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV,
-                            intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd) ==
-                            sizeof(intel_dp->edp_dpcd)))
+                            intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) ==
+                            sizeof(intel_dp->edp_dpcd))
                DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(intel_dp->edp_dpcd),
                              intel_dp->edp_dpcd);
 
@@ -3607,8 +3610,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        if (!is_edp(intel_dp) && !intel_dp->sink_count)
                return false;
 
-       if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
-             DP_DWN_STRM_PORT_PRESENT))
+       if (!drm_dp_is_branch(intel_dp->dpcd))
                return true; /* native DP sink */
 
        if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
@@ -3622,23 +3624,6 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        return true;
 }
 
-static void
-intel_dp_probe_oui(struct intel_dp *intel_dp)
-{
-       u8 buf[3];
-
-       if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
-               return;
-
-       if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_OUI, buf, 3) == 3)
-               DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
-                             buf[0], buf[1], buf[2]);
-
-       if (drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_OUI, buf, 3) == 3)
-               DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
-                             buf[0], buf[1], buf[2]);
-}
-
 static bool
 intel_dp_can_mst(struct intel_dp *intel_dp)
 {
@@ -3682,7 +3667,7 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
 static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
 {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
        u8 buf;
        int ret = 0;
@@ -3703,7 +3688,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
        }
 
        do {
-               intel_wait_for_vblank(dev, intel_crtc->pipe);
+               intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
 
                if (drm_dp_dpcd_readb(&intel_dp->aux,
                                      DP_TEST_SINK_MISC, &buf) < 0) {
@@ -3726,7 +3711,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
 static int intel_dp_sink_crc_start(struct intel_dp *intel_dp)
 {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
        u8 buf;
        int ret;
@@ -3754,14 +3739,14 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp)
                return -EIO;
        }
 
-       intel_wait_for_vblank(dev, intel_crtc->pipe);
+       intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
        return 0;
 }
 
 int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
 {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
        u8 buf;
        int count, ret;
@@ -3772,7 +3757,7 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
                return ret;
 
        do {
-               intel_wait_for_vblank(dev, intel_crtc->pipe);
+               intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
 
                if (drm_dp_dpcd_readb(&intel_dp->aux,
                                      DP_TEST_SINK_MISC, &buf) < 0) {
@@ -3988,6 +3973,31 @@ go_again:
        return -EINVAL;
 }
 
+static void
+intel_dp_retrain_link(struct intel_dp *intel_dp)
+{
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+       /* Suppress underruns caused by re-training */
+       intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
+       if (crtc->config->has_pch_encoder)
+               intel_set_pch_fifo_underrun_reporting(dev_priv,
+                                                     intel_crtc_pch_transcoder(crtc), false);
+
+       intel_dp_start_link_train(intel_dp);
+       intel_dp_stop_link_train(intel_dp);
+
+       /* Keep underrun reporting disabled until things are stable */
+       intel_wait_for_vblank(dev_priv, crtc->pipe);
+
+       intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
+       if (crtc->config->has_pch_encoder)
+               intel_set_pch_fifo_underrun_reporting(dev_priv,
+                                                     intel_crtc_pch_transcoder(crtc), true);
+}
+
 static void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
@@ -4008,13 +4018,18 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
        if (!to_intel_crtc(intel_encoder->base.crtc)->active)
                return;
 
+       /* FIXME: we need to synchronize this sort of stuff with hardware
+        * readout */
+       if (WARN_ON_ONCE(!intel_dp->lane_count))
+               return;
+
        /* if link training is requested we should perform it always */
        if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) ||
            (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) {
                DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
                              intel_encoder->base.name);
-               intel_dp_start_link_train(intel_dp);
-               intel_dp_stop_link_train(intel_dp);
+
+               intel_dp_retrain_link(intel_dp);
        }
 }
 
@@ -4096,7 +4111,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
                return connector_status_connected;
 
        /* if there's no downstream port, we're done */
-       if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
+       if (!drm_dp_is_branch(dpcd))
                return connector_status_connected;
 
        /* If we're HPD-aware, SINK_COUNT changes dynamically */
@@ -4387,10 +4402,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
 
        intel_dp_print_rates(intel_dp);
 
-       intel_dp_probe_oui(intel_dp);
-
-       intel_dp_print_hw_revision(intel_dp);
-       intel_dp_print_sw_revision(intel_dp);
+       intel_dp_read_desc(intel_dp);
 
        intel_dp_configure_mst(intel_dp);
 
@@ -4454,21 +4466,11 @@ static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector, bool force)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
-       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-       struct intel_encoder *intel_encoder = &intel_dig_port->base;
        enum drm_connector_status status = connector->status;
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
                      connector->base.id, connector->name);
 
-       if (intel_dp->is_mst) {
-               /* MST devices are disconnected from a monitor POV */
-               intel_dp_unset_edid(intel_dp);
-               if (intel_encoder->type != INTEL_OUTPUT_EDP)
-                       intel_encoder->type = INTEL_OUTPUT_DP;
-               return connector_status_disconnected;
-       }
-
        /* If full detect is not performed yet, do a full detect */
        if (!intel_dp->detect_done)
                status = intel_dp_long_pulse(intel_dp->attached_connector);
@@ -4756,11 +4758,16 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
 void intel_dp_encoder_reset(struct drm_encoder *encoder)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->dev);
-       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+       struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+       struct intel_lspcon *lspcon = &intel_dig_port->lspcon;
+       struct intel_dp *intel_dp = &intel_dig_port->dp;
 
        if (!HAS_DDI(dev_priv))
                intel_dp->DP = I915_READ(intel_dp->output_reg);
 
+       if (IS_GEN9(dev_priv) && lspcon->active)
+               lspcon_resume(lspcon);
+
        if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
                return;
 
@@ -5074,7 +5081,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
                 (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT);
        /* Compute the divisor for the pp clock, simply match the Bspec
         * formula. */
-       if (IS_BROXTON(dev)) {
+       if (IS_BROXTON(dev_priv)) {
                pp_div = I915_READ(regs.pp_ctrl);
                pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK;
                pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000)
@@ -5087,9 +5094,9 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 
        /* Haswell doesn't have any port selection bits for the panel
         * power sequencer any more. */
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                port_sel = PANEL_PORT_SELECT_VLV(port);
-       } else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
+       } else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) {
                if (port == PORT_A)
                        port_sel = PANEL_PORT_SELECT_DPA;
                else
@@ -5100,7 +5107,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 
        I915_WRITE(regs.pp_on, pp_on);
        I915_WRITE(regs.pp_off, pp_off);
-       if (IS_BROXTON(dev))
+       if (IS_BROXTON(dev_priv))
                I915_WRITE(regs.pp_ctrl, pp_div);
        else
                I915_WRITE(regs.pp_div, pp_div);
@@ -5108,7 +5115,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
        DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n",
                      I915_READ(regs.pp_on),
                      I915_READ(regs.pp_off),
-                     IS_BROXTON(dev) ?
+                     IS_BROXTON(dev_priv) ?
                      (I915_READ(regs.pp_ctrl) & BXT_POWER_CYCLE_DELAY_MASK) :
                      I915_READ(regs.pp_div));
 }
@@ -5116,7 +5123,9 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 static void intel_dp_pps_init(struct drm_device *dev,
                              struct intel_dp *intel_dp)
 {
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       struct drm_i915_private *dev_priv = to_i915(dev);
+
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                vlv_initial_power_sequencer_setup(intel_dp);
        } else {
                intel_dp_init_panel_power_sequencer(dev, intel_dp);
@@ -5586,7 +5595,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
        }
        mutex_unlock(&dev->mode_config.mutex);
 
-       if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                intel_dp->edp_notifier.notifier_call = edp_notify_handler;
                register_reboot_notifier(&intel_dp->edp_notifier);
 
@@ -5595,7 +5604,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
                 * If the current pipe isn't valid, try the PPS pipe, and if that
                 * fails just assume pipe A.
                 */
-               if (IS_CHERRYVIEW(dev))
+               if (IS_CHERRYVIEW(dev_priv))
                        pipe = DP_PORT_TO_PIPE_CHV(intel_dp->DP);
                else
                        pipe = PORT_TO_PIPE(intel_dp->DP);
@@ -5651,9 +5660,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
        /* intel_dp vfuncs */
        if (INTEL_INFO(dev)->gen >= 9)
                intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider;
-       else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+       else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
                intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider;
-       else if (HAS_PCH_SPLIT(dev))
+       else if (HAS_PCH_SPLIT(dev_priv))
                intel_dp->get_aux_clock_divider = ilk_get_aux_clock_divider;
        else
                intel_dp->get_aux_clock_divider = g4x_get_aux_clock_divider;
@@ -5663,7 +5672,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
        else
                intel_dp->get_aux_send_ctl = g4x_get_aux_send_ctl;
 
-       if (HAS_DDI(dev))
+       if (HAS_DDI(dev_priv))
                intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;
 
        /* Preserve the current hw state. */
@@ -5684,7 +5693,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
                intel_encoder->type = INTEL_OUTPUT_EDP;
 
        /* eDP only on port B and/or C on vlv/chv */
-       if (WARN_ON((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
+       if (WARN_ON((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
                    is_edp(intel_dp) && port != PORT_B && port != PORT_C))
                return false;
 
@@ -5705,7 +5714,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
        intel_connector_attach_encoder(intel_connector, intel_encoder);
 
-       if (HAS_DDI(dev))
+       if (HAS_DDI(dev_priv))
                intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
        else
                intel_connector->get_hw_state = intel_connector_get_hw_state;
@@ -5717,7 +5726,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
                break;
        case PORT_B:
                intel_encoder->hpd_pin = HPD_PORT_B;
-               if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
+               if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
                        intel_encoder->hpd_pin = HPD_PORT_A;
                break;
        case PORT_C:
@@ -5751,7 +5760,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
         * 0xd.  Failure to do so will result in spurious interrupts being
         * generated on the port when a cable is not attached.
         */
-       if (IS_G4X(dev) && !IS_GM45(dev)) {
+       if (IS_G4X(dev_priv) && !IS_GM45(dev_priv)) {
                u32 temp = I915_READ(PEG_BAND_GAP_DATA);
                I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
        }
@@ -5794,13 +5803,13 @@ bool intel_dp_init(struct drm_device *dev,
        intel_encoder->get_hw_state = intel_dp_get_hw_state;
        intel_encoder->get_config = intel_dp_get_config;
        intel_encoder->suspend = intel_dp_encoder_suspend;
-       if (IS_CHERRYVIEW(dev)) {
+       if (IS_CHERRYVIEW(dev_priv)) {
                intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
                intel_encoder->pre_enable = chv_pre_enable_dp;
                intel_encoder->enable = vlv_enable_dp;
                intel_encoder->post_disable = chv_post_disable_dp;
                intel_encoder->post_pll_disable = chv_dp_post_pll_disable;
-       } else if (IS_VALLEYVIEW(dev)) {
+       } else if (IS_VALLEYVIEW(dev_priv)) {
                intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
                intel_encoder->pre_enable = vlv_pre_enable_dp;
                intel_encoder->enable = vlv_enable_dp;
@@ -5817,7 +5826,7 @@ bool intel_dp_init(struct drm_device *dev,
        intel_dig_port->max_lanes = 4;
 
        intel_encoder->type = INTEL_OUTPUT_DP;
-       if (IS_CHERRYVIEW(dev)) {
+       if (IS_CHERRYVIEW(dev_priv)) {
                if (port == PORT_D)
                        intel_encoder->crtc_mask = 1 << 2;
                else
@@ -5826,6 +5835,7 @@ bool intel_dp_init(struct drm_device *dev,
                intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
        }
        intel_encoder->cloneable = 0;
+       intel_encoder->port = port;
 
        intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
        dev_priv->hotplug.irq_port[port] = intel_dig_port;