We need to be able to update dbuf min tracker and mdclk ratio separately if mbus_join state didn't change, so lets add one degree of freedom and make it possible. Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@xxxxxxxxx> --- drivers/gpu/drm/i915/display/skl_watermark.c | 55 ++++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 8ff69da664807..2b947870527fc 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3570,16 +3570,38 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915, u8 ratio DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1)); } +static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state) +{ + struct drm_i915_private *i915 = to_i915(state->base.dev); + const struct intel_dbuf_state *old_dbuf_state = + intel_atomic_get_old_dbuf_state(state); + const struct intel_dbuf_state *new_dbuf_state = + intel_atomic_get_new_dbuf_state(state); + + if (DISPLAY_VER(i915) >= 20 && + old_dbuf_state->mdclk_cdclk_ratio != new_dbuf_state->mdclk_cdclk_ratio) { + /* + * For Xe2LPD and beyond, when there is a change in the ratio + * between MDCLK and CDCLK, updates to related registers need to + * happen at a specific point in the CDCLK change sequence. In + * that case, we defer to the call to + * intel_dbuf_mdclk_cdclk_ratio_update() to the CDCLK logic. + */ + return; + } + + intel_dbuf_mdclk_cdclk_ratio_update(i915, new_dbuf_state->mdclk_cdclk_ratio, + new_dbuf_state->joined_mbus); +} + /* * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state before * update the request state of all DBUS slices. */ -static void intel_dbuf_mbus_update(struct intel_atomic_state *state) +static void intel_dbuf_mbus_join_update(struct intel_atomic_state *state) { struct drm_i915_private *i915 = to_i915(state->base.dev); u32 mbus_ctl; - const struct intel_dbuf_state *old_dbuf_state = - intel_atomic_get_old_dbuf_state(state); const struct intel_dbuf_state *new_dbuf_state = intel_atomic_get_new_dbuf_state(state); @@ -3600,21 +3622,6 @@ static void intel_dbuf_mbus_update(struct intel_atomic_state *state) intel_de_rmw(i915, MBUS_CTL, MBUS_HASHING_MODE_MASK | MBUS_JOIN | MBUS_JOIN_PIPE_SELECT_MASK, mbus_ctl); - - if (DISPLAY_VER(i915) >= 20 && - old_dbuf_state->mdclk_cdclk_ratio != new_dbuf_state->mdclk_cdclk_ratio) { - /* - * For Xe2LPD and beyond, when there is a change in the ratio - * between MDCLK and CDCLK, updates to related registers need to - * happen at a specific point in the CDCLK change sequence. In - * that case, we defer to the call to - * intel_dbuf_mdclk_cdclk_ratio_update() to the CDCLK logic. - */ - return; - } - - intel_dbuf_mdclk_cdclk_ratio_update(i915, new_dbuf_state->mdclk_cdclk_ratio, - new_dbuf_state->joined_mbus); } void intel_dbuf_pre_plane_update(struct intel_atomic_state *state) @@ -3632,8 +3639,10 @@ void intel_dbuf_pre_plane_update(struct intel_atomic_state *state) WARN_ON(!new_dbuf_state->base.changed); - if (!old_dbuf_state->joined_mbus && new_dbuf_state->joined_mbus) - intel_dbuf_mbus_update(state); + if (!old_dbuf_state->joined_mbus && new_dbuf_state->joined_mbus) { + intel_dbuf_mbus_join_update(state); + intel_dbuf_mdclk_min_tracker_update(state); + } gen9_dbuf_slices_update(i915, old_dbuf_state->enabled_slices | @@ -3655,8 +3664,10 @@ void intel_dbuf_post_plane_update(struct intel_atomic_state *state) WARN_ON(!new_dbuf_state->base.changed); - if (old_dbuf_state->joined_mbus && !new_dbuf_state->joined_mbus) - intel_dbuf_mbus_update(state); + if (old_dbuf_state->joined_mbus && !new_dbuf_state->joined_mbus) { + intel_dbuf_mbus_join_update(state); + intel_dbuf_mdclk_min_tracker_update(state); + } gen9_dbuf_slices_update(i915, new_dbuf_state->enabled_slices); -- 2.37.3