Merge drm/drm-next into drm-intel-next-queued
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_dp.c
index 04231ca..8a673d0 100644 (file)
@@ -4481,62 +4481,6 @@ intel_dp_link_down(struct intel_encoder *encoder,
        }
 }
 
-static void
-intel_dp_extended_receiver_capabilities(struct intel_dp *intel_dp)
-{
-       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-       u8 dpcd_ext[6];
-
-       /*
-        * Prior to DP1.3 the bit represented by
-        * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
-        * if it is set DP_DPCD_REV at 0000h could be at a value less than
-        * the true capability of the panel. The only way to check is to
-        * then compare 0000h and 2200h.
-        */
-       if (!(intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
-             DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
-               return;
-
-       if (drm_dp_dpcd_read(&intel_dp->aux, DP_DP13_DPCD_REV,
-                            &dpcd_ext, sizeof(dpcd_ext)) != sizeof(dpcd_ext)) {
-               drm_err(&i915->drm,
-                       "DPCD failed read at extended capabilities\n");
-               return;
-       }
-
-       if (intel_dp->dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
-               drm_dbg_kms(&i915->drm,
-                           "DPCD extended DPCD rev less than base DPCD rev\n");
-               return;
-       }
-
-       if (!memcmp(intel_dp->dpcd, dpcd_ext, sizeof(dpcd_ext)))
-               return;
-
-       drm_dbg_kms(&i915->drm, "Base DPCD: %*ph\n",
-                   (int)sizeof(intel_dp->dpcd), intel_dp->dpcd);
-
-       memcpy(intel_dp->dpcd, dpcd_ext, sizeof(dpcd_ext));
-}
-
-bool
-intel_dp_read_dpcd(struct intel_dp *intel_dp)
-{
-       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-
-       if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
-                            sizeof(intel_dp->dpcd)) < 0)
-               return false; /* aux transfer failed */
-
-       intel_dp_extended_receiver_capabilities(intel_dp);
-
-       drm_dbg_kms(&i915->drm, "DPCD: %*ph\n", (int)sizeof(intel_dp->dpcd),
-                   intel_dp->dpcd);
-
-       return intel_dp->dpcd[DP_DPCD_REV] != 0;
-}
-
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
 {
        u8 dprx = 0;
@@ -4595,7 +4539,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
        /* this function is meant to be called only once */
        drm_WARN_ON(&dev_priv->drm, intel_dp->dpcd[DP_DPCD_REV] != 0);
 
-       if (!intel_dp_read_dpcd(intel_dp))
+       if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0)
                return false;
 
        drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
@@ -4666,11 +4610,23 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
        return true;
 }
 
+static bool
+intel_dp_has_sink_count(struct intel_dp *intel_dp)
+{
+       if (!intel_dp->attached_connector)
+               return false;
+
+       return drm_dp_read_sink_count_cap(&intel_dp->attached_connector->base,
+                                         intel_dp->dpcd,
+                                         &intel_dp->desc);
+}
 
 static bool
 intel_dp_get_dpcd(struct intel_dp *intel_dp)
 {
-       if (!intel_dp_read_dpcd(intel_dp))
+       int ret;
+
+       if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd))
                return false;
 
        /*
@@ -4685,18 +4641,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
                intel_dp_set_common_rates(intel_dp);
        }
 
-       /*
-        * Some eDP panels do not set a valid value for sink count, that is why
-        * it don't care about read it here and in intel_edp_init_dpcd().
-        */
-       if (!intel_dp_is_edp(intel_dp) &&
-           !drm_dp_has_quirk(&intel_dp->desc, 0,
-                             DP_DPCD_QUIRK_NO_SINK_COUNT)) {
-               u8 count;
-               ssize_t r;
-
-               r = drm_dp_dpcd_readb(&intel_dp->aux, DP_SINK_COUNT, &count);
-               if (r < 1)
+       if (intel_dp_has_sink_count(intel_dp)) {
+               ret = drm_dp_read_sink_count(&intel_dp->aux);
+               if (ret < 0)
                        return false;
 
                /*
@@ -4704,7 +4651,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
                 * a member variable in intel_dp will track any changes
                 * between short pulse interrupts.
                 */
-               intel_dp->sink_count = DP_GET_SINK_COUNT(count);
+               intel_dp->sink_count = ret;
 
                /*
                 * SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that
@@ -4717,32 +4664,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
                        return false;
        }
 
-       if (!drm_dp_is_branch(intel_dp->dpcd))
-               return true; /* native DP sink */
-
-       if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
-               return true; /* no per-port downstream info */
-
-       if (drm_dp_dpcd_read(&intel_dp->aux, DP_DOWNSTREAM_PORT_0,
-                            intel_dp->downstream_ports,
-                            DP_MAX_DOWNSTREAM_PORTS) < 0)
-               return false; /* downstream port status fetch failed */
-
-       return true;
-}
-
-static bool
-intel_dp_sink_can_mst(struct intel_dp *intel_dp)
-{
-       u8 mstm_cap;
-
-       if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
-               return false;
-
-       if (drm_dp_dpcd_readb(&intel_dp->aux, DP_MSTM_CAP, &mstm_cap) != 1)
-               return false;
-
-       return mstm_cap & DP_MST_CAP;
+       return drm_dp_read_downstream_info(&intel_dp->aux, intel_dp->dpcd,
+                                          intel_dp->downstream_ports) == 0;
 }
 
 static bool
@@ -4752,7 +4675,7 @@ intel_dp_can_mst(struct intel_dp *intel_dp)
 
        return i915->params.enable_dp_mst &&
                intel_dp->can_mst &&
-               intel_dp_sink_can_mst(intel_dp);
+               drm_dp_read_mst_cap(&intel_dp->aux, intel_dp->dpcd);
 }
 
 static void
@@ -4761,7 +4684,7 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
        struct drm_i915_private *i915 = dp_to_i915(intel_dp);
        struct intel_encoder *encoder =
                &dp_to_dig_port(intel_dp)->base;
-       bool sink_can_mst = intel_dp_sink_can_mst(intel_dp);
+       bool sink_can_mst = drm_dp_read_mst_cap(&intel_dp->aux, intel_dp->dpcd);
 
        drm_dbg_kms(&i915->drm,
                    "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n",
@@ -5995,9 +5918,8 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
                return connector_status_connected;
 
        /* If we're HPD-aware, SINK_COUNT changes dynamically */
-       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+       if (intel_dp_has_sink_count(intel_dp) &&
            intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) {
-
                return intel_dp->sink_count ?
                connector_status_connected : connector_status_disconnected;
        }
@@ -6275,6 +6197,11 @@ out:
         */
        intel_display_power_flush_work(dev_priv);
 
+       if (!intel_dp_is_edp(intel_dp))
+               drm_dp_set_subconnector_property(connector,
+                                                status,
+                                                intel_dp->dpcd,
+                                                intel_dp->downstream_ports);
        return status;
 }
 
@@ -6722,6 +6649,9 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
        enum port port = dp_to_dig_port(intel_dp)->base.port;
 
+       if (!intel_dp_is_edp(intel_dp))
+               drm_connector_attach_dp_subconnector_property(connector);
+
        if (!IS_G4X(dev_priv) && port != PORT_A)
                intel_attach_force_audio_property(connector);