diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index e4a79c11fd255..cc9be82e128f4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1596,6 +1596,16 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			return ret;
 	}
 
+	return 0;
+}
+
+static void
+intel_dp_print_link_config(struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
+	const struct drm_display_mode *adjusted_mode =
+			&pipe_config->hw.adjusted_mode;
+
 	if (pipe_config->dsc.compression_enable) {
 		drm_dbg_kms(&i915->drm,
 			    "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n",
@@ -1621,7 +1631,6 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			    intel_dp_max_data_rate(pipe_config->port_clock,
 						   pipe_config->lane_count));
 	}
-	return 0;
 }
 
 bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
@@ -1915,6 +1924,72 @@ static bool intel_dp_has_audio(struct intel_encoder *encoder,
 		return intel_conn_state->force_audio == HDMI_AUDIO_ON;
 }
 
+/*
+ * If modeset is not allowed it checks for link computed state and if different
+ * it checks if is possible to fallback to previous configuration.
+ *
+ * Returns 0 if modeset is allowed, link computed states matches or fallback is
+ * possible otherwise returns a errno.
+ */
+static int
+intel_dp_compute_link_config_no_modeset_fallback(struct intel_crtc_state *crtc_state)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
+	struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+	const struct intel_crtc_state *old_crtc_state;
+	int output_bpp, mode_rate, old_link_avail;
+	struct intel_crtc *crtc;
+
+	if (state->base.allow_modeset)
+		return 0;
+
+	crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
+
+	/* Check if both states matches */
+	if (crtc_state->output_format == old_crtc_state->output_format &&
+	    crtc_state->port_clock == old_crtc_state->port_clock &&
+	    crtc_state->lane_count == old_crtc_state->lane_count &&
+	    crtc_state->pipe_bpp == old_crtc_state->pipe_bpp &&
+	    crtc_state->dsc.compression_enable == old_crtc_state->dsc.compression_enable &&
+	    crtc_state->dsc.compressed_bpp == old_crtc_state->dsc.compressed_bpp &&
+	    crtc_state->dsc.slice_count == old_crtc_state->dsc.slice_count &&
+	    crtc_state->bigjoiner_pipes == old_crtc_state->bigjoiner_pipes)
+		return 0;
+
+	/*
+	 * Modeset will be required if any of this changed, there is no way
+	 * around it
+	 */
+	if (crtc_state->output_format != old_crtc_state->output_format ||
+	    crtc_state->bigjoiner_pipes != old_crtc_state->bigjoiner_pipes ||
+	    crtc_state->dsc.compression_enable != old_crtc_state->dsc.compression_enable)
+		return -EINVAL;
+
+	/* TODO: Not supporting DSC fallback but it might be possible */
+	if (crtc_state->dsc.compression_enable)
+		return -EINVAL;
+
+	output_bpp = intel_dp_output_bpp(crtc_state->output_format,
+					 old_crtc_state->pipe_bpp);
+	mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
+					   output_bpp);
+
+	old_link_avail = intel_dp_max_data_rate(old_crtc_state->port_clock,
+						old_crtc_state->lane_count);
+
+	/* Check if old link configuration has enough bandwidth for new mode */
+	if (mode_rate > old_link_avail)
+		return -EINVAL;
+
+	/* Fallback is possible */
+	crtc_state->lane_count = old_crtc_state->lane_count;
+	crtc_state->pipe_bpp = old_crtc_state->pipe_bpp;
+	crtc_state->port_clock = old_crtc_state->port_clock;
+
+	return 0;
+}
+
 static int
 intel_dp_compute_output_format(struct intel_encoder *encoder,
 			       struct intel_crtc_state *crtc_state,
@@ -1950,8 +2025,17 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
 		crtc_state->output_format = intel_dp_output_format(connector, true);
 		ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
 						   respect_downstream_limits);
+		if (ret)
+			return ret;
 	}
 
+	ret = intel_dp_compute_link_config_no_modeset_fallback(crtc_state);
+	if (ret)
+		drm_dbg_kms(&i915->drm, "DP link configuration requires "
+			    "changes but modeset is not allowed\n");
+
+	intel_dp_print_link_config(crtc_state);
+
 	return ret;
 }
 
