diff options
author | Thomas Zimmermann <tzimmermann@suse.de> | 2023-10-11 09:50:59 +0200 |
---|---|---|
committer | Thomas Zimmermann <tzimmermann@suse.de> | 2023-10-11 09:50:59 +0200 |
commit | 57390019b68b83f96eb98f490367b9df1f2d77cb (patch) | |
tree | e6d4b6c75efdd2d7fb7d37f980688c491be3ff6a /drivers/gpu/drm/i915/display/intel_frontbuffer.c | |
parent | e5f9d543419c78ac58f3b3557bc5a76b20ff600b (diff) | |
parent | 389af786f92ecdff35883551d54bf4e507ffcccb (diff) | |
download | linux-57390019b68b83f96eb98f490367b9df1f2d77cb.tar.gz linux-57390019b68b83f96eb98f490367b9df1f2d77cb.tar.bz2 linux-57390019b68b83f96eb98f490367b9df1f2d77cb.zip |
Merge drm/drm-next into drm-misc-next
Updating drm-misc-next to the state of Linux v6.6-rc2.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_frontbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_frontbuffer.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 17a7aa8b28c2..412a19a888a2 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -55,6 +55,7 @@ * cancelled as soon as busyness is detected. */ +#include "gem/i915_gem_object_frontbuffer.h" #include "i915_drv.h" #include "intel_display_trace.h" #include "intel_display_types.h" @@ -167,7 +168,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front, enum fb_op_origin origin, unsigned int frontbuffer_bits) { - struct drm_i915_private *i915 = to_i915(front->obj->base.dev); + struct drm_i915_private *i915 = intel_bo_to_i915(front->obj); if (origin == ORIGIN_CS) { spin_lock(&i915->display.fb_tracking.lock); @@ -188,7 +189,7 @@ void __intel_fb_flush(struct intel_frontbuffer *front, enum fb_op_origin origin, unsigned int frontbuffer_bits) { - struct drm_i915_private *i915 = to_i915(front->obj->base.dev); + struct drm_i915_private *i915 = intel_bo_to_i915(front->obj); if (origin == ORIGIN_CS) { spin_lock(&i915->display.fb_tracking.lock); @@ -202,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 = @@ -221,24 +249,19 @@ static void frontbuffer_retire(struct i915_active *ref) } static void frontbuffer_release(struct kref *ref) - __releases(&to_i915(front->obj->base.dev)->display.fb_tracking.lock) + __releases(&intel_bo_to_i915(front->obj)->display.fb_tracking.lock) { - struct intel_frontbuffer *front = + struct intel_frontbuffer *ret, *front = container_of(ref, typeof(*front), ref); struct drm_i915_gem_object *obj = front->obj; - struct i915_vma *vma; - drm_WARN_ON(obj->base.dev, atomic_read(&front->bits)); + drm_WARN_ON(&intel_bo_to_i915(obj)->drm, atomic_read(&front->bits)); - spin_lock(&obj->vma.lock); - for_each_ggtt_vma(vma, obj) { - i915_vma_clear_scanout(vma); - vma->display_alignment = I915_GTT_MIN_ALIGNMENT; - } - spin_unlock(&obj->vma.lock); + i915_ggtt_clear_scanout(obj); - RCU_INIT_POINTER(obj->frontbuffer, NULL); - spin_unlock(&to_i915(obj->base.dev)->display.fb_tracking.lock); + ret = i915_gem_object_set_frontbuffer(obj, NULL); + drm_WARN_ON(&intel_bo_to_i915(obj)->drm, ret); + spin_unlock(&intel_bo_to_i915(obj)->display.fb_tracking.lock); i915_active_fini(&front->write); @@ -249,10 +272,10 @@ static void frontbuffer_release(struct kref *ref) struct intel_frontbuffer * intel_frontbuffer_get(struct drm_i915_gem_object *obj) { - struct drm_i915_private *i915 = to_i915(obj->base.dev); - struct intel_frontbuffer *front; + struct drm_i915_private *i915 = intel_bo_to_i915(obj); + struct intel_frontbuffer *front, *cur; - front = __intel_frontbuffer_get(obj); + front = i915_gem_object_get_frontbuffer(obj); if (front) return front; @@ -267,26 +290,21 @@ 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); - if (rcu_access_pointer(obj->frontbuffer)) { - kfree(front); - front = rcu_dereference_protected(obj->frontbuffer, true); - kref_get(&front->ref); - } else { - i915_gem_object_get(obj); - rcu_assign_pointer(obj->frontbuffer, front); - } + cur = i915_gem_object_set_frontbuffer(obj, front); spin_unlock(&i915->display.fb_tracking.lock); - - return front; + if (cur != front) + kfree(front); + return cur; } void intel_frontbuffer_put(struct intel_frontbuffer *front) { kref_put_lock(&front->ref, frontbuffer_release, - &to_i915(front->obj->base.dev)->display.fb_tracking.lock); + &intel_bo_to_i915(front->obj)->display.fb_tracking.lock); } /** @@ -315,13 +333,13 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old, BUILD_BUG_ON(I915_MAX_PLANES > INTEL_FRONTBUFFER_BITS_PER_PIPE); if (old) { - drm_WARN_ON(old->obj->base.dev, + drm_WARN_ON(&intel_bo_to_i915(old->obj)->drm, !(atomic_read(&old->bits) & frontbuffer_bits)); atomic_andnot(frontbuffer_bits, &old->bits); } if (new) { - drm_WARN_ON(new->obj->base.dev, + drm_WARN_ON(&intel_bo_to_i915(new->obj)->drm, atomic_read(&new->bits) & frontbuffer_bits); atomic_or(frontbuffer_bits, &new->bits); } |