aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_frontbuffer.c
diff options
context:
space:
mode:
authorJouni Högander <jouni.hogander@intel.com>2023-09-01 12:34:59 +0300
committerJouni Högander <jouni.hogander@intel.com>2023-09-04 12:04:07 +0300
commit40320844ca8bda4def0f04d2bd8c2022c867ed86 (patch)
tree6aea1d5b78848f8b8334e40f2985444dce2633ee /drivers/gpu/drm/i915/display/intel_frontbuffer.c
parent35a97f56d6ccf1870e666fb6efa12a7ec201b9e4 (diff)
drm/i915: Add new frontbuffer tracking interface to queue flush
We want to wait dma fences in dirtyfb ioctl. As we don't want to make dirtyfb ioctl as blocking call we need to use dma_fence_add_callback. Callback used for dma_fence_add_callback is called from atomic context. Due to this we need to add a new frontbuffer tracking interface to queue flush. v3: - Check schedule work success rather than work being pending - Init flush work when frontbuffer struct is initialized v2: Check if flush work is already pending Signed-off-by: Jouni Högander <jouni.hogander@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230901093500.3463046-4-jouni.hogander@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_frontbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_frontbuffer.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index 54ddb69eca66..d5540c739404 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -203,6 +203,33 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
frontbuffer_flush(i915, frontbuffer_bits, origin);
}
+static void intel_frontbuffer_flush_work(struct work_struct *work)
+{
+ struct intel_frontbuffer *front =
+ container_of(work, struct intel_frontbuffer, flush_work);
+
+ i915_gem_object_flush_if_display(front->obj);
+ intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
+ intel_frontbuffer_put(front);
+}
+
+/**
+ * intel_frontbuffer_queue_flush - queue flushing frontbuffer object
+ * @front: GEM object to flush
+ *
+ * This function is targeted for our dirty callback for queueing flush when
+ * dma fence is signales
+ */
+void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front)
+{
+ if (!front)
+ return;
+
+ kref_get(&front->ref);
+ if (!schedule_work(&front->flush_work))
+ intel_frontbuffer_put(front);
+}
+
static int frontbuffer_active(struct i915_active *ref)
{
struct intel_frontbuffer *front =
@@ -262,6 +289,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj)
frontbuffer_active,
frontbuffer_retire,
I915_ACTIVE_RETIRE_SLEEPS);
+ INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work);
spin_lock(&i915->display.fb_tracking.lock);
cur = i915_gem_object_set_frontbuffer(obj, front);