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@xxxxxxxxxxxxxxxxxx> --- 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(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bfcd368ebf6f..6c51b0f2a96e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -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 diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5c521065dc3b..87fd544339d9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -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); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 79f93e7d699d..476a25961f34 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -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; -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx