From: Ville Syrjälä Date: Tue, 23 Sep 2025 17:19:32 +0000 (+0300) Subject: drm/i915/cdclk: Extract intel_cdclk_update_crtc_min_cdclk() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=25b0657e7fe849897bb28831860a50c7ab6ad707;p=thirdparty%2Fkernel%2Flinux.git drm/i915/cdclk: Extract intel_cdclk_update_crtc_min_cdclk() Hide the cdclk state details better by providing a helper (intel_cdclk_update_crtc_min_cdclk()) by which the crtc code can inform the cdclk code about a new per-pipe min_cdclk value. Note that this is currently being called once per-plane, but it'll be changed to be just a single call for the whole pipe later. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250923171943.7319-11-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola --- diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index c1f00bb7b8d34..5eae148e114b1 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2837,6 +2837,36 @@ static int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_stat return min_cdclk; } +int intel_cdclk_update_crtc_min_cdclk(struct intel_atomic_state *state, + struct intel_crtc *crtc, + int old_min_cdclk, int new_min_cdclk, + bool *need_cdclk_calc) +{ + struct intel_display *display = to_intel_display(state); + struct intel_cdclk_state *cdclk_state; + + if (new_min_cdclk <= old_min_cdclk) + return 0; + + cdclk_state = intel_atomic_get_cdclk_state(state); + if (IS_ERR(cdclk_state)) + return PTR_ERR(cdclk_state); + + old_min_cdclk = cdclk_state->min_cdclk[crtc->pipe]; + + if (new_min_cdclk <= old_min_cdclk) + return 0; + + *need_cdclk_calc = true; + + drm_dbg_kms(display->drm, + "[CRTC:%d:%s] min cdclk: %d kHz -> %d kHz\n", + crtc->base.base.id, crtc->base.name, + old_min_cdclk, new_min_cdclk); + + return 0; +} + int intel_cdclk_update_bw_min_cdclk(struct intel_atomic_state *state, int old_min_cdclk, int new_min_cdclk, bool *need_cdclk_calc) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index 0e67c75ca569f..25d45c8f059d9 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -51,6 +51,10 @@ void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc); int intel_cdclk_update_bw_min_cdclk(struct intel_atomic_state *state, int old_min_cdclk, int new_min_cdclk, bool *need_cdclk_calc); +int intel_cdclk_update_crtc_min_cdclk(struct intel_atomic_state *state, + struct intel_crtc *crtc, + int old_min_cdclk, int new_min_cdclk, + bool *need_cdclk_calc); #define to_intel_cdclk_state(global_state) \ container_of_const((global_state), struct intel_cdclk_state, base) diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index 19d4640c0e539..aceac2ef28a87 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -295,13 +295,12 @@ int intel_plane_calc_min_cdclk(struct intel_atomic_state *state, struct intel_plane *plane, bool *need_cdclk_calc) { - struct intel_display *display = to_intel_display(plane); const struct intel_plane_state *plane_state = intel_atomic_get_new_plane_state(state, plane); struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc); - const struct intel_cdclk_state *cdclk_state; const struct intel_crtc_state *old_crtc_state; struct intel_crtc_state *new_crtc_state; + int ret; if (!plane_state->uapi.visible || !plane->min_cdclk) return 0; @@ -312,41 +311,12 @@ int intel_plane_calc_min_cdclk(struct intel_atomic_state *state, new_crtc_state->min_cdclk[plane->id] = plane->min_cdclk(new_crtc_state, plane_state); - /* - * No need to check against the cdclk state if - * the min cdclk for the plane doesn't increase. - * - * Ie. we only ever increase the cdclk due to plane - * requirements. This can reduce back and forth - * display blinking due to constant cdclk changes. - */ - if (new_crtc_state->min_cdclk[plane->id] <= - old_crtc_state->min_cdclk[plane->id]) - return 0; - - cdclk_state = intel_atomic_get_cdclk_state(state); - if (IS_ERR(cdclk_state)) - return PTR_ERR(cdclk_state); - - /* - * No need to recalculate the cdclk state if - * the min cdclk for the pipe doesn't increase. - * - * Ie. we only ever increase the cdclk due to plane - * requirements. This can reduce back and forth - * display blinking due to constant cdclk changes. - */ - if (new_crtc_state->min_cdclk[plane->id] <= - intel_cdclk_min_cdclk(cdclk_state, crtc->pipe)) - return 0; - - drm_dbg_kms(display->drm, - "[PLANE:%d:%s] min cdclk (%d kHz) > [CRTC:%d:%s] min cdclk (%d kHz)\n", - plane->base.base.id, plane->base.name, - new_crtc_state->min_cdclk[plane->id], - crtc->base.base.id, crtc->base.name, - intel_cdclk_min_cdclk(cdclk_state, crtc->pipe)); - *need_cdclk_calc = true; + ret = intel_cdclk_update_crtc_min_cdclk(state, crtc, + old_crtc_state->min_cdclk[plane->id], + new_crtc_state->min_cdclk[plane->id], + need_cdclk_calc); + if (ret) + return ret; return 0; }