1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2012-2018 Rob Clark <robclark@freedesktop.org>
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci * Authors:
24bf215546Sopenharmony_ci *    Rob Clark <robclark@freedesktop.org>
25bf215546Sopenharmony_ci */
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#ifndef FREEDRENO_DRMIF_H_
28bf215546Sopenharmony_ci#define FREEDRENO_DRMIF_H_
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include <stdint.h>
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "util/bitset.h"
33bf215546Sopenharmony_ci#include "util/u_debug.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci#ifdef __cplusplus
36bf215546Sopenharmony_ciextern "C" {
37bf215546Sopenharmony_ci#endif
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_cistruct fd_bo;
40bf215546Sopenharmony_cistruct fd_pipe;
41bf215546Sopenharmony_cistruct fd_device;
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_cienum fd_pipe_id {
44bf215546Sopenharmony_ci   FD_PIPE_3D = 1,
45bf215546Sopenharmony_ci   FD_PIPE_2D = 2,
46bf215546Sopenharmony_ci   /* some devices have two 2d blocks.. not really sure how to
47bf215546Sopenharmony_ci    * use that yet, so just ignoring the 2nd 2d pipe for now
48bf215546Sopenharmony_ci    */
49bf215546Sopenharmony_ci   FD_PIPE_MAX
50bf215546Sopenharmony_ci};
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_cienum fd_param_id {
53bf215546Sopenharmony_ci   FD_DEVICE_ID,
54bf215546Sopenharmony_ci   FD_GMEM_SIZE,
55bf215546Sopenharmony_ci   FD_GMEM_BASE,     /* 64b */
56bf215546Sopenharmony_ci   FD_GPU_ID,
57bf215546Sopenharmony_ci   FD_CHIP_ID,       /* 64b */
58bf215546Sopenharmony_ci   FD_MAX_FREQ,
59bf215546Sopenharmony_ci   FD_TIMESTAMP,
60bf215546Sopenharmony_ci   FD_NR_RINGS,      /* # of rings == # of distinct priority levels */
61bf215546Sopenharmony_ci   FD_CTX_FAULTS,    /* # of per context faults */
62bf215546Sopenharmony_ci   FD_GLOBAL_FAULTS, /* # of global (all context) faults */
63bf215546Sopenharmony_ci   FD_SUSPEND_COUNT, /* # of times the GPU has suspended, and potentially lost state */
64bf215546Sopenharmony_ci   FD_SYSPROF,       /* Settable (for CAP_SYS_ADMIN) param for system profiling */
65bf215546Sopenharmony_ci};
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ci/**
68bf215546Sopenharmony_ci * Helper for fence/seqno comparisions which deals properly with rollover.
69bf215546Sopenharmony_ci * Returns true if fence 'a' is before fence 'b'
70bf215546Sopenharmony_ci */
71bf215546Sopenharmony_cistatic inline bool
72bf215546Sopenharmony_cifd_fence_before(uint32_t a, uint32_t b)
73bf215546Sopenharmony_ci{
74bf215546Sopenharmony_ci   return (int32_t)(a - b) < 0;
75bf215546Sopenharmony_ci}
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_cistatic inline bool
78bf215546Sopenharmony_cifd_fence_after(uint32_t a, uint32_t b)
79bf215546Sopenharmony_ci{
80bf215546Sopenharmony_ci   return (int32_t)(a - b) > 0;
81bf215546Sopenharmony_ci}
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci/**
84bf215546Sopenharmony_ci * Per submit, there are actually two fences:
85bf215546Sopenharmony_ci *  1) The userspace maintained fence, which is used to optimistically
86bf215546Sopenharmony_ci *     avoid kernel ioctls to query if specific rendering is completed
87bf215546Sopenharmony_ci *  2) The kernel maintained fence, which we cannot directly do anything
88bf215546Sopenharmony_ci *     with, other than pass it back to the kernel
89bf215546Sopenharmony_ci *
90bf215546Sopenharmony_ci * The userspace fence is mostly internal to the drm layer, but we want
91bf215546Sopenharmony_ci * the gallium layer to be able to pass it back to us for things like
92bf215546Sopenharmony_ci * fd_pipe_wait().  So this struct encapsulates the two.
93bf215546Sopenharmony_ci */
94bf215546Sopenharmony_cistruct fd_fence {
95bf215546Sopenharmony_ci   uint32_t kfence;     /* kernel fence */
96bf215546Sopenharmony_ci   uint32_t ufence;     /* userspace fence */
97bf215546Sopenharmony_ci};
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci/* bo flags: */
100bf215546Sopenharmony_ci#define FD_BO_GPUREADONLY         BITSET_BIT(1)
101bf215546Sopenharmony_ci#define FD_BO_SCANOUT             BITSET_BIT(2)
102bf215546Sopenharmony_ci/* Default caching is WRITECOMBINE: */
103bf215546Sopenharmony_ci#define FD_BO_CACHED_COHERENT     BITSET_BIT(3)
104bf215546Sopenharmony_ci/* Hint that the bo will not be mmap'd: */
105bf215546Sopenharmony_ci#define FD_BO_NOMAP               BITSET_BIT(4)
106bf215546Sopenharmony_ci/* Hint that the bo will be exported/shared: */
107bf215546Sopenharmony_ci#define FD_BO_SHARED              BITSET_BIT(5)
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci/* backend private bo flags: */
110bf215546Sopenharmony_ci#define _FD_BO_VIRTIO_SHM         BITSET_BIT(6)
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci/* bo access flags: (keep aligned to MSM_PREP_x) */
113bf215546Sopenharmony_ci#define FD_BO_PREP_READ   BITSET_BIT(0)
114bf215546Sopenharmony_ci#define FD_BO_PREP_WRITE  BITSET_BIT(1)
115bf215546Sopenharmony_ci#define FD_BO_PREP_NOSYNC BITSET_BIT(2)
116bf215546Sopenharmony_ci#define FD_BO_PREP_FLUSH  BITSET_BIT(3)
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci/* device functions:
120bf215546Sopenharmony_ci */
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_cistruct fd_device *fd_device_new(int fd);
123bf215546Sopenharmony_cistruct fd_device *fd_device_new_dup(int fd);
124bf215546Sopenharmony_cistruct fd_device *fd_device_open(void);
125bf215546Sopenharmony_cistruct fd_device *fd_device_ref(struct fd_device *dev);
126bf215546Sopenharmony_civoid fd_device_purge(struct fd_device *dev);
127bf215546Sopenharmony_civoid fd_device_del(struct fd_device *dev);
128bf215546Sopenharmony_ciint fd_device_fd(struct fd_device *dev);
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_cienum fd_version {
131bf215546Sopenharmony_ci   FD_VERSION_MADVISE = 1,             /* kernel supports madvise */
132bf215546Sopenharmony_ci   FD_VERSION_UNLIMITED_CMDS = 1,      /* submits w/ >4 cmd buffers (growable ringbuffer) */
133bf215546Sopenharmony_ci   FD_VERSION_FENCE_FD = 2,            /* submit command supports in/out fences */
134bf215546Sopenharmony_ci   FD_VERSION_GMEM_BASE = 3,           /* supports querying GMEM base address */
135bf215546Sopenharmony_ci   FD_VERSION_SUBMIT_QUEUES = 3,       /* submit queues and multiple priority levels */
136bf215546Sopenharmony_ci   FD_VERSION_BO_IOVA = 3,             /* supports fd_bo_get/put_iova() */
137bf215546Sopenharmony_ci   FD_VERSION_SOFTPIN = 4,             /* adds softpin, bo name, and dump flag */
138bf215546Sopenharmony_ci   FD_VERSION_ROBUSTNESS = 5,          /* adds FD_NR_FAULTS and FD_PP_PGTABLE */
139bf215546Sopenharmony_ci   FD_VERSION_MEMORY_FD = 2,           /* supports shared memory objects */
140bf215546Sopenharmony_ci   FD_VERSION_SUSPENDS = 7,            /* Adds MSM_PARAM_SUSPENDS to detect device suspend */
141bf215546Sopenharmony_ci   FD_VERSION_CACHED_COHERENT = 8,     /* Adds cached-coherent support (a6xx+) */
142bf215546Sopenharmony_ci};
143bf215546Sopenharmony_cienum fd_version fd_device_version(struct fd_device *dev);
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_cibool fd_has_syncobj(struct fd_device *dev);
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci/* pipe functions:
148bf215546Sopenharmony_ci */
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_cistruct fd_pipe *fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id);
151bf215546Sopenharmony_cistruct fd_pipe *fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id,
152bf215546Sopenharmony_ci                             uint32_t prio);
153bf215546Sopenharmony_cistruct fd_pipe *fd_pipe_ref(struct fd_pipe *pipe);
154bf215546Sopenharmony_cistruct fd_pipe *fd_pipe_ref_locked(struct fd_pipe *pipe);
155bf215546Sopenharmony_civoid fd_pipe_del(struct fd_pipe *pipe);
156bf215546Sopenharmony_civoid fd_pipe_purge(struct fd_pipe *pipe);
157bf215546Sopenharmony_ciconst struct fd_dev_id * fd_pipe_dev_id(struct fd_pipe *pipe);
158bf215546Sopenharmony_ciint fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
159bf215546Sopenharmony_ci                      uint64_t *value);
160bf215546Sopenharmony_ciint fd_pipe_set_param(struct fd_pipe *pipe, enum fd_param_id param,
161bf215546Sopenharmony_ci                      uint64_t value);
162bf215546Sopenharmony_ciint fd_pipe_wait(struct fd_pipe *pipe, const struct fd_fence *fence);
163bf215546Sopenharmony_ci/* timeout in nanosec */
164bf215546Sopenharmony_ciint fd_pipe_wait_timeout(struct fd_pipe *pipe, const struct fd_fence *fence,
165bf215546Sopenharmony_ci                         uint64_t timeout);
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci/* buffer-object functions:
168bf215546Sopenharmony_ci */
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_cistruct fd_bo *_fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags);
171bf215546Sopenharmony_civoid _fd_bo_set_name(struct fd_bo *bo, const char *fmt, va_list ap);
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_cistatic inline void fd_bo_set_name(struct fd_bo *bo, const char *fmt, ...)
174bf215546Sopenharmony_ci   _util_printf_format(2, 3);
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_cistatic inline void
177bf215546Sopenharmony_cifd_bo_set_name(struct fd_bo *bo, const char *fmt, ...)
178bf215546Sopenharmony_ci{
179bf215546Sopenharmony_ci#ifndef NDEBUG
180bf215546Sopenharmony_ci   va_list ap;
181bf215546Sopenharmony_ci   va_start(ap, fmt);
182bf215546Sopenharmony_ci   _fd_bo_set_name(bo, fmt, ap);
183bf215546Sopenharmony_ci   va_end(ap);
184bf215546Sopenharmony_ci#endif
185bf215546Sopenharmony_ci}
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_cistatic inline struct fd_bo *fd_bo_new(struct fd_device *dev, uint32_t size,
188bf215546Sopenharmony_ci                                      uint32_t flags, const char *fmt, ...)
189bf215546Sopenharmony_ci   _util_printf_format(4, 5);
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_cistatic inline struct fd_bo *
192bf215546Sopenharmony_cifd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags, const char *fmt,
193bf215546Sopenharmony_ci          ...)
194bf215546Sopenharmony_ci{
195bf215546Sopenharmony_ci   struct fd_bo *bo = _fd_bo_new(dev, size, flags);
196bf215546Sopenharmony_ci#ifndef NDEBUG
197bf215546Sopenharmony_ci   if (fmt) {
198bf215546Sopenharmony_ci      va_list ap;
199bf215546Sopenharmony_ci      va_start(ap, fmt);
200bf215546Sopenharmony_ci      _fd_bo_set_name(bo, fmt, ap);
201bf215546Sopenharmony_ci      va_end(ap);
202bf215546Sopenharmony_ci   }
203bf215546Sopenharmony_ci#endif
204bf215546Sopenharmony_ci   return bo;
205bf215546Sopenharmony_ci}
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_cistruct fd_bo *fd_bo_from_handle(struct fd_device *dev, uint32_t handle,
208bf215546Sopenharmony_ci                                uint32_t size);
209bf215546Sopenharmony_cistruct fd_bo *fd_bo_from_name(struct fd_device *dev, uint32_t name);
210bf215546Sopenharmony_cistruct fd_bo *fd_bo_from_dmabuf(struct fd_device *dev, int fd);
211bf215546Sopenharmony_civoid fd_bo_mark_for_dump(struct fd_bo *bo);
212bf215546Sopenharmony_ciuint64_t fd_bo_get_iova(struct fd_bo *bo);
213bf215546Sopenharmony_cistruct fd_bo *fd_bo_ref(struct fd_bo *bo);
214bf215546Sopenharmony_civoid fd_bo_del(struct fd_bo *bo);
215bf215546Sopenharmony_ciint fd_bo_get_name(struct fd_bo *bo, uint32_t *name);
216bf215546Sopenharmony_ciuint32_t fd_bo_handle(struct fd_bo *bo);
217bf215546Sopenharmony_ciint fd_bo_dmabuf(struct fd_bo *bo);
218bf215546Sopenharmony_ciuint32_t fd_bo_size(struct fd_bo *bo);
219bf215546Sopenharmony_civoid *fd_bo_map(struct fd_bo *bo);
220bf215546Sopenharmony_civoid fd_bo_upload(struct fd_bo *bo, void *src, unsigned len);
221bf215546Sopenharmony_ciint fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op);
222bf215546Sopenharmony_civoid fd_bo_cpu_fini(struct fd_bo *bo);
223bf215546Sopenharmony_cibool fd_bo_is_cached(struct fd_bo *bo);
224bf215546Sopenharmony_ci
225bf215546Sopenharmony_ci#ifdef __cplusplus
226bf215546Sopenharmony_ci} /* end of extern "C" */
227bf215546Sopenharmony_ci#endif
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci#endif /* FREEDRENO_DRMIF_H_ */
230