> -----Original Message-----
> From: Intel-xe <[email protected]> On Behalf Of Ville 
> Syrjala
> Sent: Monday, 13 October 2025 23.13
> To: [email protected]
> Cc: [email protected]
> Subject: [PATCH 5/9] drm/i915/fbc: Decouple FBC from 
> intel_cdclk_atomic_check()
> 
> From: Ville Syrjälä <[email protected]>
> 
> Always account for FBC requirements in intel_crtc_compute_min_cdclk() so that 
> we don't to worry about the actual CDCLK
> frequency in
> intel_fbc_check_plane() any longer.
> 

Reviewed-by: Mika Kahola <[email protected]>

> Signed-off-by: Ville Syrjälä <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_cdclk.c |  1 +
>  drivers/gpu/drm/i915/display/intel_fbc.c   | 49 ++++++++++++++++------
>  drivers/gpu/drm/i915/display/intel_fbc.h   |  1 +
>  3 files changed, 38 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
> b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index 80a6c98eea5d..d55b3dc23356 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -2838,6 +2838,7 @@ static int intel_crtc_compute_min_cdclk(const struct 
> intel_crtc_state *crtc_stat
> 
>       min_cdclk = intel_pixel_rate_to_cdclk(crtc_state);
>       min_cdclk = max(min_cdclk, intel_crtc_bw_min_cdclk(crtc_state));
> +     min_cdclk = max(min_cdclk, intel_fbc_min_cdclk(crtc_state));
>       min_cdclk = max(min_cdclk, hsw_ips_min_cdclk(crtc_state));
>       min_cdclk = max(min_cdclk, intel_audio_min_cdclk(crtc_state));
>       min_cdclk = max(min_cdclk, vlv_dsi_min_cdclk(crtc_state)); diff --git 
> a/drivers/gpu/drm/i915/display/intel_fbc.c
> b/drivers/gpu/drm/i915/display/intel_fbc.c
> index 4edb4342833e..90060c60c5f4 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.c
> @@ -53,7 +53,6 @@
>  #include "i915_vgpu.h"
>  #include "i915_vma.h"
>  #include "i9xx_plane_regs.h"
> -#include "intel_cdclk.h"
>  #include "intel_de.h"
>  #include "intel_display_device.h"
>  #include "intel_display_regs.h"
> @@ -1417,6 +1416,18 @@ intel_fbc_prepare_dirty_rect(struct intel_atomic_state 
> *state,
>       }
>  }
> 
> +static int _intel_fbc_min_cdclk(const struct intel_crtc_state
> +*crtc_state) {
> +     struct intel_display *display = to_intel_display(crtc_state);
> +
> +     /* WaFbcExceedCdClockThreshold:hsw,bdw */
> +     if (display->platform.haswell || display->platform.broadwell)
> +             return DIV_ROUND_UP(crtc_state->pixel_rate * 100, 95);
> +
> +     /* no FBC specific limits to worry about */
> +     return 0;
> +}
> +
>  static int intel_fbc_check_plane(struct intel_atomic_state *state,
>                                struct intel_plane *plane)
>  {
> @@ -1556,18 +1567,9 @@ static int intel_fbc_check_plane(struct 
> intel_atomic_state *state,
>               return 0;
>       }
> 
> -     /* WaFbcExceedCdClockThreshold:hsw,bdw */
> -     if (display->platform.haswell || display->platform.broadwell) {
> -             const struct intel_cdclk_state *cdclk_state;
> -
> -             cdclk_state = intel_atomic_get_cdclk_state(state);
> -             if (IS_ERR(cdclk_state))
> -                     return PTR_ERR(cdclk_state);
> -
> -             if (crtc_state->pixel_rate >= intel_cdclk_logical(cdclk_state) 
> * 95 / 100) {
> -                     plane_state->no_fbc_reason = "pixel rate too high";
> -                     return 0;
> -             }
> +     if (_intel_fbc_min_cdclk(crtc_state) > display->cdclk.max_cdclk_freq) {
> +             plane_state->no_fbc_reason = "pixel rate too high";
> +             return 0;
>       }
> 
>       plane_state->no_fbc_reason = NULL;
> @@ -1575,6 +1577,27 @@ static int intel_fbc_check_plane(struct 
> intel_atomic_state *state,
>       return 0;
>  }
> 
> +int intel_fbc_min_cdclk(const struct intel_crtc_state *crtc_state) {
> +     struct intel_display *display = to_intel_display(crtc_state);
> +     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +     struct intel_plane *plane = to_intel_plane(crtc->base.primary);
> +     int min_cdclk;
> +
> +     if (!plane->fbc)
> +             return 0;
> +
> +     min_cdclk = _intel_fbc_min_cdclk(crtc_state);
> +
> +     /*
> +      * Do not ask for more than the max CDCLK frequency,
> +      * if that is not enough FBC will simply not be used.
> +      */
> +     if (min_cdclk > display->cdclk.max_cdclk_freq)
> +             return 0;
> +
> +     return min_cdclk;
> +}
> 
>  static bool intel_fbc_can_flip_nuke(struct intel_atomic_state *state,
>                                   struct intel_crtc *crtc,
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h 
> b/drivers/gpu/drm/i915/display/intel_fbc.h
> index 0e715cb6b4e6..c86562404a00 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.h
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.h
> @@ -28,6 +28,7 @@ enum intel_fbc_id {
>  };
> 
>  int intel_fbc_atomic_check(struct intel_atomic_state *state);
> +int intel_fbc_min_cdclk(const struct intel_crtc_state *crtc_state);
>  bool intel_fbc_pre_update(struct intel_atomic_state *state,
>                         struct intel_crtc *crtc);
>  void intel_fbc_post_update(struct intel_atomic_state *state,
> --
> 2.49.1

Reply via email to