On Fri, 10 Sep 2021, Dave Airlie <airl...@gmail.com> wrote:
> From: Dave Airlie <airl...@redhat.com>
>
> This moves one wrapper from the pm->display side, and creates
> wrappers for all the others, this should simplify things later.
>
> One thing to note is that the code checks the existance of some
> of these ptrs, so the wrappers are a bit complicated by that.
>
> Suggested by Jani.
>
> v2: fixup warnings in wrong place error.

Reviewed-by: Jani Nikula <jani.nik...@intel.com>


>
> Signed-off-by: Dave Airlie <airl...@redhat.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 187 ++++++++++++-------
>  drivers/gpu/drm/i915/intel_pm.c              |  39 ----
>  drivers/gpu/drm/i915/intel_pm.h              |   1 -
>  3 files changed, 123 insertions(+), 104 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index e62f8317cbda..a1380ce02861 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -126,6 +126,101 @@ static void ilk_pfit_enable(const struct 
> intel_crtc_state *crtc_state);
>  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 void 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)
> +             dev_priv->display.compute_global_watermarks(state);
> +}
> +
>  /* returns HPLL frequency in kHz */
>  int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
>  {
> @@ -2528,9 +2623,8 @@ static void intel_pre_plane_update(struct 
> intel_atomic_state *state,
>                * 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)
> +             if (!intel_initial_watermarks(state, crtc))
> +                 if (new_crtc_state->update_wm_pre)
>                       intel_update_watermarks(dev_priv);
>       }
>  
> @@ -2903,8 +2997,7 @@ static void ilk_crtc_enable(struct intel_atomic_state 
> *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);
> +     intel_initial_watermarks(state, crtc);
>       intel_enable_pipe(new_crtc_state);
>  
>       if (new_crtc_state->has_pch_encoder)
> @@ -3114,8 +3207,7 @@ static void hsw_crtc_enable(struct intel_atomic_state 
> *state,
>       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 =
> @@ -3532,7 +3624,7 @@ static void valleyview_crtc_enable(struct 
> intel_atomic_state *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_pipe(new_crtc_state);
>  
>       intel_crtc_vblank_on(new_crtc_state);
> @@ -3575,10 +3667,8 @@ static void i9xx_crtc_enable(struct intel_atomic_state 
> *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
> -             intel_update_watermarks(dev_priv);
> +     if (!intel_initial_watermarks(state, crtc))
> +         intel_update_watermarks(dev_priv);
>       intel_enable_pipe(new_crtc_state);
>  
>       intel_crtc_vblank_on(new_crtc_state);
> @@ -6752,32 +6842,23 @@ static int intel_crtc_atomic_check(struct 
> intel_atomic_state *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) {
> @@ -8870,23 +8951,6 @@ static int intel_modeset_checks(struct 
> intel_atomic_state *state)
>       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)
>  {
> @@ -9533,9 +9597,7 @@ static int intel_atomic_check(struct drm_device *dev,
>               goto fail;
>  
>       intel_fbc_choose_crtc(dev_priv, state);
> -     ret = calc_watermark_data(state);
> -     if (ret)
> -             goto fail;
> +     intel_compute_global_watermarks(state);
>  
>       ret = intel_bw_atomic_check(state);
>       if (ret)
> @@ -9707,8 +9769,7 @@ static void commit_pipe_pre_planes(struct 
> intel_atomic_state *state,
>               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,
> @@ -9835,9 +9896,8 @@ static void intel_old_crtc_state_disables(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)
> @@ -10259,8 +10319,7 @@ static void intel_atomic_commit_tail(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);
> @@ -11361,7 +11420,7 @@ static void sanitize_watermarks(struct 
> drm_i915_private *dev_priv)
>       /* 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;
>       }
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index be6520756aae..4054c6f7a2f9 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7132,45 +7132,6 @@ void ilk_wm_get_hw_state(struct drm_i915_private 
> *dev_priv)
>               !(intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) & 
> DISP_FBC_WM_DIS);
>  }
>  
> -/**
> - * 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.
> - */
> -void intel_update_watermarks(struct drm_i915_private *dev_priv)
> -{
> -     if (dev_priv->display.update_wm)
> -             dev_priv->display.update_wm(dev_priv);
> -}
> -
>  void intel_enable_ipc(struct drm_i915_private *dev_priv)
>  {
>       u32 val;
> diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h
> index 99bce0b4f5fb..990cdcaf85ce 100644
> --- a/drivers/gpu/drm/i915/intel_pm.h
> +++ b/drivers/gpu/drm/i915/intel_pm.h
> @@ -29,7 +29,6 @@ struct skl_wm_level;
>  void intel_init_clock_gating(struct drm_i915_private *dev_priv);
>  void intel_suspend_hw(struct drm_i915_private *dev_priv);
>  int ilk_wm_max_level(const struct drm_i915_private *dev_priv);
> -void intel_update_watermarks(struct drm_i915_private *dev_priv);
>  void intel_init_pm(struct drm_i915_private *dev_priv);
>  void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv);
>  void intel_pm_setup(struct drm_i915_private *dev_priv);

-- 
Jani Nikula, Intel Open Source Graphics Center

Reply via email to