@@ -1855,7 +1855,8 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct link_config_limits limits;
bool joiner_needs_dsc = false;
- int ret;
+ bool dsc_needed;
+ int ret = 0;
intel_dp_compute_config_limits(intel_dp, pipe_config,
respect_downstream_limits, &limits);
@@ -1871,13 +1872,20 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
*/
joiner_needs_dsc = DISPLAY_VER(i915) < 13 && pipe_config->bigjoiner_pipes;
- /*
- * Optimize for slow and wide for everything, because there are some
- * eDP 1.3 and 1.4 panels don't work well with fast and narrow.
- */
- ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, conn_state, &limits);
+ dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en;
+
+ if (!dsc_needed) {
+ /*
+ * Optimize for slow and wide for everything, because there are some
+ * eDP 1.3 and 1.4 panels don't work well with fast and narrow.
+ */
+ ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config,
+ conn_state, &limits);
+ if (ret)
+ dsc_needed = true;
+ }
- if (ret || joiner_needs_dsc || intel_dp->force_dsc_en) {
+ if (dsc_needed) {
drm_dbg_kms(&i915->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",
str_yes_no(ret), str_yes_no(joiner_needs_dsc),
str_yes_no(intel_dp->force_dsc_en));
@@ -347,7 +347,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
const struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
struct link_config_limits limits;
- int ret;
+ bool dsc_needed;
+ int ret = 0;
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
@@ -362,15 +363,25 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
intel_dp_mst_compute_config_limits(intel_dp, pipe_config, &limits);
- ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
- conn_state, &limits);
+ dsc_needed = intel_dp->force_dsc_en;
- if (ret == -EDEADLK)
- return ret;
+ if (!dsc_needed) {
+ ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
+ conn_state, &limits);
+
+ if (ret == -EDEADLK)
+ return ret;
+
+ if (ret)
+ dsc_needed = true;
+ }
/* enable compression if the mode doesn't fit available BW */
- drm_dbg_kms(&dev_priv->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en);
- if (ret || intel_dp->force_dsc_en) {
+ if (dsc_needed) {
+ drm_dbg_kms(&dev_priv->drm, "Try DSC (fallback=%s, force=%s)\n",
+ str_yes_no(ret),
+ str_yes_no(intel_dp->force_dsc_en));
+
/*
* Try to get at least some timeslots and then see, if
* we can fit there with DSC.
Computing the non-DSC mode link config is redundant once it's determined that DSC will be needed, so skip computing it. In a follow-up patch this simplifies setting the link limits which are dependent on the DSC vs. non-DSC mode. While at it sanitize the debug print about the MST DSC fallback path, making it similar to the SST DSC one. Signed-off-by: Imre Deak <imre.deak@intel.com> --- drivers/gpu/drm/i915/display/intel_dp.c | 22 ++++++++++++------ drivers/gpu/drm/i915/display/intel_dp_mst.c | 25 +++++++++++++++------ 2 files changed, 33 insertions(+), 14 deletions(-)