drm/i915: Commit skl+ planes in an order that avoids ddb overlaps
skl+ can go belly up if there are overlapping ddb allocations between
planes. If we could absolutely guarantee that we can perform the atomic
update within a single frame we shouldn't have to worry about this. But
we can't rely on that so let's steal the ddb overlap check trick from
skl_update_crtcs() and apply it to the plane updates. Since each step
of the sequence is free from ddb overlaps we don't have to worry about
a vblank sneaking up on us in the middle of the sequence. The partial
state that gets latched by the hardware will be safe. And unlike
skl_update_crtcs() we don't have to intoduce any extra vblank waits
on account of only having to worry about a single pipe.
v2: Fix typo in commit msg (Matt)
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181114210729.16185-12-ville.syrjala@linux.intel.com
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6c5d71b..d07fa44 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12692,7 +12692,6 @@ static void intel_update_crtc(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_crtc_state *old_intel_cstate = to_intel_crtc_state(old_crtc_state);
struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state);
bool modeset = needs_modeset(new_crtc_state);
struct intel_plane_state *new_plane_state =
@@ -12715,8 +12714,10 @@ static void intel_update_crtc(struct drm_crtc *crtc,
intel_begin_crtc_commit(crtc, old_crtc_state);
- intel_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc,
- old_intel_cstate, pipe_config);
+ if (INTEL_GEN(dev_priv) >= 9)
+ skl_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc);
+ else
+ i9xx_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc);
intel_finish_crtc_commit(crtc, old_crtc_state);
}