Home | History | Annotate | Line # | Download | only in i915
      1 /*	$NetBSD: i915_sw_fence.h,v 1.6 2021/12/19 11:36:08 riastradh Exp $	*/
      2 
      3 /*
      4  * SPDX-License-Identifier: MIT
      5  *
      6  * i915_sw_fence.h - library routines for N:M synchronisation points
      7  *
      8  * Copyright (C) 2016 Intel Corporation
      9  */
     10 
     11 #ifndef _I915_SW_FENCE_H_
     12 #define _I915_SW_FENCE_H_
     13 
     14 #include <linux/dma-fence.h>
     15 #include <linux/gfp.h>
     16 #include <linux/kref.h>
     17 #include <linux/notifier.h> /* for NOTIFY_DONE */
     18 #include <linux/wait.h>
     19 
     20 struct completion;
     21 struct dma_resv;
     22 
     23 struct i915_sw_fence_waiter {
     24 	struct list_head entry;
     25 	int flags;
     26 	int (*func)(struct i915_sw_fence_waiter *, unsigned, int, void *);
     27 	void *private;
     28 };
     29 
     30 struct i915_sw_fence {
     31 	struct i915_sw_fence_queue {
     32 		spinlock_t lock;
     33 		struct list_head head;
     34 	} wait;
     35 	unsigned long flags;
     36 	atomic_t pending;
     37 	int error;
     38 };
     39 
     40 #define I915_SW_FENCE_CHECKED_BIT	0 /* used internally for DAG checking */
     41 #define I915_SW_FENCE_PRIVATE_BIT	1 /* available for use by owner */
     42 #define I915_SW_FENCE_MASK		(~3)
     43 
     44 enum i915_sw_fence_notify {
     45 	FENCE_COMPLETE,
     46 	FENCE_FREE
     47 };
     48 
     49 typedef int (*i915_sw_fence_notify_t)(struct i915_sw_fence *,
     50 				      enum i915_sw_fence_notify state);
     51 #define __i915_sw_fence_call __aligned(4)
     52 
     53 void __i915_sw_fence_init(struct i915_sw_fence *fence,
     54 			  i915_sw_fence_notify_t fn,
     55 			  const char *name,
     56 			  struct lock_class_key *key);
     57 #if IS_ENABLED(CONFIG_LOCKDEP)
     58 #define i915_sw_fence_init(fence, fn)				\
     59 do {								\
     60 	static struct lock_class_key __key;			\
     61 								\
     62 	__i915_sw_fence_init((fence), (fn), #fence, &__key);	\
     63 } while (0)
     64 #else
     65 #define i915_sw_fence_init(fence, fn)				\
     66 	__i915_sw_fence_init((fence), (fn), NULL, NULL)
     67 #endif
     68 
     69 void i915_sw_fence_reinit(struct i915_sw_fence *fence);
     70 
     71 void i915_sw_fence_fini(struct i915_sw_fence *fence);
     72 
     73 void i915_sw_fence_commit(struct i915_sw_fence *fence);
     74 
     75 #ifdef __NetBSD__
     76 int i915_sw_fence_await_sw_fence(struct i915_sw_fence *,
     77 				 struct i915_sw_fence *,
     78 				 struct i915_sw_fence_waiter *);
     79 #else
     80 int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
     81 				 struct i915_sw_fence *after,
     82 				 wait_queue_entry_t *wq);
     83 #endif
     84 int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
     85 				     struct i915_sw_fence *after,
     86 				     gfp_t gfp);
     87 
     88 struct i915_sw_dma_fence_cb {
     89 	struct dma_fence_cb base;
     90 	struct i915_sw_fence *fence;
     91 };
     92 
     93 int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
     94 				    struct dma_fence *dma,
     95 				    struct i915_sw_dma_fence_cb *cb);
     96 int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
     97 				  struct dma_fence *dma,
     98 				  unsigned long timeout,
     99 				  gfp_t gfp);
    100 
    101 int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
    102 				    struct dma_resv *resv,
    103 				    const struct dma_fence_ops *exclude,
    104 				    bool write,
    105 				    unsigned long timeout,
    106 				    gfp_t gfp);
    107 
    108 void i915_sw_fence_await(struct i915_sw_fence *fence);
    109 void i915_sw_fence_complete(struct i915_sw_fence *fence);
    110 
    111 static inline bool i915_sw_fence_signaled(const struct i915_sw_fence *fence)
    112 {
    113 	return atomic_read(&fence->pending) <= 0;
    114 }
    115 
    116 static inline bool i915_sw_fence_done(const struct i915_sw_fence *fence)
    117 {
    118 	return atomic_read(&fence->pending) < 0;
    119 }
    120 
    121 #ifdef __NetBSD__
    122 void i915_sw_fence_wait(struct i915_sw_fence *);
    123 #else
    124 static inline void i915_sw_fence_wait(struct i915_sw_fence *fence)
    125 {
    126 	wait_event(fence->wait, i915_sw_fence_done(fence));
    127 }
    128 #endif
    129 
    130 static inline void
    131 i915_sw_fence_set_error_once(struct i915_sw_fence *fence, int error)
    132 {
    133 	if (unlikely(error))
    134 		cmpxchg(&fence->error, 0, error);
    135 }
    136 
    137 #endif /* _I915_SW_FENCE_H_ */
    138