@@ -14183,9 +14183,18 @@ intel_prepare_plane_fb(struct drm_plane *plane,
int ret;
if (plane->state->fb && old_plane_needs_modeset(plane, new_state)) {
+ struct intel_crtc *crtc = to_intel_crtc(plane->state->crtc);
struct drm_i915_gem_object *old_obj =
intel_fb_obj(plane->state->fb);
+ /* Queue this update after a previous old-school overlay flip */
+ if (crtc->overlay) {
+ ret = intel_overlay_await(crtc->overlay,
+ &intel_state->commit_ready);
+ if (ret)
+ return ret;
+ }
+
/* Big Hammer, we also need to ensure that any pending
* MI_WAIT_FOR_EVENT inside a user batch buffer on the
* current scanout is retired before unpinning the old
@@ -1566,6 +1566,8 @@ void intel_attach_aspect_ratio_property(struct drm_connector *connector);
/* intel_overlay.c */
void intel_setup_overlay(struct drm_i915_private *dev_priv);
void intel_cleanup_overlay(struct drm_i915_private *dev_priv);
+int intel_overlay_await(struct intel_overlay *overlay,
+ struct i915_sw_fence *fence);
int intel_overlay_switch_off(struct intel_overlay *overlay);
int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
@@ -855,6 +855,25 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
return ret;
}
+int intel_overlay_await(struct intel_overlay *overlay,
+ struct i915_sw_fence *fence)
+{
+ struct drm_i915_gem_request *request;
+ int err;
+
+ request = i915_gem_active_peek(&overlay->last_flip,
+ &overlay->i915->drm.struct_mutex);
+ if (!request)
+ return 0;
+
+ err = i915_sw_fence_await_dma_fence(fence,
+ &request->fence, 0, GFP_KERNEL);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
int intel_overlay_switch_off(struct intel_overlay *overlay)
{
struct drm_i915_private *dev_priv = overlay->i915;
Treat the overlay as another wait-source, just like other rendering to the fb, and asynchronously wait upon it before doing an atomic modeset. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- This is half the solution, it should prevent the wait before disabling the overlay, but we still need to remove the wait from inside intel_overlay_off() itself, preferably by switching to mmio instead of CS here. --- drivers/gpu/drm/i915/intel_display.c | 9 +++++++++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_overlay.c | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+)