[PATCH 21/21] drm/i915/dp_mst: Calculate Timeslots for each compressed bpp

Ankit Nautiyal ankit.k.nautiyal at intel.com
Thu Aug 10 07:19:59 UTC 2023


Use dp_dsc_compute_config to calculate timeslots for different lane
count, link rate and compressed bpp.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c     |  76 +++++++-----
 drivers/gpu/drm/i915/display/intel_dp.h     |   7 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 128 ++++++--------------
 drivers/gpu/drm/i915/display/intel_dp_mst.h |   6 +
 4 files changed, 94 insertions(+), 123 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 9e904bb4ac5c..a14a12bbd9dc 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1715,10 +1715,10 @@ static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp,
 	return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format);
 }
 
-static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
-					    u32 lane_count, u32 mode_clock,
-					    enum intel_output_format output_format,
-					    int timeslots)
+bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+				     u32 lane_count, u32 mode_clock,
+				     enum intel_output_format output_format,
+				     int timeslots)
 {
 	u32 available_bw, required_bw;
 
@@ -1730,6 +1730,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
 
 static int dsc_compute_link_config(struct intel_dp *intel_dp,
 				   struct intel_crtc_state *pipe_config,
+				   struct drm_connector_state *conn_state,
 				   struct link_config_limits *limits,
 				   u16 compressed_bpp,
 				   int timeslots)
@@ -1738,6 +1739,7 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
 	int link_rate, lane_count;
 	int i;
 
+
 	for (i = 0; i < intel_dp->num_common_rates; i++) {
 		link_rate = intel_dp_common_rate(intel_dp, i);
 		if (link_rate < limits->min_rate || link_rate > limits->max_rate)
@@ -1746,11 +1748,23 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
 		for (lane_count = limits->min_lane_count;
 		     lane_count <= limits->max_lane_count;
 		     lane_count <<= 1) {
-			if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate, lane_count,
-							     adjusted_mode->clock,
-							     pipe_config->output_format,
-							     timeslots))
+
+			if (!timeslots) {
+				int ret;
+
+				ret = intel_dp_dsc_mst_compute_link_config(intel_dp, pipe_config,
+									   conn_state, link_rate, lane_count,
+									   compressed_bpp);
+				if (ret)
+					continue;
+			} else {
+
+				if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate, lane_count,
+								     adjusted_mode->clock,
+								     pipe_config->output_format,
+								     timeslots))
 				continue;
+			}
 
 			pipe_config->lane_count = lane_count;
 			pipe_config->port_clock = link_rate;
@@ -1841,6 +1855,7 @@ static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp)
 static int
 icl_dsc_compute_link_config(struct intel_dp *intel_dp,
 			    struct intel_crtc_state *pipe_config,
+			    struct drm_connector_state *conn_state,
 			    struct link_config_limits *limits,
 			    int dsc_max_bpp,
 			    int dsc_min_bpp,
@@ -1859,6 +1874,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
 
 		ret = dsc_compute_link_config(intel_dp,
 					      pipe_config,
+					      conn_state,
 					      limits,
 					      valid_dsc_bpp[i],
 					      timeslots);
@@ -1880,6 +1896,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
 static int
 xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
 			      struct intel_crtc_state *pipe_config,
+			      struct drm_connector_state *conn_state,
 			      struct link_config_limits *limits,
 			      int dsc_max_bpp,
 			      int dsc_min_bpp,
@@ -1897,6 +1914,7 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
 	     compressed_bpp--) {
 		ret = dsc_compute_link_config(intel_dp,
 					      pipe_config,
+					      conn_state,
 					      limits,
 					      compressed_bpp,
 					      timeslots);
@@ -1910,6 +1928,7 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
 
 static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
 				      struct intel_crtc_state *pipe_config,
+				      struct drm_connector_state *conn_state,
 				      struct link_config_limits *limits,
 				      int pipe_bpp,
 				      int timeslots)
@@ -1934,9 +1953,9 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
 	dsc_max_bpp = min(dsc_max_bpp, dsc_joiner_max_bpp);
 
 	if (DISPLAY_VER(i915) >= 13)
-		return xelpd_dsc_compute_link_config(intel_dp, pipe_config, limits,
+		return xelpd_dsc_compute_link_config(intel_dp, pipe_config, conn_state, limits,
 						     dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
-	return icl_dsc_compute_link_config(intel_dp, pipe_config, limits,
+	return icl_dsc_compute_link_config(intel_dp, pipe_config, conn_state, limits,
 					   dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
 }
 
@@ -2006,7 +2025,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
 	forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
 	if (forced_bpp) {
-		ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
+		ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state,
 						 limits, forced_bpp, timeslots);
 		if (ret == 0) {
 			pipe_config->pipe_bpp = forced_bpp;
@@ -2035,7 +2054,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
 			break;
 		if (pipe_bpp > dsc_max_bpp)
 			continue;
-		ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
+		ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state,
 						 limits, pipe_bpp, timeslots);
 		if (ret == 0) {
 			pipe_config->pipe_bpp = pipe_bpp;
@@ -2095,8 +2114,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 				struct intel_crtc_state *pipe_config,
 				struct drm_connector_state *conn_state,
 				struct link_config_limits *limits,
-				int timeslots,
-				bool compute_pipe_bpp)
+				int timeslots)
 {
 	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);
@@ -2113,24 +2131,16 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 	if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
 		return -EINVAL;
 
-	/*
-	 * compute pipe bpp is set to false for DP MST DSC case
-	 * and compressed_bpp is calculated same time once
-	 * vpci timeslots are allocated, because overall bpp
-	 * calculation procedure is bit different for MST case.
-	 */
-	if (compute_pipe_bpp) {
-		if (intel_dp_is_edp(intel_dp))
-			ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
-							     conn_state, limits);
-		else
-			ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
-							    conn_state, limits, timeslots);
-		if (ret) {
-			drm_dbg_kms(&dev_priv->drm,
-				    "No Valid pipe bpp for given mode ret = %d\n", ret);
-			return ret;
-		}
+	if (intel_dp_is_edp(intel_dp))
+		ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
+						     conn_state, limits);
+	else
+		ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
+						    conn_state, limits, timeslots);
+	if (ret) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "No Valid pipe bpp for given mode ret = %d\n", ret);
+		return ret;
 	}
 
 	/* Calculate Slice count */
@@ -2253,7 +2263,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			    str_yes_no(ret), str_yes_no(joiner_needs_dsc),
 			    str_yes_no(intel_dp->force_dsc_en));
 		ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
-						  conn_state, &limits, 64, true);
+						  conn_state, &limits, 64);
 		if (ret < 0)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 788a577ebe16..095cbc602e7c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -63,8 +63,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 				struct intel_crtc_state *pipe_config,
 				struct drm_connector_state *conn_state,
 				struct link_config_limits *limits,
-				int timeslots,
-				bool recompute_pipe_bpp);
+				int timeslots);
 bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp);
 bool intel_dp_is_edp(struct intel_dp *intel_dp);
 bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);
@@ -145,5 +144,9 @@ void intel_dp_phy_test(struct intel_encoder *encoder);
 
 void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
 int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
+bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+				     u32 lane_count, u32 mode_clock,
+				     enum intel_output_format output_format,
+				     int timeslots);
 
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 3eb085fbc7c8..d9436c7caf0d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -72,8 +72,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
 						int min_bpp,
 						struct link_config_limits *limits,
 						struct drm_connector_state *conn_state,
-						int step,
-						bool dsc)
+						int step)
 {
 	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
@@ -104,13 +103,11 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
 	for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
 		drm_dbg_kms(&i915->drm, "Trying bpp %d\n", bpp);
 
-		ret = intel_dp_mst_check_constraints(i915, bpp, adjusted_mode, crtc_state, dsc);
+		ret = intel_dp_mst_check_constraints(i915, bpp, adjusted_mode, crtc_state, false);
 		if (ret)
 			continue;
 
-		crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock,
-						       dsc ? bpp << 4 : bpp,
-						       dsc);
+		crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp, false);
 
 		slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr,
 						      connector->port,
@@ -137,11 +134,8 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
 		drm_dbg_kms(&i915->drm, "failed finding vcpi slots:%d\n",
 			    slots);
 	} else {
-		if (!dsc)
-			crtc_state->pipe_bpp = bpp;
-		else
-			crtc_state->dsc.compressed_bpp = bpp;
-		drm_dbg_kms(&i915->drm, "Got %d slots for pipe bpp %d dsc %d\n", slots, bpp, dsc);
+		crtc_state->pipe_bpp = bpp;
+		drm_dbg_kms(&i915->drm, "Got %d slots for pipe bpp %d\n", slots, bpp);
 	}
 
 	return slots;
@@ -159,7 +153,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 
 	slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, limits->max_bpp,
 						     limits->min_bpp, limits,
-						     conn_state, 2 * 3, false);
+						     conn_state, 2 * 3);
 
 	if (slots < 0)
 		return slots;
@@ -177,99 +171,63 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 	return 0;
 }
 
-static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder,
-						struct intel_crtc_state *crtc_state,
-						struct drm_connector_state *conn_state,
-						struct link_config_limits *limits)
+int intel_dp_dsc_mst_compute_link_config(struct intel_dp *intel_dp,
+					 struct intel_crtc_state *crtc_state,
+					 struct drm_connector_state *conn_state,
+					 int link_rate, int lane_count,
+					 u16 compressed_bpp)
 {
-	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
-	struct intel_dp *intel_dp = &intel_mst->primary->dp;
+	struct drm_atomic_state *state = crtc_state->uapi.state;
+	struct drm_dp_mst_topology_state *mst_state;
 	struct intel_connector *connector =
 		to_intel_connector(conn_state->connector);
-	struct drm_i915_private *i915 = to_i915(connector->base.dev);
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
 	int slots = -EINVAL;
-	int i, num_bpc;
-	u8 dsc_bpc[3] = {0};
-	int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp;
-	u8 dsc_max_bpc;
-	bool need_timeslot_recalc = false;
-	u32 last_compressed_bpp;
-
-	/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */
-	if (DISPLAY_VER(i915) >= 12)
-		dsc_max_bpc = min_t(u8, 12, conn_state->max_requested_bpc);
-	else
-		dsc_max_bpc = min_t(u8, 10, conn_state->max_requested_bpc);
-
-	max_bpp = min_t(u8, dsc_max_bpc * 3, limits->max_bpp);
-	min_bpp = limits->min_bpp;
-
-	num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
-						       dsc_bpc);
-
-	drm_dbg_kms(&i915->drm, "DSC Source supported min bpp %d max bpp %d\n",
-		    min_bpp, max_bpp);
-
-	sink_max_bpp = dsc_bpc[0] * 3;
-	sink_min_bpp = sink_max_bpp;
+	int ret = 0;
+	int pbn_div, pbn;
 
-	for (i = 1; i < num_bpc; i++) {
-		if (sink_min_bpp > dsc_bpc[i] * 3)
-			sink_min_bpp = dsc_bpc[i] * 3;
-		if (sink_max_bpp < dsc_bpc[i] * 3)
-			sink_max_bpp = dsc_bpc[i] * 3;
-	}
+	mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr);
+	if (IS_ERR(mst_state))
+		return PTR_ERR(mst_state);
 
-	drm_dbg_kms(&i915->drm, "DSC Sink supported min bpp %d max bpp %d\n",
-		    sink_min_bpp, sink_max_bpp);
+	ret = intel_dp_mst_check_constraints(i915, compressed_bpp, adjusted_mode, crtc_state, true);
+	if (ret)
+		return ret;
 
-	if (min_bpp < sink_min_bpp)
-		min_bpp = sink_min_bpp;
+	pbn_div = drm_dp_get_vc_payload_bw(&intel_dp->mst_mgr, link_rate, lane_count);
 
-	if (max_bpp > sink_max_bpp)
-		max_bpp = sink_max_bpp;
+	pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, compressed_bpp << 4, true);
 
-	slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, max_bpp,
-						     min_bpp, limits,
-						     conn_state, 2 * 3, true);
+	slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, connector->port, pbn);
 
 	if (slots < 0)
 		return slots;
 
-	last_compressed_bpp = crtc_state->dsc.compressed_bpp;
+	ret = drm_dp_mst_atomic_check(state);
+	if (ret)
+		return ret;
 
-	crtc_state->dsc.compressed_bpp = intel_dp_dsc_nearest_valid_bpp(i915,
-									last_compressed_bpp,
-									crtc_state->pipe_bpp);
+	if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate,
+					     lane_count, adjusted_mode->clock,
+					     crtc_state->output_format, slots))
+		return -EINVAL;
 
-	if (crtc_state->dsc.compressed_bpp != last_compressed_bpp)
-		need_timeslot_recalc = true;
+	drm_dbg_kms(&i915->drm, "Got %d slots for compressed bpp %d\n", slots, compressed_bpp);
 
-	/*
-	 * Apparently some MST hubs dislike if vcpi slots are not matching precisely
-	 * the actual compressed bpp we use.
-	 */
-	if (need_timeslot_recalc) {
-		slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state,
-							     crtc_state->dsc.compressed_bpp,
-							     crtc_state->dsc.compressed_bpp,
-							     limits, conn_state, 2 * 3, true);
-		if (slots < 0)
-			return slots;
-	}
+	mst_state->pbn_div = pbn_div;
+	crtc_state->pbn = pbn;
 
-	intel_link_compute_m_n(crtc_state->dsc.compressed_bpp,
-			       crtc_state->lane_count,
+	intel_link_compute_m_n(compressed_bpp, lane_count,
 			       adjusted_mode->crtc_clock,
-			       crtc_state->port_clock,
-			       &crtc_state->dp_m_n,
+			       link_rate, &crtc_state->dp_m_n,
 			       crtc_state->fec_enable);
-	crtc_state->dp_m_n.tu = slots;
 
+	crtc_state->dp_m_n.tu = slots;
 	return 0;
 }
+
 static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
 				     struct intel_crtc_state *crtc_state,
 				     struct drm_connector_state *conn_state)
@@ -372,14 +330,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 		 */
 		drm_dbg_kms(&dev_priv->drm, "Trying to find VCPI slots in DSC mode\n");
 
-		ret = intel_dp_dsc_mst_compute_link_config(encoder, pipe_config,
-							   conn_state, &limits);
-		if (ret < 0)
-			return ret;
-
 		ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
-						  conn_state, &limits,
-						  pipe_config->dp_m_n.tu, false);
+						  conn_state, &limits, 0);
 	}
 
 	if (ret)
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h
index f1815bb72267..383c6c7b89a9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
@@ -13,6 +13,7 @@ struct intel_crtc;
 struct intel_crtc_state;
 struct intel_digital_port;
 struct intel_dp;
+struct drm_connector_state;
 
 int intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *dig_port);
@@ -22,5 +23,10 @@ bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state);
 bool intel_dp_mst_source_support(struct intel_dp *intel_dp);
 int intel_dp_mst_add_topology_state_for_crtc(struct intel_atomic_state *state,
 					     struct intel_crtc *crtc);
+int intel_dp_dsc_mst_compute_link_config(struct intel_dp *intel_dp,
+					 struct intel_crtc_state *crtc_state,
+					 struct drm_connector_state *conn_state,
+					 int link_rate, int lane_count,
+					 u16 compressed_bpp);
 
 #endif /* __INTEL_DP_MST_H__ */
-- 
2.40.1



More information about the Intel-gfx-trybot mailing list