As explained in the previous patch, the MST link BW reported by branch
devices during topology probing/path resources enumeration depends on
the link parameters programmed to DPCD to be up-to-date. After a sink is
plugged this is not ensured, as those DPCD values start out zeroed. The
target link parameters (for a subsequent modeset) are the maximum that
is supported, so make sure these maximum values are programmed before the
topology probing.

Signed-off-by: Imre Deak <imre.d...@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c     |  3 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 31 +++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp_mst.h |  1 +
 3 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0771e4c6357ba..41f5d82ca75d8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4262,6 +4262,9 @@ intel_dp_mst_configure(struct intel_dp *intel_dp)
 
        intel_dp->is_mst = intel_dp->mst_detect != DRM_DP_SST;
 
+       if (intel_dp->is_mst)
+               intel_dp_mst_prepare_probe(intel_dp);
+
        drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
 
        /* Avoid stale info on the next detect cycle. */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 19c8b6878b030..faee7af0a8a48 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -43,6 +43,7 @@
 #include "intel_dp_hdcp.h"
 #include "intel_dp_mst.h"
 #include "intel_dp_tunnel.h"
+#include "intel_dp_link_training.h"
 #include "intel_dpio_phy.h"
 #include "intel_hdcp.h"
 #include "intel_hotplug.h"
@@ -2031,3 +2032,33 @@ bool intel_dp_mst_crtc_needs_modeset(struct 
intel_atomic_state *state,
 
        return false;
 }
+
+/**
+ * intel_dp_mst_prepare_probe - Prepare an MST link for topology probing
+ * @intel_dp: DP port object
+ *
+ * Prepare an MST link for topology probing, programming the target
+ * link parameters to DPCD. This step is a requirement of the enumaration
+ * of path resources during probing.
+ */
+void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp)
+{
+       int link_rate = intel_dp_max_link_rate(intel_dp);
+       int lane_count = intel_dp_max_lane_count(intel_dp);
+       u8 rate_select;
+       u8 link_bw;
+
+       if (intel_dp->link_trained)
+               return;
+
+       if (intel_mst_probed_link_params_valid(intel_dp, link_rate, lane_count))
+               return;
+
+       intel_dp_compute_rate(intel_dp, link_rate, &link_bw, &rate_select);
+
+       intel_dp_link_training_set_mode(intel_dp, link_rate, false);
+       intel_dp_link_training_set_bw(intel_dp, link_bw, rate_select, 
lane_count,
+                                     
drm_dp_enhanced_frame_cap(intel_dp->dpcd));
+
+       intel_mst_set_probed_link_params(intel_dp, link_rate, lane_count);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h 
b/drivers/gpu/drm/i915/display/intel_dp_mst.h
index 8ca1d599091c6..fba76454fa67f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
@@ -27,5 +27,6 @@ int intel_dp_mst_atomic_check_link(struct intel_atomic_state 
*state,
                                   struct intel_link_bw_limits *limits);
 bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state,
                                     struct intel_crtc *crtc);
+void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp);
 
 #endif /* __INTEL_DP_MST_H__ */
-- 
2.44.2

Reply via email to