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