> -----Original Message-----
> From: Intel-gfx <[email protected]> On Behalf Of Ville
> Syrjala
> Sent: Wednesday, October 8, 2025 11:56 PM
> To: [email protected]
> Cc: [email protected]
> Subject: [RFC][PATCH 07/11] drm/i915: Introduce
> intel_compute_global_watermarks_late()
> 
> From: Ville Syrjälä <[email protected]>
> 
> Add a late watermarks computation stage for skl+. Need this (temporarily
> perhaps) to get the final cdclk values into skl_wm_check_vblank().
> 
> But the order is actually wrong now for SAGV. For SAGV we want to first do
> skl_wm_check_vblank(), then copute crttc_state->use_sagv_wm, and then do

Nit: Typo in crtc

> intel_bw_atomic_check().
> 
> Scalers are completely borked as far as skl_wm_check_vblank() goes as well.
> 
> TODO: just a hack really, need to figure out the correct order
>       for real

We can go with hack for now and take up the re-factoring later to sort out the 
correct order.
Reviewed-by: Uma Shankar <[email protected]>

> Signed-off-by: Ville Syrjälä <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  |  4 ++
> .../gpu/drm/i915/display/intel_display_core.h |  1 +
>  drivers/gpu/drm/i915/display/intel_wm.c       | 10 +++++
>  drivers/gpu/drm/i915/display/intel_wm.h       |  1 +
>  drivers/gpu/drm/i915/display/skl_watermark.c  | 38 ++++++++++++++++---
>  5 files changed, 48 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index afa78774eaeb..54ed36183ebe 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6455,6 +6455,10 @@ int intel_atomic_check(struct drm_device *dev,
>                       return ret;
>       }
> 
> +     ret = intel_compute_global_watermarks_late(state);
> +     if (ret)
> +             goto fail;
> +
>       ret = intel_pmdemand_atomic_check(state);
>       if (ret)
>               goto fail;
> diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h
> b/drivers/gpu/drm/i915/display/intel_display_core.h
> index df4da52cbdb3..62bd894a72f9 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> @@ -89,6 +89,7 @@ struct intel_wm_funcs {
>       void (*optimize_watermarks)(struct intel_atomic_state *state,
>                                   struct intel_crtc *crtc);
>       int (*compute_global_watermarks)(struct intel_atomic_state *state);
> +     int (*compute_global_watermarks_late)(struct intel_atomic_state
> +*state);
>       void (*get_hw_state)(struct intel_display *display);
>       void (*sanitize)(struct intel_display *display);  }; diff --git
> a/drivers/gpu/drm/i915/display/intel_wm.c
> b/drivers/gpu/drm/i915/display/intel_wm.c
> index f887a664fe22..3035d9879d83 100644
> --- a/drivers/gpu/drm/i915/display/intel_wm.c
> +++ b/drivers/gpu/drm/i915/display/intel_wm.c
> @@ -104,6 +104,16 @@ int intel_compute_global_watermarks(struct
> intel_atomic_state *state)
>       return 0;
>  }
> 
> +int intel_compute_global_watermarks_late(struct intel_atomic_state
> +*state) {
> +     struct intel_display *display = to_intel_display(state);
> +
> +     if (display->funcs.wm->compute_global_watermarks_late)
> +             return display->funcs.wm-
> >compute_global_watermarks_late(state);
> +
> +     return 0;
> +}
> +
>  void intel_wm_get_hw_state(struct intel_display *display)  {
>       if (display->funcs.wm->get_hw_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_wm.h
> b/drivers/gpu/drm/i915/display/intel_wm.h
> index 9ad4e9eae5ca..9f69dc5dfda5 100644
> --- a/drivers/gpu/drm/i915/display/intel_wm.h
> +++ b/drivers/gpu/drm/i915/display/intel_wm.h
> @@ -24,6 +24,7 @@ void intel_atomic_update_watermarks(struct
> intel_atomic_state *state,  void intel_optimize_watermarks(struct
> intel_atomic_state *state,
>                              struct intel_crtc *crtc);
>  int intel_compute_global_watermarks(struct intel_atomic_state *state);
> +int intel_compute_global_watermarks_late(struct intel_atomic_state
> +*state);
>  void intel_wm_get_hw_state(struct intel_display *display);  void
> intel_wm_sanitize(struct intel_display *display);  bool
> intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, diff --git
> a/drivers/gpu/drm/i915/display/skl_watermark.c
> b/drivers/gpu/drm/i915/display/skl_watermark.c
> index aac3ca8f6c0f..5c18fe9a5237 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -2433,7 +2433,7 @@ static int skl_build_pipe_wm(struct intel_atomic_state
> *state,
> 
>       crtc_state->wm.skl.optimal = crtc_state->wm.skl.raw;
> 
> -     return skl_wm_check_vblank(crtc_state);
> +     return 0;
>  }
> 
>  static bool skl_wm_level_equals(const struct skl_wm_level *l1, @@ -3002,11
> +3002,6 @@ skl_compute_wm(struct intel_atomic_state *state)
>       if (ret)
>               return ret;
> 
> -     /*
> -      * skl_compute_ddb() will have adjusted the final watermarks
> -      * based on how much ddb is available. Now we can actually
> -      * check if the final watermarks changed.
> -      */
>       for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
>               struct skl_pipe_wm *pipe_wm = &new_crtc_state-
> >wm.skl.optimal;
> 
> @@ -3030,6 +3025,36 @@ skl_compute_wm(struct intel_atomic_state *state)
>               pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(display) &&
>                       DISPLAY_VER(display) >= 12 &&
>                       intel_crtc_can_enable_sagv(new_crtc_state);
> +     }
> +
> +     return 0;
> +}
> +
> +static int
> +skl_compute_wm_late(struct intel_atomic_state *state) {
> +     struct intel_crtc *crtc;
> +     struct intel_crtc_state __maybe_unused *new_crtc_state;
> +     int i;
> +
> +     for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> +             int ret;
> +
> +             /*
> +              * FIXME we need something along the lins of the following 
> order:
> +              * 1. intel_atomic_setup_scalers() (needed by
> skl_wm_check_vblank())
> +              * 2. intel_modeset_calc_cdclk() (needed by
> skl_wm_check_vblank())
> +              * 3. skl_compute_wm() (skl_wm_check_vblank() + update
> use_sagv_wm)
> +              * 4. intel_bw_atomic_check() (needs use_sagv_wm)
> +              * but shuffling all that needs a lot more work...
> +              *
> +              * For now hack it by deferreing skl_wm_check_vblank() until
> +              * intel_modeset_calc_cdclk() has been done. Scalers are still
> +              * completely broken wrt. skl_wm_check_vblank().
> +              */
> +             ret = skl_wm_check_vblank(new_crtc_state);
> +             if (ret)
> +                     return ret;
> 
>               ret = skl_wm_add_affected_planes(state, crtc);
>               if (ret)
> @@ -4060,6 +4085,7 @@ void intel_wm_state_verify(struct intel_atomic_state
> *state,
> 
>  static const struct intel_wm_funcs skl_wm_funcs = {
>       .compute_global_watermarks = skl_compute_wm,
> +     .compute_global_watermarks_late = skl_compute_wm_late,
>       .get_hw_state = skl_wm_get_hw_state,
>       .sanitize = skl_wm_sanitize,
>  };
> --
> 2.49.1

Reply via email to