[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