static void intel_modeset_setup_hw_state(struct drm_device *dev,
                                         struct drm_modeset_acquire_ctx *ctx);
 
+/**
+ * intel_update_watermarks - update FIFO watermark values based on current modes
+ * @dev_priv: i915 device
+ *
+ * Calculate watermark values for the various WM regs based on current mode
+ * and plane configuration.
+ *
+ * There are several cases to deal with here:
+ *   - normal (i.e. non-self-refresh)
+ *   - self-refresh (SR) mode
+ *   - lines are large relative to FIFO size (buffer can hold up to 2)
+ *   - lines are small relative to FIFO size (buffer can hold more than 2
+ *     lines), so need to account for TLB latency
+ *
+ *   The normal calculation is:
+ *     watermark = dotclock * bytes per pixel * latency
+ *   where latency is platform & configuration dependent (we assume pessimal
+ *   values here).
+ *
+ *   The SR calculation is:
+ *     watermark = (trunc(latency/line time)+1) * surface width *
+ *       bytes per pixel
+ *   where
+ *     line time = htotal / dotclock
+ *     surface width = hdisplay for normal plane and 64 for cursor
+ *   and latency is assumed to be high, as above.
+ *
+ * The final value programmed to the register should always be rounded up,
+ * and include an extra 2 entries to account for clock crossings.
+ *
+ * We don't use the sprite, so we can ignore that.  And on Crestline we have
+ * to set the non-SR watermarks to 8.
+ */
+static void intel_update_watermarks(struct drm_i915_private *dev_priv)
+{
+       if (dev_priv->display.update_wm)
+               dev_priv->display.update_wm(dev_priv);
+}
+
+static int intel_compute_pipe_wm(struct intel_atomic_state *state,
+                                struct intel_crtc *crtc)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+       if (dev_priv->display.compute_pipe_wm)
+               return dev_priv->display.compute_pipe_wm(state, crtc);
+       return 0;
+}
+
+static int intel_compute_intermediate_wm(struct intel_atomic_state *state,
+                                        struct intel_crtc *crtc)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+       if (!dev_priv->display.compute_intermediate_wm)
+               return 0;
+       if (drm_WARN_ON(&dev_priv->drm,
+                       !dev_priv->display.compute_pipe_wm))
+               return 0;
+       return dev_priv->display.compute_intermediate_wm(state, crtc);
+}
+
+static bool intel_initial_watermarks(struct intel_atomic_state *state,
+                                    struct intel_crtc *crtc)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+       if (dev_priv->display.initial_watermarks) {
+               dev_priv->display.initial_watermarks(state, crtc);
+               return true;
+       }
+       return false;
+}
+
+static void intel_atomic_update_watermarks(struct intel_atomic_state *state,
+                                          struct intel_crtc *crtc)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+       if (dev_priv->display.atomic_update_watermarks)
+               dev_priv->display.atomic_update_watermarks(state, crtc);
+}
+
+static void intel_optimize_watermarks(struct intel_atomic_state *state,
+                                     struct intel_crtc *crtc)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+       if (dev_priv->display.optimize_watermarks)
+               dev_priv->display.optimize_watermarks(state, crtc);
+}
+
+static int intel_compute_global_watermarks(struct intel_atomic_state *state)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+       if (dev_priv->display.compute_global_watermarks)
+               return dev_priv->display.compute_global_watermarks(state);
+       return 0;
+}
+
 /* returns HPLL frequency in kHz */
 int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
 {
                 * we'll continue to update watermarks the old way, if flags tell
                 * us to.
                 */
-               if (dev_priv->display.initial_watermarks)
-                       dev_priv->display.initial_watermarks(state, crtc);
-               else if (new_crtc_state->update_wm_pre)
-                       intel_update_watermarks(dev_priv);
+               if (!intel_initial_watermarks(state, crtc))
+                       if (new_crtc_state->update_wm_pre)
+                               intel_update_watermarks(dev_priv);
        }
 
        /*
        /* update DSPCNTR to configure gamma for pipe bottom color */
        intel_disable_primary_plane(new_crtc_state);
 
-       if (dev_priv->display.initial_watermarks)
-               dev_priv->display.initial_watermarks(state, crtc);
+       intel_initial_watermarks(state, crtc);
        intel_enable_transcoder(new_crtc_state);
 
        if (new_crtc_state->has_pch_encoder)
        if (DISPLAY_VER(dev_priv) >= 11)
                icl_set_pipe_chicken(new_crtc_state);
 
-       if (dev_priv->display.initial_watermarks)
-               dev_priv->display.initial_watermarks(state, crtc);
+       intel_initial_watermarks(state, crtc);
 
        if (DISPLAY_VER(dev_priv) >= 11) {
                const struct intel_dbuf_state *dbuf_state =
        /* update DSPCNTR to configure gamma for pipe bottom color */
        intel_disable_primary_plane(new_crtc_state);
 
-       dev_priv->display.initial_watermarks(state, crtc);
+       intel_initial_watermarks(state, crtc);
        intel_enable_transcoder(new_crtc_state);
 
        intel_crtc_vblank_on(new_crtc_state);
        /* update DSPCNTR to configure gamma for pipe bottom color */
        intel_disable_primary_plane(new_crtc_state);
 
-       if (dev_priv->display.initial_watermarks)
-               dev_priv->display.initial_watermarks(state, crtc);
-       else
+       if (!intel_initial_watermarks(state, crtc))
                intel_update_watermarks(dev_priv);
        intel_enable_transcoder(new_crtc_state);
 
                        return ret;
        }
 
-       if (dev_priv->display.compute_pipe_wm) {
-               ret = dev_priv->display.compute_pipe_wm(state, crtc);
-               if (ret) {
-                       drm_dbg_kms(&dev_priv->drm,
-                                   "Target pipe watermarks are invalid\n");
-                       return ret;
-               }
-
+       ret = intel_compute_pipe_wm(state, crtc);
+       if (ret) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "Target pipe watermarks are invalid\n");
+               return ret;
        }
 
-       if (dev_priv->display.compute_intermediate_wm) {
-               if (drm_WARN_ON(&dev_priv->drm,
-                               !dev_priv->display.compute_pipe_wm))
-                       return 0;
-
-               /*
-                * Calculate 'intermediate' watermarks that satisfy both the
-                * old state and the new state.  We can program these
-                * immediately.
-                */
-               ret = dev_priv->display.compute_intermediate_wm(state, crtc);
-               if (ret) {
-                       drm_dbg_kms(&dev_priv->drm,
-                                   "No valid intermediate pipe watermarks are possible\n");
-                       return ret;
-               }
+       /*
+        * Calculate 'intermediate' watermarks that satisfy both the
+        * old state and the new state.  We can program these
+        * immediately.
+        */
+       ret = intel_compute_intermediate_wm(state, crtc);
+       if (ret) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "No valid intermediate pipe watermarks are possible\n");
+               return ret;
        }
 
        if (DISPLAY_VER(dev_priv) >= 9) {
        return 0;
 }
 
-/*
- * Handle calculation of various watermark data at the end of the atomic check
- * phase.  The code here should be run after the per-crtc and per-plane 'check'
- * handlers to ensure that all derived state has been updated.
- */
-static int calc_watermark_data(struct intel_atomic_state *state)
-{
-       struct drm_device *dev = state->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-
-       /* Is there platform-specific watermark information to calculate? */
-       if (dev_priv->display.compute_global_watermarks)
-               return dev_priv->display.compute_global_watermarks(state);
-
-       return 0;
-}
-
 static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_state,
                                     struct intel_crtc_state *new_crtc_state)
 {
                goto fail;
 
        intel_fbc_choose_crtc(dev_priv, state);
-       ret = calc_watermark_data(state);
+       ret = intel_compute_global_watermarks(state);
        if (ret)
                goto fail;
 
 
        intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
 
-       if (dev_priv->display.atomic_update_watermarks)
-               dev_priv->display.atomic_update_watermarks(state, crtc);
+       intel_atomic_update_watermarks(state, crtc);
 }
 
 static void commit_pipe_post_planes(struct intel_atomic_state *state,
 
        /* FIXME unify this for all platforms */
        if (!new_crtc_state->hw.active &&
-           !HAS_GMCH(dev_priv) &&
-           dev_priv->display.initial_watermarks)
-               dev_priv->display.initial_watermarks(state, crtc);
+           !HAS_GMCH(dev_priv))
+               intel_initial_watermarks(state, crtc);
 }
 
 static void intel_commit_modeset_disables(struct intel_atomic_state *state)
                if (DISPLAY_VER(dev_priv) == 2 && planes_enabling(old_crtc_state, new_crtc_state))
                        intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
 
-               if (dev_priv->display.optimize_watermarks)
-                       dev_priv->display.optimize_watermarks(state, crtc);
+               intel_optimize_watermarks(state, crtc);
        }
 
        intel_dbuf_post_plane_update(state);
        /* Write calculated watermark values back */
        for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
                crtc_state->wm.need_postvbl_update = true;
-               dev_priv->display.optimize_watermarks(intel_state, crtc);
+               intel_optimize_watermarks(intel_state, crtc);
 
                to_intel_crtc_state(crtc->base.state)->wm = crtc_state->wm;
        }