From: Ville Syrjälä <[email protected]> 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ä <[email protected]> --- drivers/gpu/drm/i915/display/intel_cdclk.c | 30 +++++++++++++++ drivers/gpu/drm/i915/display/intel_cdclk.h | 4 ++ drivers/gpu/drm/i915/display/intel_plane.c | 44 ++++------------------ 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 3257f1f4fc11..aa5793326b0c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2836,6 +2836,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 0e67c75ca569..25d45c8f059d 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 2329f09d413d..864e2db207fa 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -296,13 +296,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; @@ -313,41 +312,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; } -- 2.49.1
