11e12ee3bSFrançois Tigeot /*
21e12ee3bSFrançois Tigeot * i915_sw_fence.h - library routines for N:M synchronisation points
31e12ee3bSFrançois Tigeot *
41e12ee3bSFrançois Tigeot * Copyright (C) 2016 Intel Corporation
51e12ee3bSFrançois Tigeot *
61e12ee3bSFrançois Tigeot * This file is released under the GPLv2.
71e12ee3bSFrançois Tigeot *
81e12ee3bSFrançois Tigeot */
91e12ee3bSFrançois Tigeot
101e12ee3bSFrançois Tigeot #ifndef _I915_SW_FENCE_H_
111e12ee3bSFrançois Tigeot #define _I915_SW_FENCE_H_
121e12ee3bSFrançois Tigeot
131e12ee3bSFrançois Tigeot #include <linux/gfp.h>
141e12ee3bSFrançois Tigeot #include <linux/kref.h>
151e12ee3bSFrançois Tigeot #include <linux/notifier.h> /* for NOTIFY_DONE */
161e12ee3bSFrançois Tigeot #include <linux/wait.h>
171e12ee3bSFrançois Tigeot
181e12ee3bSFrançois Tigeot struct completion;
196559babbSFrançois Tigeot struct dma_fence;
206559babbSFrançois Tigeot struct dma_fence_ops;
211e12ee3bSFrançois Tigeot struct reservation_object;
221e12ee3bSFrançois Tigeot
231e12ee3bSFrançois Tigeot struct i915_sw_fence {
241e12ee3bSFrançois Tigeot wait_queue_head_t wait;
251e12ee3bSFrançois Tigeot unsigned long flags;
261e12ee3bSFrançois Tigeot atomic_t pending;
271e12ee3bSFrançois Tigeot };
281e12ee3bSFrançois Tigeot
291e12ee3bSFrançois Tigeot #define I915_SW_FENCE_CHECKED_BIT 0 /* used internally for DAG checking */
301e12ee3bSFrançois Tigeot #define I915_SW_FENCE_PRIVATE_BIT 1 /* available for use by owner */
311e12ee3bSFrançois Tigeot #define I915_SW_FENCE_MASK (~3)
321e12ee3bSFrançois Tigeot
331e12ee3bSFrançois Tigeot enum i915_sw_fence_notify {
341e12ee3bSFrançois Tigeot FENCE_COMPLETE,
351e12ee3bSFrançois Tigeot FENCE_FREE
361e12ee3bSFrançois Tigeot };
371e12ee3bSFrançois Tigeot
381e12ee3bSFrançois Tigeot typedef int (*i915_sw_fence_notify_t)(struct i915_sw_fence *,
391e12ee3bSFrançois Tigeot enum i915_sw_fence_notify state);
401e12ee3bSFrançois Tigeot #define __i915_sw_fence_call __aligned(4)
411e12ee3bSFrançois Tigeot
424be47400SFrançois Tigeot void __i915_sw_fence_init(struct i915_sw_fence *fence,
434be47400SFrançois Tigeot i915_sw_fence_notify_t fn,
444be47400SFrançois Tigeot const char *name,
454be47400SFrançois Tigeot struct lock_class_key *key);
464be47400SFrançois Tigeot #ifdef CONFIG_LOCKDEP
474be47400SFrançois Tigeot #define i915_sw_fence_init(fence, fn) \
484be47400SFrançois Tigeot do { \
494be47400SFrançois Tigeot static struct lock_class_key __key; \
504be47400SFrançois Tigeot \
514be47400SFrançois Tigeot __i915_sw_fence_init((fence), (fn), #fence, &__key); \
524be47400SFrançois Tigeot } while (0)
534be47400SFrançois Tigeot #else
544be47400SFrançois Tigeot #define i915_sw_fence_init(fence, fn) \
554be47400SFrançois Tigeot __i915_sw_fence_init((fence), (fn), NULL, NULL)
564be47400SFrançois Tigeot #endif
574be47400SFrançois Tigeot
58a85cb24fSFrançois Tigeot #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
59a85cb24fSFrançois Tigeot void i915_sw_fence_fini(struct i915_sw_fence *fence);
60a85cb24fSFrançois Tigeot #else
i915_sw_fence_fini(struct i915_sw_fence * fence)61a85cb24fSFrançois Tigeot static inline void i915_sw_fence_fini(struct i915_sw_fence *fence) {}
62a85cb24fSFrançois Tigeot #endif
63a85cb24fSFrançois Tigeot
641e12ee3bSFrançois Tigeot void i915_sw_fence_commit(struct i915_sw_fence *fence);
651e12ee3bSFrançois Tigeot
661e12ee3bSFrançois Tigeot int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
671e12ee3bSFrançois Tigeot struct i915_sw_fence *after,
68*3f2dd94aSFrançois Tigeot wait_queue_entry_t *wq);
694be47400SFrançois Tigeot int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
704be47400SFrançois Tigeot struct i915_sw_fence *after,
714be47400SFrançois Tigeot gfp_t gfp);
721e12ee3bSFrançois Tigeot int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
736559babbSFrançois Tigeot struct dma_fence *dma,
741e12ee3bSFrançois Tigeot unsigned long timeout,
751e12ee3bSFrançois Tigeot gfp_t gfp);
761e12ee3bSFrançois Tigeot int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
771e12ee3bSFrançois Tigeot struct reservation_object *resv,
786559babbSFrançois Tigeot const struct dma_fence_ops *exclude,
791e12ee3bSFrançois Tigeot bool write,
801e12ee3bSFrançois Tigeot unsigned long timeout,
811e12ee3bSFrançois Tigeot gfp_t gfp);
821e12ee3bSFrançois Tigeot
i915_sw_fence_signaled(const struct i915_sw_fence * fence)834be47400SFrançois Tigeot static inline bool i915_sw_fence_signaled(const struct i915_sw_fence *fence)
844be47400SFrançois Tigeot {
854be47400SFrançois Tigeot return atomic_read(&fence->pending) <= 0;
864be47400SFrançois Tigeot }
874be47400SFrançois Tigeot
i915_sw_fence_done(const struct i915_sw_fence * fence)884be47400SFrançois Tigeot static inline bool i915_sw_fence_done(const struct i915_sw_fence *fence)
891e12ee3bSFrançois Tigeot {
901e12ee3bSFrançois Tigeot return atomic_read(&fence->pending) < 0;
911e12ee3bSFrançois Tigeot }
921e12ee3bSFrançois Tigeot
i915_sw_fence_wait(struct i915_sw_fence * fence)934be47400SFrançois Tigeot static inline void i915_sw_fence_wait(struct i915_sw_fence *fence)
944be47400SFrançois Tigeot {
954be47400SFrançois Tigeot wait_event(fence->wait, i915_sw_fence_done(fence));
964be47400SFrançois Tigeot }
974be47400SFrançois Tigeot
981e12ee3bSFrançois Tigeot #endif /* _I915_SW_FENCE_H_ */
99