1*7688df22SAndroid Build Coastguard Worker /*
2*7688df22SAndroid Build Coastguard Worker * Copyright © 2008 Dave Airlie
3*7688df22SAndroid Build Coastguard Worker * Copyright © 2008 Jérôme Glisse
4*7688df22SAndroid Build Coastguard Worker * All Rights Reserved.
5*7688df22SAndroid Build Coastguard Worker *
6*7688df22SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining
7*7688df22SAndroid Build Coastguard Worker * a copy of this software and associated documentation files (the
8*7688df22SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
9*7688df22SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
10*7688df22SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
11*7688df22SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
12*7688df22SAndroid Build Coastguard Worker * the following conditions:
13*7688df22SAndroid Build Coastguard Worker *
14*7688df22SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15*7688df22SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16*7688df22SAndroid Build Coastguard Worker * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17*7688df22SAndroid Build Coastguard Worker * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
18*7688df22SAndroid Build Coastguard Worker * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*7688df22SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*7688df22SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21*7688df22SAndroid Build Coastguard Worker * USE OR OTHER DEALINGS IN THE SOFTWARE.
22*7688df22SAndroid Build Coastguard Worker *
23*7688df22SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
24*7688df22SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
25*7688df22SAndroid Build Coastguard Worker * of the Software.
26*7688df22SAndroid Build Coastguard Worker */
27*7688df22SAndroid Build Coastguard Worker /*
28*7688df22SAndroid Build Coastguard Worker * Authors:
29*7688df22SAndroid Build Coastguard Worker * Dave Airlie
30*7688df22SAndroid Build Coastguard Worker * Jérôme Glisse <[email protected]>
31*7688df22SAndroid Build Coastguard Worker */
32*7688df22SAndroid Build Coastguard Worker #include <stdio.h>
33*7688df22SAndroid Build Coastguard Worker #include <stdint.h>
34*7688df22SAndroid Build Coastguard Worker #include <stdlib.h>
35*7688df22SAndroid Build Coastguard Worker #include <string.h>
36*7688df22SAndroid Build Coastguard Worker #include <errno.h>
37*7688df22SAndroid Build Coastguard Worker #include "libdrm_macros.h"
38*7688df22SAndroid Build Coastguard Worker #include "xf86drm.h"
39*7688df22SAndroid Build Coastguard Worker #include "xf86atomic.h"
40*7688df22SAndroid Build Coastguard Worker #include "drm.h"
41*7688df22SAndroid Build Coastguard Worker #include "radeon_drm.h"
42*7688df22SAndroid Build Coastguard Worker #include "radeon_bo.h"
43*7688df22SAndroid Build Coastguard Worker #include "radeon_bo_int.h"
44*7688df22SAndroid Build Coastguard Worker #include "radeon_bo_gem.h"
45*7688df22SAndroid Build Coastguard Worker #include <fcntl.h>
46*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem {
47*7688df22SAndroid Build Coastguard Worker struct radeon_bo_int base;
48*7688df22SAndroid Build Coastguard Worker uint32_t name;
49*7688df22SAndroid Build Coastguard Worker int map_count;
50*7688df22SAndroid Build Coastguard Worker atomic_t reloc_in_cs;
51*7688df22SAndroid Build Coastguard Worker void *priv_ptr;
52*7688df22SAndroid Build Coastguard Worker };
53*7688df22SAndroid Build Coastguard Worker
54*7688df22SAndroid Build Coastguard Worker struct bo_manager_gem {
55*7688df22SAndroid Build Coastguard Worker struct radeon_bo_manager base;
56*7688df22SAndroid Build Coastguard Worker };
57*7688df22SAndroid Build Coastguard Worker
58*7688df22SAndroid Build Coastguard Worker static int bo_wait(struct radeon_bo_int *boi);
59*7688df22SAndroid Build Coastguard Worker
bo_open(struct radeon_bo_manager * bom,uint32_t handle,uint32_t size,uint32_t alignment,uint32_t domains,uint32_t flags)60*7688df22SAndroid Build Coastguard Worker static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
61*7688df22SAndroid Build Coastguard Worker uint32_t handle,
62*7688df22SAndroid Build Coastguard Worker uint32_t size,
63*7688df22SAndroid Build Coastguard Worker uint32_t alignment,
64*7688df22SAndroid Build Coastguard Worker uint32_t domains,
65*7688df22SAndroid Build Coastguard Worker uint32_t flags)
66*7688df22SAndroid Build Coastguard Worker {
67*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo;
68*7688df22SAndroid Build Coastguard Worker int r;
69*7688df22SAndroid Build Coastguard Worker
70*7688df22SAndroid Build Coastguard Worker bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem));
71*7688df22SAndroid Build Coastguard Worker if (bo == NULL) {
72*7688df22SAndroid Build Coastguard Worker return NULL;
73*7688df22SAndroid Build Coastguard Worker }
74*7688df22SAndroid Build Coastguard Worker
75*7688df22SAndroid Build Coastguard Worker bo->base.bom = bom;
76*7688df22SAndroid Build Coastguard Worker bo->base.handle = 0;
77*7688df22SAndroid Build Coastguard Worker bo->base.size = size;
78*7688df22SAndroid Build Coastguard Worker bo->base.alignment = alignment;
79*7688df22SAndroid Build Coastguard Worker bo->base.domains = domains;
80*7688df22SAndroid Build Coastguard Worker bo->base.flags = flags;
81*7688df22SAndroid Build Coastguard Worker bo->base.ptr = NULL;
82*7688df22SAndroid Build Coastguard Worker atomic_set(&bo->reloc_in_cs, 0);
83*7688df22SAndroid Build Coastguard Worker bo->map_count = 0;
84*7688df22SAndroid Build Coastguard Worker if (handle) {
85*7688df22SAndroid Build Coastguard Worker struct drm_gem_open open_arg;
86*7688df22SAndroid Build Coastguard Worker
87*7688df22SAndroid Build Coastguard Worker memset(&open_arg, 0, sizeof(open_arg));
88*7688df22SAndroid Build Coastguard Worker open_arg.name = handle;
89*7688df22SAndroid Build Coastguard Worker r = drmIoctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
90*7688df22SAndroid Build Coastguard Worker if (r != 0) {
91*7688df22SAndroid Build Coastguard Worker free(bo);
92*7688df22SAndroid Build Coastguard Worker return NULL;
93*7688df22SAndroid Build Coastguard Worker }
94*7688df22SAndroid Build Coastguard Worker bo->base.handle = open_arg.handle;
95*7688df22SAndroid Build Coastguard Worker bo->base.size = open_arg.size;
96*7688df22SAndroid Build Coastguard Worker bo->name = handle;
97*7688df22SAndroid Build Coastguard Worker } else {
98*7688df22SAndroid Build Coastguard Worker struct drm_radeon_gem_create args;
99*7688df22SAndroid Build Coastguard Worker
100*7688df22SAndroid Build Coastguard Worker args.size = size;
101*7688df22SAndroid Build Coastguard Worker args.alignment = alignment;
102*7688df22SAndroid Build Coastguard Worker args.initial_domain = bo->base.domains;
103*7688df22SAndroid Build Coastguard Worker args.flags = flags;
104*7688df22SAndroid Build Coastguard Worker args.handle = 0;
105*7688df22SAndroid Build Coastguard Worker r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE,
106*7688df22SAndroid Build Coastguard Worker &args, sizeof(args));
107*7688df22SAndroid Build Coastguard Worker bo->base.handle = args.handle;
108*7688df22SAndroid Build Coastguard Worker if (r) {
109*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "Failed to allocate :\n");
110*7688df22SAndroid Build Coastguard Worker fprintf(stderr, " size : %d bytes\n", size);
111*7688df22SAndroid Build Coastguard Worker fprintf(stderr, " alignment : %d bytes\n", alignment);
112*7688df22SAndroid Build Coastguard Worker fprintf(stderr, " domains : %d\n", bo->base.domains);
113*7688df22SAndroid Build Coastguard Worker free(bo);
114*7688df22SAndroid Build Coastguard Worker return NULL;
115*7688df22SAndroid Build Coastguard Worker }
116*7688df22SAndroid Build Coastguard Worker }
117*7688df22SAndroid Build Coastguard Worker radeon_bo_ref((struct radeon_bo*)bo);
118*7688df22SAndroid Build Coastguard Worker return (struct radeon_bo*)bo;
119*7688df22SAndroid Build Coastguard Worker }
120*7688df22SAndroid Build Coastguard Worker
bo_ref(struct radeon_bo_int * boi)121*7688df22SAndroid Build Coastguard Worker static void bo_ref(struct radeon_bo_int *boi)
122*7688df22SAndroid Build Coastguard Worker {
123*7688df22SAndroid Build Coastguard Worker }
124*7688df22SAndroid Build Coastguard Worker
bo_unref(struct radeon_bo_int * boi)125*7688df22SAndroid Build Coastguard Worker static struct radeon_bo *bo_unref(struct radeon_bo_int *boi)
126*7688df22SAndroid Build Coastguard Worker {
127*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
128*7688df22SAndroid Build Coastguard Worker
129*7688df22SAndroid Build Coastguard Worker if (boi->cref) {
130*7688df22SAndroid Build Coastguard Worker return (struct radeon_bo *)boi;
131*7688df22SAndroid Build Coastguard Worker }
132*7688df22SAndroid Build Coastguard Worker if (bo_gem->priv_ptr) {
133*7688df22SAndroid Build Coastguard Worker drm_munmap(bo_gem->priv_ptr, boi->size);
134*7688df22SAndroid Build Coastguard Worker }
135*7688df22SAndroid Build Coastguard Worker
136*7688df22SAndroid Build Coastguard Worker /* close object */
137*7688df22SAndroid Build Coastguard Worker drmCloseBufferHandle(boi->bom->fd, boi->handle);
138*7688df22SAndroid Build Coastguard Worker memset(bo_gem, 0, sizeof(struct radeon_bo_gem));
139*7688df22SAndroid Build Coastguard Worker free(bo_gem);
140*7688df22SAndroid Build Coastguard Worker return NULL;
141*7688df22SAndroid Build Coastguard Worker }
142*7688df22SAndroid Build Coastguard Worker
bo_map(struct radeon_bo_int * boi,int write)143*7688df22SAndroid Build Coastguard Worker static int bo_map(struct radeon_bo_int *boi, int write)
144*7688df22SAndroid Build Coastguard Worker {
145*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
146*7688df22SAndroid Build Coastguard Worker struct drm_radeon_gem_mmap args;
147*7688df22SAndroid Build Coastguard Worker int r;
148*7688df22SAndroid Build Coastguard Worker void *ptr;
149*7688df22SAndroid Build Coastguard Worker
150*7688df22SAndroid Build Coastguard Worker if (bo_gem->map_count++ != 0) {
151*7688df22SAndroid Build Coastguard Worker return 0;
152*7688df22SAndroid Build Coastguard Worker }
153*7688df22SAndroid Build Coastguard Worker if (bo_gem->priv_ptr) {
154*7688df22SAndroid Build Coastguard Worker goto wait;
155*7688df22SAndroid Build Coastguard Worker }
156*7688df22SAndroid Build Coastguard Worker
157*7688df22SAndroid Build Coastguard Worker boi->ptr = NULL;
158*7688df22SAndroid Build Coastguard Worker
159*7688df22SAndroid Build Coastguard Worker /* Zero out args to make valgrind happy */
160*7688df22SAndroid Build Coastguard Worker memset(&args, 0, sizeof(args));
161*7688df22SAndroid Build Coastguard Worker args.handle = boi->handle;
162*7688df22SAndroid Build Coastguard Worker args.offset = 0;
163*7688df22SAndroid Build Coastguard Worker args.size = (uint64_t)boi->size;
164*7688df22SAndroid Build Coastguard Worker r = drmCommandWriteRead(boi->bom->fd,
165*7688df22SAndroid Build Coastguard Worker DRM_RADEON_GEM_MMAP,
166*7688df22SAndroid Build Coastguard Worker &args,
167*7688df22SAndroid Build Coastguard Worker sizeof(args));
168*7688df22SAndroid Build Coastguard Worker if (r) {
169*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
170*7688df22SAndroid Build Coastguard Worker boi, boi->handle, r);
171*7688df22SAndroid Build Coastguard Worker return r;
172*7688df22SAndroid Build Coastguard Worker }
173*7688df22SAndroid Build Coastguard Worker ptr = drm_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, boi->bom->fd, args.addr_ptr);
174*7688df22SAndroid Build Coastguard Worker if (ptr == MAP_FAILED)
175*7688df22SAndroid Build Coastguard Worker return -errno;
176*7688df22SAndroid Build Coastguard Worker bo_gem->priv_ptr = ptr;
177*7688df22SAndroid Build Coastguard Worker wait:
178*7688df22SAndroid Build Coastguard Worker boi->ptr = bo_gem->priv_ptr;
179*7688df22SAndroid Build Coastguard Worker r = bo_wait(boi);
180*7688df22SAndroid Build Coastguard Worker if (r)
181*7688df22SAndroid Build Coastguard Worker return r;
182*7688df22SAndroid Build Coastguard Worker return 0;
183*7688df22SAndroid Build Coastguard Worker }
184*7688df22SAndroid Build Coastguard Worker
bo_unmap(struct radeon_bo_int * boi)185*7688df22SAndroid Build Coastguard Worker static int bo_unmap(struct radeon_bo_int *boi)
186*7688df22SAndroid Build Coastguard Worker {
187*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
188*7688df22SAndroid Build Coastguard Worker
189*7688df22SAndroid Build Coastguard Worker if (--bo_gem->map_count > 0) {
190*7688df22SAndroid Build Coastguard Worker return 0;
191*7688df22SAndroid Build Coastguard Worker }
192*7688df22SAndroid Build Coastguard Worker //drm_munmap(bo->ptr, bo->size);
193*7688df22SAndroid Build Coastguard Worker boi->ptr = NULL;
194*7688df22SAndroid Build Coastguard Worker return 0;
195*7688df22SAndroid Build Coastguard Worker }
196*7688df22SAndroid Build Coastguard Worker
bo_wait(struct radeon_bo_int * boi)197*7688df22SAndroid Build Coastguard Worker static int bo_wait(struct radeon_bo_int *boi)
198*7688df22SAndroid Build Coastguard Worker {
199*7688df22SAndroid Build Coastguard Worker struct drm_radeon_gem_wait_idle args;
200*7688df22SAndroid Build Coastguard Worker int ret;
201*7688df22SAndroid Build Coastguard Worker
202*7688df22SAndroid Build Coastguard Worker /* Zero out args to make valgrind happy */
203*7688df22SAndroid Build Coastguard Worker memset(&args, 0, sizeof(args));
204*7688df22SAndroid Build Coastguard Worker args.handle = boi->handle;
205*7688df22SAndroid Build Coastguard Worker do {
206*7688df22SAndroid Build Coastguard Worker ret = drmCommandWrite(boi->bom->fd, DRM_RADEON_GEM_WAIT_IDLE,
207*7688df22SAndroid Build Coastguard Worker &args, sizeof(args));
208*7688df22SAndroid Build Coastguard Worker } while (ret == -EBUSY);
209*7688df22SAndroid Build Coastguard Worker return ret;
210*7688df22SAndroid Build Coastguard Worker }
211*7688df22SAndroid Build Coastguard Worker
bo_is_busy(struct radeon_bo_int * boi,uint32_t * domain)212*7688df22SAndroid Build Coastguard Worker static int bo_is_busy(struct radeon_bo_int *boi, uint32_t *domain)
213*7688df22SAndroid Build Coastguard Worker {
214*7688df22SAndroid Build Coastguard Worker struct drm_radeon_gem_busy args;
215*7688df22SAndroid Build Coastguard Worker int ret;
216*7688df22SAndroid Build Coastguard Worker
217*7688df22SAndroid Build Coastguard Worker args.handle = boi->handle;
218*7688df22SAndroid Build Coastguard Worker args.domain = 0;
219*7688df22SAndroid Build Coastguard Worker
220*7688df22SAndroid Build Coastguard Worker ret = drmCommandWriteRead(boi->bom->fd, DRM_RADEON_GEM_BUSY,
221*7688df22SAndroid Build Coastguard Worker &args, sizeof(args));
222*7688df22SAndroid Build Coastguard Worker
223*7688df22SAndroid Build Coastguard Worker *domain = args.domain;
224*7688df22SAndroid Build Coastguard Worker return ret;
225*7688df22SAndroid Build Coastguard Worker }
226*7688df22SAndroid Build Coastguard Worker
bo_set_tiling(struct radeon_bo_int * boi,uint32_t tiling_flags,uint32_t pitch)227*7688df22SAndroid Build Coastguard Worker static int bo_set_tiling(struct radeon_bo_int *boi, uint32_t tiling_flags,
228*7688df22SAndroid Build Coastguard Worker uint32_t pitch)
229*7688df22SAndroid Build Coastguard Worker {
230*7688df22SAndroid Build Coastguard Worker struct drm_radeon_gem_set_tiling args;
231*7688df22SAndroid Build Coastguard Worker int r;
232*7688df22SAndroid Build Coastguard Worker
233*7688df22SAndroid Build Coastguard Worker args.handle = boi->handle;
234*7688df22SAndroid Build Coastguard Worker args.tiling_flags = tiling_flags;
235*7688df22SAndroid Build Coastguard Worker args.pitch = pitch;
236*7688df22SAndroid Build Coastguard Worker
237*7688df22SAndroid Build Coastguard Worker r = drmCommandWriteRead(boi->bom->fd,
238*7688df22SAndroid Build Coastguard Worker DRM_RADEON_GEM_SET_TILING,
239*7688df22SAndroid Build Coastguard Worker &args,
240*7688df22SAndroid Build Coastguard Worker sizeof(args));
241*7688df22SAndroid Build Coastguard Worker return r;
242*7688df22SAndroid Build Coastguard Worker }
243*7688df22SAndroid Build Coastguard Worker
bo_get_tiling(struct radeon_bo_int * boi,uint32_t * tiling_flags,uint32_t * pitch)244*7688df22SAndroid Build Coastguard Worker static int bo_get_tiling(struct radeon_bo_int *boi, uint32_t *tiling_flags,
245*7688df22SAndroid Build Coastguard Worker uint32_t *pitch)
246*7688df22SAndroid Build Coastguard Worker {
247*7688df22SAndroid Build Coastguard Worker struct drm_radeon_gem_set_tiling args = {};
248*7688df22SAndroid Build Coastguard Worker int r;
249*7688df22SAndroid Build Coastguard Worker
250*7688df22SAndroid Build Coastguard Worker args.handle = boi->handle;
251*7688df22SAndroid Build Coastguard Worker
252*7688df22SAndroid Build Coastguard Worker r = drmCommandWriteRead(boi->bom->fd,
253*7688df22SAndroid Build Coastguard Worker DRM_RADEON_GEM_GET_TILING,
254*7688df22SAndroid Build Coastguard Worker &args,
255*7688df22SAndroid Build Coastguard Worker sizeof(args));
256*7688df22SAndroid Build Coastguard Worker
257*7688df22SAndroid Build Coastguard Worker if (r)
258*7688df22SAndroid Build Coastguard Worker return r;
259*7688df22SAndroid Build Coastguard Worker
260*7688df22SAndroid Build Coastguard Worker *tiling_flags = args.tiling_flags;
261*7688df22SAndroid Build Coastguard Worker *pitch = args.pitch;
262*7688df22SAndroid Build Coastguard Worker return r;
263*7688df22SAndroid Build Coastguard Worker }
264*7688df22SAndroid Build Coastguard Worker
265*7688df22SAndroid Build Coastguard Worker static const struct radeon_bo_funcs bo_gem_funcs = {
266*7688df22SAndroid Build Coastguard Worker .bo_open = bo_open,
267*7688df22SAndroid Build Coastguard Worker .bo_ref = bo_ref,
268*7688df22SAndroid Build Coastguard Worker .bo_unref = bo_unref,
269*7688df22SAndroid Build Coastguard Worker .bo_map = bo_map,
270*7688df22SAndroid Build Coastguard Worker .bo_unmap = bo_unmap,
271*7688df22SAndroid Build Coastguard Worker .bo_wait = bo_wait,
272*7688df22SAndroid Build Coastguard Worker .bo_is_static = NULL,
273*7688df22SAndroid Build Coastguard Worker .bo_set_tiling = bo_set_tiling,
274*7688df22SAndroid Build Coastguard Worker .bo_get_tiling = bo_get_tiling,
275*7688df22SAndroid Build Coastguard Worker .bo_is_busy = bo_is_busy,
276*7688df22SAndroid Build Coastguard Worker .bo_is_referenced_by_cs = NULL,
277*7688df22SAndroid Build Coastguard Worker };
278*7688df22SAndroid Build Coastguard Worker
radeon_bo_manager_gem_ctor(int fd)279*7688df22SAndroid Build Coastguard Worker drm_public struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
280*7688df22SAndroid Build Coastguard Worker {
281*7688df22SAndroid Build Coastguard Worker struct bo_manager_gem *bomg;
282*7688df22SAndroid Build Coastguard Worker
283*7688df22SAndroid Build Coastguard Worker bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem));
284*7688df22SAndroid Build Coastguard Worker if (bomg == NULL) {
285*7688df22SAndroid Build Coastguard Worker return NULL;
286*7688df22SAndroid Build Coastguard Worker }
287*7688df22SAndroid Build Coastguard Worker bomg->base.funcs = &bo_gem_funcs;
288*7688df22SAndroid Build Coastguard Worker bomg->base.fd = fd;
289*7688df22SAndroid Build Coastguard Worker return (struct radeon_bo_manager*)bomg;
290*7688df22SAndroid Build Coastguard Worker }
291*7688df22SAndroid Build Coastguard Worker
radeon_bo_manager_gem_dtor(struct radeon_bo_manager * bom)292*7688df22SAndroid Build Coastguard Worker drm_public void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
293*7688df22SAndroid Build Coastguard Worker {
294*7688df22SAndroid Build Coastguard Worker struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
295*7688df22SAndroid Build Coastguard Worker
296*7688df22SAndroid Build Coastguard Worker if (bom == NULL) {
297*7688df22SAndroid Build Coastguard Worker return;
298*7688df22SAndroid Build Coastguard Worker }
299*7688df22SAndroid Build Coastguard Worker free(bomg);
300*7688df22SAndroid Build Coastguard Worker }
301*7688df22SAndroid Build Coastguard Worker
302*7688df22SAndroid Build Coastguard Worker drm_public uint32_t
radeon_gem_name_bo(struct radeon_bo * bo)303*7688df22SAndroid Build Coastguard Worker radeon_gem_name_bo(struct radeon_bo *bo)
304*7688df22SAndroid Build Coastguard Worker {
305*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
306*7688df22SAndroid Build Coastguard Worker return bo_gem->name;
307*7688df22SAndroid Build Coastguard Worker }
308*7688df22SAndroid Build Coastguard Worker
309*7688df22SAndroid Build Coastguard Worker drm_public void *
radeon_gem_get_reloc_in_cs(struct radeon_bo * bo)310*7688df22SAndroid Build Coastguard Worker radeon_gem_get_reloc_in_cs(struct radeon_bo *bo)
311*7688df22SAndroid Build Coastguard Worker {
312*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
313*7688df22SAndroid Build Coastguard Worker return &bo_gem->reloc_in_cs;
314*7688df22SAndroid Build Coastguard Worker }
315*7688df22SAndroid Build Coastguard Worker
316*7688df22SAndroid Build Coastguard Worker drm_public int
radeon_gem_get_kernel_name(struct radeon_bo * bo,uint32_t * name)317*7688df22SAndroid Build Coastguard Worker radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
318*7688df22SAndroid Build Coastguard Worker {
319*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
320*7688df22SAndroid Build Coastguard Worker struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
321*7688df22SAndroid Build Coastguard Worker struct drm_gem_flink flink;
322*7688df22SAndroid Build Coastguard Worker int r;
323*7688df22SAndroid Build Coastguard Worker
324*7688df22SAndroid Build Coastguard Worker if (bo_gem->name) {
325*7688df22SAndroid Build Coastguard Worker *name = bo_gem->name;
326*7688df22SAndroid Build Coastguard Worker return 0;
327*7688df22SAndroid Build Coastguard Worker }
328*7688df22SAndroid Build Coastguard Worker flink.handle = bo->handle;
329*7688df22SAndroid Build Coastguard Worker r = drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_FLINK, &flink);
330*7688df22SAndroid Build Coastguard Worker if (r) {
331*7688df22SAndroid Build Coastguard Worker return r;
332*7688df22SAndroid Build Coastguard Worker }
333*7688df22SAndroid Build Coastguard Worker bo_gem->name = flink.name;
334*7688df22SAndroid Build Coastguard Worker *name = flink.name;
335*7688df22SAndroid Build Coastguard Worker return 0;
336*7688df22SAndroid Build Coastguard Worker }
337*7688df22SAndroid Build Coastguard Worker
338*7688df22SAndroid Build Coastguard Worker drm_public int
radeon_gem_set_domain(struct radeon_bo * bo,uint32_t read_domains,uint32_t write_domain)339*7688df22SAndroid Build Coastguard Worker radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
340*7688df22SAndroid Build Coastguard Worker {
341*7688df22SAndroid Build Coastguard Worker struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
342*7688df22SAndroid Build Coastguard Worker struct drm_radeon_gem_set_domain args;
343*7688df22SAndroid Build Coastguard Worker int r;
344*7688df22SAndroid Build Coastguard Worker
345*7688df22SAndroid Build Coastguard Worker args.handle = bo->handle;
346*7688df22SAndroid Build Coastguard Worker args.read_domains = read_domains;
347*7688df22SAndroid Build Coastguard Worker args.write_domain = write_domain;
348*7688df22SAndroid Build Coastguard Worker
349*7688df22SAndroid Build Coastguard Worker r = drmCommandWriteRead(boi->bom->fd,
350*7688df22SAndroid Build Coastguard Worker DRM_RADEON_GEM_SET_DOMAIN,
351*7688df22SAndroid Build Coastguard Worker &args,
352*7688df22SAndroid Build Coastguard Worker sizeof(args));
353*7688df22SAndroid Build Coastguard Worker return r;
354*7688df22SAndroid Build Coastguard Worker }
355*7688df22SAndroid Build Coastguard Worker
radeon_gem_prime_share_bo(struct radeon_bo * bo,int * handle)356*7688df22SAndroid Build Coastguard Worker drm_public int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
357*7688df22SAndroid Build Coastguard Worker {
358*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
359*7688df22SAndroid Build Coastguard Worker int ret;
360*7688df22SAndroid Build Coastguard Worker
361*7688df22SAndroid Build Coastguard Worker ret = drmPrimeHandleToFD(bo_gem->base.bom->fd, bo->handle, DRM_CLOEXEC, handle);
362*7688df22SAndroid Build Coastguard Worker return ret;
363*7688df22SAndroid Build Coastguard Worker }
364*7688df22SAndroid Build Coastguard Worker
365*7688df22SAndroid Build Coastguard Worker drm_public struct radeon_bo *
radeon_gem_bo_open_prime(struct radeon_bo_manager * bom,int fd_handle,uint32_t size)366*7688df22SAndroid Build Coastguard Worker radeon_gem_bo_open_prime(struct radeon_bo_manager *bom, int fd_handle, uint32_t size)
367*7688df22SAndroid Build Coastguard Worker {
368*7688df22SAndroid Build Coastguard Worker struct radeon_bo_gem *bo;
369*7688df22SAndroid Build Coastguard Worker int r;
370*7688df22SAndroid Build Coastguard Worker uint32_t handle;
371*7688df22SAndroid Build Coastguard Worker
372*7688df22SAndroid Build Coastguard Worker bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem));
373*7688df22SAndroid Build Coastguard Worker if (bo == NULL) {
374*7688df22SAndroid Build Coastguard Worker return NULL;
375*7688df22SAndroid Build Coastguard Worker }
376*7688df22SAndroid Build Coastguard Worker
377*7688df22SAndroid Build Coastguard Worker bo->base.bom = bom;
378*7688df22SAndroid Build Coastguard Worker bo->base.handle = 0;
379*7688df22SAndroid Build Coastguard Worker bo->base.size = size;
380*7688df22SAndroid Build Coastguard Worker bo->base.alignment = 0;
381*7688df22SAndroid Build Coastguard Worker bo->base.domains = RADEON_GEM_DOMAIN_GTT;
382*7688df22SAndroid Build Coastguard Worker bo->base.flags = 0;
383*7688df22SAndroid Build Coastguard Worker bo->base.ptr = NULL;
384*7688df22SAndroid Build Coastguard Worker atomic_set(&bo->reloc_in_cs, 0);
385*7688df22SAndroid Build Coastguard Worker bo->map_count = 0;
386*7688df22SAndroid Build Coastguard Worker
387*7688df22SAndroid Build Coastguard Worker r = drmPrimeFDToHandle(bom->fd, fd_handle, &handle);
388*7688df22SAndroid Build Coastguard Worker if (r != 0) {
389*7688df22SAndroid Build Coastguard Worker free(bo);
390*7688df22SAndroid Build Coastguard Worker return NULL;
391*7688df22SAndroid Build Coastguard Worker }
392*7688df22SAndroid Build Coastguard Worker
393*7688df22SAndroid Build Coastguard Worker bo->base.handle = handle;
394*7688df22SAndroid Build Coastguard Worker bo->name = handle;
395*7688df22SAndroid Build Coastguard Worker
396*7688df22SAndroid Build Coastguard Worker radeon_bo_ref((struct radeon_bo *)bo);
397*7688df22SAndroid Build Coastguard Worker return (struct radeon_bo *)bo;
398*7688df22SAndroid Build Coastguard Worker
399*7688df22SAndroid Build Coastguard Worker }
400