plane_state->uapi.visible);
 }
 
+static int intel_modeset_pipe(struct intel_atomic_state *state,
+                             struct intel_crtc_state *crtc_state,
+                             const char *reason)
+{
+       struct drm_i915_private *i915 = to_i915(state->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       int ret;
+
+       drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Full modeset due to %s\n",
+                   crtc->base.base.id, crtc->base.name, reason);
+
+       ret = drm_atomic_add_affected_connectors(&state->base,
+                                                &crtc->base);
+       if (ret)
+               return ret;
+
+       ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
+       if (ret)
+               return ret;
+
+       ret = intel_atomic_add_affected_planes(state, crtc);
+       if (ret)
+               return ret;
+
+       crtc_state->uapi.mode_changed = true;
+
+       return 0;
+}
+
+/**
+ * intel_modeset_pipes_in_mask_early - force a full modeset on a set of pipes
+ * @state: intel atomic state
+ * @reason: the reason for the full modeset
+ * @mask: mask of pipes to modeset
+ *
+ * Add pipes in @mask to @state and force a full modeset on the enabled ones
+ * due to the description in @reason.
+ * This function can be called only before new plane states are computed.
+ *
+ * Returns 0 in case of success, negative error code otherwise.
+ */
+int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
+                                     const char *reason, u8 mask)
+{
+       struct drm_i915_private *i915 = to_i915(state->base.dev);
+       struct intel_crtc *crtc;
+
+       for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, mask) {
+               struct intel_crtc_state *crtc_state;
+               int ret;
+
+               crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
+               if (IS_ERR(crtc_state))
+                       return PTR_ERR(crtc_state);
+
+               if (!crtc_state->hw.enable ||
+                   intel_crtc_needs_modeset(crtc_state))
+                       continue;
+
+               ret = intel_modeset_pipe(state, crtc_state, reason);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+/**
+ * intel_modeset_all_pipes - force a full modeset on all pipes
+ * @state: intel atomic state
+ * @reason: the reason for the full modeset
+ *
+ * Add all pipes to @state and force a full modeset on the active ones due to
+ * the description in @reason.
+ * This function can be called only after new plane states are computed already.
+ *
+ * Returns 0 in case of success, negative error code otherwise.
+ */
 int intel_modeset_all_pipes(struct intel_atomic_state *state,
                            const char *reason)
 {
        struct drm_i915_private *dev_priv = to_i915(state->base.dev);
        struct intel_crtc *crtc;
 
-       /*
-        * Add all pipes to the state, and force
-        * a modeset on all the active ones.
-        */
        for_each_intel_crtc(&dev_priv->drm, crtc) {
                struct intel_crtc_state *crtc_state;
                int ret;
                    intel_crtc_needs_modeset(crtc_state))
                        continue;
 
-               drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s] Full modeset due to %s\n",
-                           crtc->base.base.id, crtc->base.name, reason);
+               ret = intel_modeset_pipe(state, crtc_state, reason);
+               if (ret)
+                       return ret;
 
-               crtc_state->uapi.mode_changed = true;
                crtc_state->update_pipe = false;
                crtc_state->update_m_n = false;
                crtc_state->update_lrr = false;
-
-               ret = drm_atomic_add_affected_connectors(&state->base,
-                                                        &crtc->base);
-               if (ret)
-                       return ret;
-
-               ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
-               if (ret)
-                       return ret;
-
-               ret = intel_atomic_add_affected_planes(state, crtc);
-               if (ret)
-                       return ret;
-
                crtc_state->update_planes |= crtc_state->active_planes;
                crtc_state->async_flip_planes = 0;
                crtc_state->do_async_flip = false;