diff mbox series

[13/15] drm/i915: Properly write lock bw_state when it changes

Message ID 20220118092354.11631-14-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: Fix bandwith related cdclk calculations | expand

Commit Message

Ville Syrjälä Jan. 18, 2022, 9:23 a.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The current code also forgets to call intel_atomic_lock_global_state()
when other stuff besides the final min_cdlck changes in the state.
That means we may throw away data which actually has changed, and
thus we can't be at all sure what the code ends up doing during
subsequent commits. Do the write lock properly.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index b0cdad89c1ba..b1f6cf178678 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -676,6 +676,28 @@  intel_atomic_get_bw_state(struct intel_atomic_state *state)
 	return to_intel_bw_state(bw_state);
 }
 
+static bool intel_bw_state_changed(struct drm_i915_private *i915,
+				   const struct intel_bw_state *old_bw_state,
+				   const struct intel_bw_state *new_bw_state)
+{
+	enum pipe pipe;
+
+	for_each_pipe(i915, pipe) {
+		const struct intel_dbuf_bw *old_crtc_bw =
+			&old_bw_state->dbuf_bw[pipe];
+		const struct intel_dbuf_bw *new_crtc_bw =
+			&new_bw_state->dbuf_bw[pipe];
+		enum dbuf_slice slice;
+
+		for_each_dbuf_slice(i915, slice) {
+			if (old_crtc_bw->used_bw[slice] != new_crtc_bw->used_bw[slice])
+				return true;
+		}
+	}
+
+	return old_bw_state->min_cdclk != new_bw_state->min_cdclk;
+}
+
 static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state,
 				  const struct intel_crtc_state *crtc_state)
 {
@@ -763,7 +785,7 @@  int intel_bw_calc_min_cdclk(struct intel_atomic_state *state)
 
 	new_bw_state->min_cdclk = DIV_ROUND_UP(max_bw, 64);
 
-	if (new_bw_state->min_cdclk != old_bw_state->min_cdclk) {
+	if (intel_bw_state_changed(dev_priv, old_bw_state, new_bw_state)) {
 		int ret = intel_atomic_lock_global_state(&new_bw_state->base);
 
 		if (ret)