aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Syrjälä <[email protected]>2023-09-07 15:25:41 +0300
committerVille Syrjälä <[email protected]>2023-11-08 19:20:20 +0200
commitc610e841f19d57233062868f2408349e9ecade91 (patch)
tree2b92920f6eabfcc77c879ebc6ce604036aa9c8f7
parentc39c93578106f035218078c300db6361cf6a326c (diff)
drm/i915: Do plane/etc. updates more atomically across pipes
Perform all the intel_pre_update_crtc() stuff for all pipes first, and only then do the intel_update_crtc() vblank evasion stuff for every pipe back to back. This should make it more likely that the plane updates from multiple pipes happen on the same frame (assuming the pipes are running in sync, eg. due to bigjoiner or port sync). Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Stanislav Lisovskiy <[email protected]>
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index bedd338ee9be..3effafcbb411 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6936,6 +6936,12 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
intel_enable_crtc(state, crtc);
intel_pre_update_crtc(state, crtc);
+ }
+
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ if (!new_crtc_state->hw.active)
+ continue;
+
intel_update_crtc(state, crtc);
}
}
@@ -6973,6 +6979,15 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
* So first lets enable all pipes that do not need a fullmodeset as
* those don't have any external dependency.
*/
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ enum pipe pipe = crtc->pipe;
+
+ if ((update_pipes & BIT(pipe)) == 0)
+ continue;
+
+ intel_pre_update_crtc(state, crtc);
+ }
+
while (update_pipes) {
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
@@ -6988,7 +7003,6 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
entries[pipe] = new_crtc_state->wm.skl.ddb;
update_pipes &= ~BIT(pipe);
- intel_pre_update_crtc(state, crtc);
intel_update_crtc(state, crtc);
/*
@@ -7050,13 +7064,21 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
if ((update_pipes & BIT(pipe)) == 0)
continue;
+ intel_pre_update_crtc(state, crtc);
+ }
+
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+ enum pipe pipe = crtc->pipe;
+
+ if ((update_pipes & BIT(pipe)) == 0)
+ continue;
+
drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
entries, I915_MAX_PIPES, pipe));
entries[pipe] = new_crtc_state->wm.skl.ddb;
update_pipes &= ~BIT(pipe);
- intel_pre_update_crtc(state, crtc);
intel_update_crtc(state, crtc);
}