xref: /aosp_15_r20/external/mesa3d/src/nouveau/winsys/nouveau_bo.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker #include "nouveau_bo.h"
2*61046927SAndroid Build Coastguard Worker 
3*61046927SAndroid Build Coastguard Worker #include "drm-uapi/nouveau_drm.h"
4*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
5*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
6*61046927SAndroid Build Coastguard Worker 
7*61046927SAndroid Build Coastguard Worker #include <errno.h>
8*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
9*61046927SAndroid Build Coastguard Worker #include <stddef.h>
10*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
11*61046927SAndroid Build Coastguard Worker #include <xf86drm.h>
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include "nvidia/classes/cl9097.h"
14*61046927SAndroid Build Coastguard Worker #include "nvidia/classes/clc597.h"
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker void
nouveau_ws_bo_unbind_vma(struct nouveau_ws_device * dev,uint64_t offset,uint64_t range)17*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_unbind_vma(struct nouveau_ws_device *dev,
18*61046927SAndroid Build Coastguard Worker                          uint64_t offset, uint64_t range)
19*61046927SAndroid Build Coastguard Worker {
20*61046927SAndroid Build Coastguard Worker    assert(dev->has_vm_bind);
21*61046927SAndroid Build Coastguard Worker 
22*61046927SAndroid Build Coastguard Worker    struct drm_nouveau_vm_bind_op newbindop = {
23*61046927SAndroid Build Coastguard Worker       .op = DRM_NOUVEAU_VM_BIND_OP_UNMAP,
24*61046927SAndroid Build Coastguard Worker       .addr = offset,
25*61046927SAndroid Build Coastguard Worker       .range = range,
26*61046927SAndroid Build Coastguard Worker    };
27*61046927SAndroid Build Coastguard Worker    struct drm_nouveau_vm_bind vmbind = {
28*61046927SAndroid Build Coastguard Worker       .op_count = 1,
29*61046927SAndroid Build Coastguard Worker       .op_ptr = (uint64_t)(uintptr_t)(void *)&newbindop,
30*61046927SAndroid Build Coastguard Worker    };
31*61046927SAndroid Build Coastguard Worker    ASSERTED int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_VM_BIND,
32*61046927SAndroid Build Coastguard Worker                                           &vmbind, sizeof(vmbind));
33*61046927SAndroid Build Coastguard Worker    assert(ret == 0);
34*61046927SAndroid Build Coastguard Worker }
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker void
nouveau_ws_bo_bind_vma(struct nouveau_ws_device * dev,struct nouveau_ws_bo * bo,uint64_t addr,uint64_t range,uint64_t bo_offset,uint32_t pte_kind)37*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_bind_vma(struct nouveau_ws_device *dev,
38*61046927SAndroid Build Coastguard Worker                        struct nouveau_ws_bo *bo,
39*61046927SAndroid Build Coastguard Worker                        uint64_t addr,
40*61046927SAndroid Build Coastguard Worker                        uint64_t range,
41*61046927SAndroid Build Coastguard Worker                        uint64_t bo_offset,
42*61046927SAndroid Build Coastguard Worker                        uint32_t pte_kind)
43*61046927SAndroid Build Coastguard Worker {
44*61046927SAndroid Build Coastguard Worker    assert(dev->has_vm_bind);
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker    struct drm_nouveau_vm_bind_op newbindop = {
47*61046927SAndroid Build Coastguard Worker       .op = DRM_NOUVEAU_VM_BIND_OP_MAP,
48*61046927SAndroid Build Coastguard Worker       .handle = bo->handle,
49*61046927SAndroid Build Coastguard Worker       .addr = addr,
50*61046927SAndroid Build Coastguard Worker       .range = range,
51*61046927SAndroid Build Coastguard Worker       .bo_offset = bo_offset,
52*61046927SAndroid Build Coastguard Worker       .flags = pte_kind,
53*61046927SAndroid Build Coastguard Worker    };
54*61046927SAndroid Build Coastguard Worker    struct drm_nouveau_vm_bind vmbind = {
55*61046927SAndroid Build Coastguard Worker       .op_count = 1,
56*61046927SAndroid Build Coastguard Worker       .op_ptr = (uint64_t)(uintptr_t)(void *)&newbindop,
57*61046927SAndroid Build Coastguard Worker    };
58*61046927SAndroid Build Coastguard Worker    ASSERTED int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_VM_BIND,
59*61046927SAndroid Build Coastguard Worker                                           &vmbind, sizeof(vmbind));
60*61046927SAndroid Build Coastguard Worker    assert(ret == 0);
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker struct nouveau_ws_bo *
nouveau_ws_bo_new_mapped(struct nouveau_ws_device * dev,uint64_t size,uint64_t align,enum nouveau_ws_bo_flags flags,enum nouveau_ws_bo_map_flags map_flags,void ** map_out)64*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_new_mapped(struct nouveau_ws_device *dev,
65*61046927SAndroid Build Coastguard Worker                          uint64_t size, uint64_t align,
66*61046927SAndroid Build Coastguard Worker                          enum nouveau_ws_bo_flags flags,
67*61046927SAndroid Build Coastguard Worker                          enum nouveau_ws_bo_map_flags map_flags,
68*61046927SAndroid Build Coastguard Worker                          void **map_out)
69*61046927SAndroid Build Coastguard Worker {
70*61046927SAndroid Build Coastguard Worker    struct nouveau_ws_bo *bo = nouveau_ws_bo_new(dev, size, align,
71*61046927SAndroid Build Coastguard Worker                                                 flags | NOUVEAU_WS_BO_MAP);
72*61046927SAndroid Build Coastguard Worker    if (!bo)
73*61046927SAndroid Build Coastguard Worker       return NULL;
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    void *map = nouveau_ws_bo_map(bo, map_flags);
76*61046927SAndroid Build Coastguard Worker    if (map == NULL) {
77*61046927SAndroid Build Coastguard Worker       nouveau_ws_bo_destroy(bo);
78*61046927SAndroid Build Coastguard Worker       return NULL;
79*61046927SAndroid Build Coastguard Worker    }
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker    *map_out = map;
82*61046927SAndroid Build Coastguard Worker    return bo;
83*61046927SAndroid Build Coastguard Worker }
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker static struct nouveau_ws_bo *
nouveau_ws_bo_new_tiled_locked(struct nouveau_ws_device * dev,uint64_t size,uint64_t align,uint8_t pte_kind,uint16_t tile_mode,enum nouveau_ws_bo_flags flags)86*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_new_tiled_locked(struct nouveau_ws_device *dev,
87*61046927SAndroid Build Coastguard Worker                                uint64_t size, uint64_t align,
88*61046927SAndroid Build Coastguard Worker                                uint8_t pte_kind, uint16_t tile_mode,
89*61046927SAndroid Build Coastguard Worker                                enum nouveau_ws_bo_flags flags)
90*61046927SAndroid Build Coastguard Worker {
91*61046927SAndroid Build Coastguard Worker    struct drm_nouveau_gem_new req = {};
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker    /* if the caller doesn't care, use the GPU page size */
94*61046927SAndroid Build Coastguard Worker    if (align == 0)
95*61046927SAndroid Build Coastguard Worker       align = 0x1000;
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker    /* Align the size */
98*61046927SAndroid Build Coastguard Worker    size = align64(size, align);
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker    req.info.domain = 0;
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    /* It needs to live somewhere */
103*61046927SAndroid Build Coastguard Worker    assert((flags & NOUVEAU_WS_BO_VRAM) || (flags & NOUVEAU_WS_BO_GART));
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    if (flags & NOUVEAU_WS_BO_VRAM)
106*61046927SAndroid Build Coastguard Worker       req.info.domain |= NOUVEAU_GEM_DOMAIN_VRAM;
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker    if (flags & NOUVEAU_WS_BO_GART)
109*61046927SAndroid Build Coastguard Worker       req.info.domain |= NOUVEAU_GEM_DOMAIN_GART;
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker    if (flags & NOUVEAU_WS_BO_MAP)
112*61046927SAndroid Build Coastguard Worker       req.info.domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    if (flags & NOUVEAU_WS_BO_NO_SHARE)
115*61046927SAndroid Build Coastguard Worker       req.info.domain |= NOUVEAU_GEM_DOMAIN_NO_SHARE;
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker    req.info.tile_flags = (uint32_t)pte_kind << 8;
118*61046927SAndroid Build Coastguard Worker    req.info.tile_mode = tile_mode;
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker    req.info.size = size;
121*61046927SAndroid Build Coastguard Worker    req.align = align;
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    int ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW, &req, sizeof(req));
124*61046927SAndroid Build Coastguard Worker    if (ret != 0)
125*61046927SAndroid Build Coastguard Worker       return NULL;
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker    struct nouveau_ws_bo *bo = CALLOC_STRUCT(nouveau_ws_bo);
128*61046927SAndroid Build Coastguard Worker    bo->size = size;
129*61046927SAndroid Build Coastguard Worker    bo->handle = req.info.handle;
130*61046927SAndroid Build Coastguard Worker    bo->map_handle = req.info.map_handle;
131*61046927SAndroid Build Coastguard Worker    bo->dev = dev;
132*61046927SAndroid Build Coastguard Worker    bo->flags = flags;
133*61046927SAndroid Build Coastguard Worker    bo->refcnt = 1;
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)bo->handle, bo);
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker    return bo;
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker 
140*61046927SAndroid Build Coastguard Worker struct nouveau_ws_bo *
nouveau_ws_bo_new_tiled(struct nouveau_ws_device * dev,uint64_t size,uint64_t align,uint8_t pte_kind,uint16_t tile_mode,enum nouveau_ws_bo_flags flags)141*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_new_tiled(struct nouveau_ws_device *dev,
142*61046927SAndroid Build Coastguard Worker                         uint64_t size, uint64_t align,
143*61046927SAndroid Build Coastguard Worker                         uint8_t pte_kind, uint16_t tile_mode,
144*61046927SAndroid Build Coastguard Worker                         enum nouveau_ws_bo_flags flags)
145*61046927SAndroid Build Coastguard Worker {
146*61046927SAndroid Build Coastguard Worker    struct nouveau_ws_bo *bo;
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&dev->bos_lock);
149*61046927SAndroid Build Coastguard Worker    bo = nouveau_ws_bo_new_tiled_locked(dev, size, align,
150*61046927SAndroid Build Coastguard Worker                                        pte_kind, tile_mode, flags);
151*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&dev->bos_lock);
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker    return bo;
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker struct nouveau_ws_bo *
nouveau_ws_bo_new(struct nouveau_ws_device * dev,uint64_t size,uint64_t align,enum nouveau_ws_bo_flags flags)157*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_new(struct nouveau_ws_device *dev,
158*61046927SAndroid Build Coastguard Worker                   uint64_t size, uint64_t align,
159*61046927SAndroid Build Coastguard Worker                   enum nouveau_ws_bo_flags flags)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker    return nouveau_ws_bo_new_tiled(dev, size, align, 0, 0, flags);
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker static struct nouveau_ws_bo *
nouveau_ws_bo_from_dma_buf_locked(struct nouveau_ws_device * dev,int fd)165*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_from_dma_buf_locked(struct nouveau_ws_device *dev, int fd)
166*61046927SAndroid Build Coastguard Worker {
167*61046927SAndroid Build Coastguard Worker    uint32_t handle;
168*61046927SAndroid Build Coastguard Worker    int ret = drmPrimeFDToHandle(dev->fd, fd, &handle);
169*61046927SAndroid Build Coastguard Worker    if (ret != 0)
170*61046927SAndroid Build Coastguard Worker       return NULL;
171*61046927SAndroid Build Coastguard Worker 
172*61046927SAndroid Build Coastguard Worker    struct hash_entry *entry =
173*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_search(dev->bos, (void *)(uintptr_t)handle);
174*61046927SAndroid Build Coastguard Worker    if (entry != NULL) {
175*61046927SAndroid Build Coastguard Worker       struct nouveau_ws_bo *bo = entry->data;
176*61046927SAndroid Build Coastguard Worker       nouveau_ws_bo_ref(bo);
177*61046927SAndroid Build Coastguard Worker       return bo;
178*61046927SAndroid Build Coastguard Worker    }
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    /*
181*61046927SAndroid Build Coastguard Worker     * If we got here, no BO exists for the retrieved handle. If we error
182*61046927SAndroid Build Coastguard Worker     * after this point, we need to close the handle.
183*61046927SAndroid Build Coastguard Worker     */
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker    struct drm_nouveau_gem_info info = {
186*61046927SAndroid Build Coastguard Worker       .handle = handle
187*61046927SAndroid Build Coastguard Worker    };
188*61046927SAndroid Build Coastguard Worker    ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO,
189*61046927SAndroid Build Coastguard Worker                              &info, sizeof(info));
190*61046927SAndroid Build Coastguard Worker    if (ret != 0)
191*61046927SAndroid Build Coastguard Worker       goto fail_fd_to_handle;
192*61046927SAndroid Build Coastguard Worker 
193*61046927SAndroid Build Coastguard Worker    enum nouveau_ws_bo_flags flags = 0;
194*61046927SAndroid Build Coastguard Worker    if (info.domain & NOUVEAU_GEM_DOMAIN_VRAM)
195*61046927SAndroid Build Coastguard Worker       flags |= NOUVEAU_WS_BO_VRAM;
196*61046927SAndroid Build Coastguard Worker    if (info.domain & NOUVEAU_GEM_DOMAIN_GART)
197*61046927SAndroid Build Coastguard Worker       flags |= NOUVEAU_WS_BO_GART;
198*61046927SAndroid Build Coastguard Worker    if (info.map_handle)
199*61046927SAndroid Build Coastguard Worker       flags |= NOUVEAU_WS_BO_MAP;
200*61046927SAndroid Build Coastguard Worker 
201*61046927SAndroid Build Coastguard Worker    struct nouveau_ws_bo *bo = CALLOC_STRUCT(nouveau_ws_bo);
202*61046927SAndroid Build Coastguard Worker    bo->size = info.size;
203*61046927SAndroid Build Coastguard Worker    bo->handle = info.handle;
204*61046927SAndroid Build Coastguard Worker    bo->map_handle = info.map_handle;
205*61046927SAndroid Build Coastguard Worker    bo->dev = dev;
206*61046927SAndroid Build Coastguard Worker    bo->flags = flags;
207*61046927SAndroid Build Coastguard Worker    bo->refcnt = 1;
208*61046927SAndroid Build Coastguard Worker 
209*61046927SAndroid Build Coastguard Worker    uint64_t align = (1ULL << 12);
210*61046927SAndroid Build Coastguard Worker    if (info.domain & NOUVEAU_GEM_DOMAIN_VRAM)
211*61046927SAndroid Build Coastguard Worker       align = (1ULL << 16);
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker    assert(bo->size == align64(bo->size, align));
214*61046927SAndroid Build Coastguard Worker 
215*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_insert(dev->bos, (void *)(uintptr_t)handle, bo);
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker    return bo;
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker fail_fd_to_handle:
220*61046927SAndroid Build Coastguard Worker    drmCloseBufferHandle(dev->fd, handle);
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker    return NULL;
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker struct nouveau_ws_bo *
nouveau_ws_bo_from_dma_buf(struct nouveau_ws_device * dev,int fd)226*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_from_dma_buf(struct nouveau_ws_device *dev, int fd)
227*61046927SAndroid Build Coastguard Worker {
228*61046927SAndroid Build Coastguard Worker    struct nouveau_ws_bo *bo;
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&dev->bos_lock);
231*61046927SAndroid Build Coastguard Worker    bo = nouveau_ws_bo_from_dma_buf_locked(dev, fd);
232*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&dev->bos_lock);
233*61046927SAndroid Build Coastguard Worker 
234*61046927SAndroid Build Coastguard Worker    return bo;
235*61046927SAndroid Build Coastguard Worker }
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker static bool
atomic_dec_not_one(atomic_uint_fast32_t * counter)238*61046927SAndroid Build Coastguard Worker atomic_dec_not_one(atomic_uint_fast32_t *counter)
239*61046927SAndroid Build Coastguard Worker {
240*61046927SAndroid Build Coastguard Worker    uint_fast32_t old = *counter;
241*61046927SAndroid Build Coastguard Worker    while (1) {
242*61046927SAndroid Build Coastguard Worker       assert(old != 0);
243*61046927SAndroid Build Coastguard Worker       if (old == 1)
244*61046927SAndroid Build Coastguard Worker          return false;
245*61046927SAndroid Build Coastguard Worker 
246*61046927SAndroid Build Coastguard Worker       if (atomic_compare_exchange_weak(counter, &old, old - 1))
247*61046927SAndroid Build Coastguard Worker          return true;
248*61046927SAndroid Build Coastguard Worker    }
249*61046927SAndroid Build Coastguard Worker }
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker void
nouveau_ws_bo_destroy(struct nouveau_ws_bo * bo)252*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo)
253*61046927SAndroid Build Coastguard Worker {
254*61046927SAndroid Build Coastguard Worker    if (atomic_dec_not_one(&bo->refcnt))
255*61046927SAndroid Build Coastguard Worker       return;
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker    struct nouveau_ws_device *dev = bo->dev;
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    /* Lock the device before we drop the final reference */
260*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&dev->bos_lock);
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker    if (--bo->refcnt == 0) {
263*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_remove_key(dev->bos, (void *)(uintptr_t)bo->handle);
264*61046927SAndroid Build Coastguard Worker 
265*61046927SAndroid Build Coastguard Worker       drmCloseBufferHandle(bo->dev->fd, bo->handle);
266*61046927SAndroid Build Coastguard Worker       FREE(bo);
267*61046927SAndroid Build Coastguard Worker    }
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&dev->bos_lock);
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker void *
nouveau_ws_bo_map(struct nouveau_ws_bo * bo,enum nouveau_ws_bo_map_flags flags)273*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_map(struct nouveau_ws_bo *bo,
274*61046927SAndroid Build Coastguard Worker                   enum nouveau_ws_bo_map_flags flags)
275*61046927SAndroid Build Coastguard Worker {
276*61046927SAndroid Build Coastguard Worker    int prot = 0;
277*61046927SAndroid Build Coastguard Worker    if (flags & NOUVEAU_WS_BO_RD)
278*61046927SAndroid Build Coastguard Worker       prot |= PROT_READ;
279*61046927SAndroid Build Coastguard Worker    if (flags & NOUVEAU_WS_BO_WR)
280*61046927SAndroid Build Coastguard Worker       prot |= PROT_WRITE;
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker    void *res = mmap(NULL, bo->size, prot, MAP_SHARED,
284*61046927SAndroid Build Coastguard Worker                     bo->dev->fd, bo->map_handle);
285*61046927SAndroid Build Coastguard Worker    if (res == MAP_FAILED)
286*61046927SAndroid Build Coastguard Worker       return NULL;
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    return res;
289*61046927SAndroid Build Coastguard Worker }
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker void
nouveau_ws_bo_unmap(struct nouveau_ws_bo * bo,void * ptr)292*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_unmap(struct nouveau_ws_bo *bo, void *ptr)
293*61046927SAndroid Build Coastguard Worker {
294*61046927SAndroid Build Coastguard Worker    munmap(ptr, bo->size);
295*61046927SAndroid Build Coastguard Worker }
296*61046927SAndroid Build Coastguard Worker 
297*61046927SAndroid Build Coastguard Worker bool
nouveau_ws_bo_wait(struct nouveau_ws_bo * bo,enum nouveau_ws_bo_map_flags flags)298*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_wait(struct nouveau_ws_bo *bo, enum nouveau_ws_bo_map_flags flags)
299*61046927SAndroid Build Coastguard Worker {
300*61046927SAndroid Build Coastguard Worker    struct drm_nouveau_gem_cpu_prep req = {};
301*61046927SAndroid Build Coastguard Worker 
302*61046927SAndroid Build Coastguard Worker    req.handle = bo->handle;
303*61046927SAndroid Build Coastguard Worker    if (flags & NOUVEAU_WS_BO_WR)
304*61046927SAndroid Build Coastguard Worker       req.flags |= NOUVEAU_GEM_CPU_PREP_WRITE;
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker    return !drmCommandWrite(bo->dev->fd, DRM_NOUVEAU_GEM_CPU_PREP, &req, sizeof(req));
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker int
nouveau_ws_bo_dma_buf(struct nouveau_ws_bo * bo,int * fd)310*61046927SAndroid Build Coastguard Worker nouveau_ws_bo_dma_buf(struct nouveau_ws_bo *bo, int *fd)
311*61046927SAndroid Build Coastguard Worker {
312*61046927SAndroid Build Coastguard Worker    return drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC, fd);
313*61046927SAndroid Build Coastguard Worker }
314