1 /* Public domain. */ 2 3 #ifndef _LINUX_DMA_FENCE_H 4 #define _LINUX_DMA_FENCE_H 5 6 #include <sys/types.h> 7 #include <sys/mutex.h> 8 #include <linux/kref.h> 9 #include <linux/list.h> 10 #include <linux/sched.h> 11 #include <linux/rcupdate.h> 12 13 #define DMA_FENCE_TRACE(fence, fmt, args...) do {} while(0) 14 15 struct dma_fence { 16 struct kref refcount; 17 const struct dma_fence_ops *ops; 18 unsigned long flags; 19 uint64_t context; 20 uint64_t seqno; 21 struct mutex *lock; 22 union { 23 struct list_head cb_list; 24 ktime_t timestamp; 25 struct rcu_head rcu; 26 }; 27 int error; 28 }; 29 30 enum dma_fence_flag_bits { 31 DMA_FENCE_FLAG_SIGNALED_BIT, 32 DMA_FENCE_FLAG_TIMESTAMP_BIT, 33 DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, 34 DMA_FENCE_FLAG_USER_BITS, 35 }; 36 37 struct dma_fence_ops { 38 const char * (*get_driver_name)(struct dma_fence *); 39 const char * (*get_timeline_name)(struct dma_fence *); 40 bool (*enable_signaling)(struct dma_fence *); 41 bool (*signaled)(struct dma_fence *); 42 long (*wait)(struct dma_fence *, bool, long); 43 void (*release)(struct dma_fence *); 44 void (*set_deadline)(struct dma_fence *, ktime_t); 45 bool use_64bit_seqno; 46 }; 47 48 struct dma_fence_cb; 49 typedef void (*dma_fence_func_t)(struct dma_fence *fence, struct dma_fence_cb *cb); 50 51 struct dma_fence_cb { 52 struct list_head node; 53 dma_fence_func_t func; 54 }; 55 56 uint64_t dma_fence_context_alloc(unsigned int); 57 struct dma_fence *dma_fence_get(struct dma_fence *); 58 struct dma_fence *dma_fence_get_rcu(struct dma_fence *); 59 struct dma_fence *dma_fence_get_rcu_safe(struct dma_fence **); 60 void dma_fence_release(struct kref *); 61 void dma_fence_put(struct dma_fence *); 62 int dma_fence_signal(struct dma_fence *); 63 int dma_fence_signal_locked(struct dma_fence *); 64 int dma_fence_signal_timestamp(struct dma_fence *, ktime_t); 65 int dma_fence_signal_timestamp_locked(struct dma_fence *, ktime_t); 66 bool dma_fence_is_signaled(struct dma_fence *); 67 bool dma_fence_is_signaled_locked(struct dma_fence *); 68 ktime_t dma_fence_timestamp(struct dma_fence *); 69 long dma_fence_default_wait(struct dma_fence *, bool, long); 70 long dma_fence_wait_any_timeout(struct dma_fence **, uint32_t, bool, long, 71 uint32_t *); 72 long dma_fence_wait_timeout(struct dma_fence *, bool, long); 73 long dma_fence_wait(struct dma_fence *, bool); 74 void dma_fence_enable_sw_signaling(struct dma_fence *); 75 void dma_fence_init(struct dma_fence *, const struct dma_fence_ops *, 76 struct mutex *, uint64_t, uint64_t); 77 int dma_fence_add_callback(struct dma_fence *, struct dma_fence_cb *, 78 dma_fence_func_t); 79 bool dma_fence_remove_callback(struct dma_fence *, struct dma_fence_cb *); 80 bool dma_fence_is_container(struct dma_fence *); 81 void dma_fence_set_deadline(struct dma_fence *, ktime_t); 82 83 struct dma_fence *dma_fence_get_stub(void); 84 struct dma_fence *dma_fence_allocate_private_stub(ktime_t); 85 86 static inline void 87 dma_fence_free(struct dma_fence *fence) 88 { 89 free(fence, M_DRM, 0); 90 } 91 92 /* 93 * is a later than b 94 * if a and b are the same, should return false to avoid unwanted work 95 */ 96 static inline bool 97 __dma_fence_is_later(uint64_t a, uint64_t b, const struct dma_fence_ops *ops) 98 { 99 uint32_t al, bl; 100 101 if (ops->use_64bit_seqno) 102 return a > b; 103 104 al = a & 0xffffffff; 105 bl = b & 0xffffffff; 106 107 return (int)(al - bl) > 0; 108 } 109 110 static inline bool 111 dma_fence_is_later(struct dma_fence *a, struct dma_fence *b) 112 { 113 if (a->context != b->context) 114 return false; 115 return __dma_fence_is_later(a->seqno, b->seqno, a->ops); 116 } 117 118 static inline bool 119 dma_fence_is_later_or_same(struct dma_fence *a, struct dma_fence *b) 120 { 121 if (a == b) 122 return true; 123 return dma_fence_is_later(a, b); 124 } 125 126 static inline void 127 dma_fence_set_error(struct dma_fence *fence, int error) 128 { 129 fence->error = error; 130 } 131 132 static inline bool 133 dma_fence_begin_signalling(void) 134 { 135 return true; 136 } 137 138 static inline void 139 dma_fence_end_signalling(bool x) 140 { 141 } 142 143 #endif 144