diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 19de0b5a7a40..31b37722cd89 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -30,6 +30,38 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 
+static int
+intel_dp_mst_atomic_release_vcpi_slots(struct drm_atomic_state *state,
+				       struct drm_crtc_state *crtc_state,
+				       struct drm_connector_state *conn_state)
+{
+	struct drm_crtc_state *new_crtc_state;
+	struct intel_crtc_state *intel_crtc_state =
+		to_intel_crtc_state(crtc_state);
+	struct drm_encoder *encoder;
+	struct drm_dp_mst_topology_mgr *mgr;
+	int slots, ret;
+
+	slots = intel_crtc_state->dp_m_n.tu;
+	if (slots <= 0)
+		return 0;
+
+	encoder = conn_state->best_encoder;
+	mgr = &enc_to_mst(encoder)->primary->dp.mst_mgr;
+
+	ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots);
+	if (ret) {
+		DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n",
+			      slots, ret);
+	} else {
+		new_crtc_state = drm_atomic_get_crtc_state(state,
+							   crtc_state->crtc);
+		to_intel_crtc_state(new_crtc_state)->dp_m_n.tu = 0;
+	}
+
+	return ret;
+}
+
 static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 					struct intel_crtc_state *pipe_config,
 					struct drm_connector_state *conn_state)
@@ -44,10 +76,14 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	struct drm_dp_mst_topology_state *mst_state =
 		drm_atomic_dp_mst_get_topology_state(state, &intel_dp->mst_mgr);
 	struct intel_dp_mst_topology_state *intel_mst_state;
+	struct drm_connector_state *old_conn_state =
+		drm_atomic_get_old_connector_state(state, &connector->base);
+	struct drm_crtc *old_crtc;
 	int bpp;
 	int slots;
 	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 	int mst_pbn;
+	int ret;
 	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
 					   DP_DPCD_QUIRK_LIMITED_M_N);
 
@@ -80,6 +116,21 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
 	pipe_config->pbn = mst_pbn;
 
+	/* Free any VCPI allocations on this connector from the previous
+	 * state
+	 */
+	old_crtc = old_conn_state->crtc;
+	if (old_crtc) {
+		struct drm_crtc_state *old_crtc_state =
+			drm_atomic_get_old_crtc_state(state, old_crtc);
+
+		ret = intel_dp_mst_atomic_release_vcpi_slots(state,
+							     old_crtc_state,
+							     old_conn_state);
+		if (ret)
+			return ret;
+	}
+
 	slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
 					      connector->port, mst_pbn);
 	if (slots < 0) {
@@ -109,31 +160,22 @@ static int intel_dp_mst_atomic_check(struct drm_connector *connector,
 {
 	struct drm_atomic_state *state = new_conn_state->state;
 	struct drm_connector_state *old_conn_state;
-	struct drm_crtc *old_crtc;
-	struct drm_crtc_state *crtc_state;
-	int slots, ret = 0;
+	struct drm_crtc_state *new_crtc_state;
+	int ret = 0;
 
 	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
-	old_crtc = old_conn_state->crtc;
-	if (!old_crtc)
-		return ret;
 
-	crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc);
-	slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu;
-	if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) {
-		struct drm_dp_mst_topology_mgr *mgr;
-		struct drm_encoder *old_encoder;
-
-		old_encoder = old_conn_state->best_encoder;
-		mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr;
+	/* Only free VCPI here if we're not going to be detaching the
+	 * connector's current CRTC, since no config will be computed
+	 */
+	if (new_conn_state->crtc || !old_conn_state->crtc)
+		return ret;
 
-		ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots);
-		if (ret)
-			DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", slots, ret);
-		else
-			to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0;
-	}
-	return ret;
+	new_crtc_state = drm_atomic_get_new_crtc_state(state,
+						       old_conn_state->crtc);
+	return intel_dp_mst_atomic_release_vcpi_slots(state,
+						      new_crtc_state,
+						      old_conn_state);
 }
 
 static void intel_mst_disable_dp(struct intel_encoder *encoder,
