16bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse/*
22fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Copyright © 2008 Dave Airlie
32fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Copyright © 2008 Jérôme Glisse
42fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * All Rights Reserved.
56bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse *
62fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Permission is hereby granted, free of charge, to any person obtaining
72fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * a copy of this software and associated documentation files (the
82fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * "Software"), to deal in the Software without restriction, including
92fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * without limitation the rights to use, copy, modify, merge, publish,
102fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * distribute, sub license, and/or sell copies of the Software, and to
112fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * permit persons to whom the Software is furnished to do so, subject to
122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * the following conditions:
136bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse *
142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
172fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
182fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
192fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
206bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
212fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * USE OR OTHER DEALINGS IN THE SOFTWARE.
222fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie *
232fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * The above copyright notice and this permission notice (including the
242fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * next paragraph) shall be included in all copies or substantial portions
252fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * of the Software.
262fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie */
272fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie/*
282fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Authors:
292fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie *      Dave Airlie
302fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie *      Jérôme Glisse <glisse@freedesktop.org>
312fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie */
322fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#ifdef HAVE_CONFIG_H
332fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <config.h>
342fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#endif
352fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <stdio.h>
362fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <stdint.h>
372fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <stdlib.h>
382fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <string.h>
392fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <errno.h>
4042465feb9759ef5a6d79d7e628510cd0a081f913Emil Velikov#include "libdrm_macros.h"
412fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "xf86drm.h"
42966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen#include "xf86atomic.h"
432fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "drm.h"
442fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_drm.h"
452fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_bo.h"
46125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie#include "radeon_bo_int.h"
472fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_bo_gem.h"
483163cfe4db925429760407e77140e2d595338bc2Dave Airlie#include <fcntl.h>
492fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestruct radeon_bo_gem {
500980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    struct radeon_bo_int    base;
510980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    uint32_t                name;
520980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    int                     map_count;
530980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    atomic_t                reloc_in_cs;
540980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    void                    *priv_ptr;
552fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie};
562fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
572fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestruct bo_manager_gem {
582fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct radeon_bo_manager    base;
592fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie};
602fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
61125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_wait(struct radeon_bo_int *boi);
62125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie
632fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestatic struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
642fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t handle,
652fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t size,
662fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t alignment,
672fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t domains,
682fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t flags)
692fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
702fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct radeon_bo_gem *bo;
712fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int r;
722fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem));
742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (bo == NULL) {
752fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return NULL;
762fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
772fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
782fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.bom = bom;
792fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.handle = 0;
802fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.size = size;
812fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.alignment = alignment;
822fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.domains = domains;
832fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.flags = flags;
842fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.ptr = NULL;
85966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen    atomic_set(&bo->reloc_in_cs, 0);
862fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->map_count = 0;
872fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (handle) {
882fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        struct drm_gem_open open_arg;
892fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
902fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        memset(&open_arg, 0, sizeof(open_arg));
912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        open_arg.name = handle;
92b84314a86ea4ad30e0f57a71b4ef0fa138fb24c6Jerome Glisse        r = drmIoctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
932fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        if (r != 0) {
942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            free(bo);
952fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            return NULL;
962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        }
972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->base.handle = open_arg.handle;
982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->base.size = open_arg.size;
992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->name = handle;
1002fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    } else {
1012fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        struct drm_radeon_gem_create args;
1022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
1032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.size = size;
1042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.alignment = alignment;
1052fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.initial_domain = bo->base.domains;
106db138b9ba12a0de5d6140832c0679c2418e3e7e0Michel Dänzer        args.flags = flags;
1072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.handle = 0;
1082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE,
1092fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                &args, sizeof(args));
1102fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->base.handle = args.handle;
1112fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        if (r) {
1122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "Failed to allocate :\n");
1132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "   size      : %d bytes\n", size);
1142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "   alignment : %d bytes\n", alignment);
1152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "   domains   : %d\n", bo->base.domains);
1162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            free(bo);
1172fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            return NULL;
1182fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        }
1192fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
1202fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    radeon_bo_ref((struct radeon_bo*)bo);
1212fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return (struct radeon_bo*)bo;
1222fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1232fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
124125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic void bo_ref(struct radeon_bo_int *boi)
1252fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
1262fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1272fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
128125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic struct radeon_bo *bo_unref(struct radeon_bo_int *boi)
1292fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
130125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
1312fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_gem_close args;
1322fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
133125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    if (boi->cref) {
134125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie        return (struct radeon_bo *)boi;
1352fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
136322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    if (bo_gem->priv_ptr) {
1376281cf1b4310ff0b7670677cb4113a89ebf0b619Emil Velikov        drm_munmap(bo_gem->priv_ptr, boi->size);
1382fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
1392fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
140a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    /* Zero out args to make valgrind happy */
141a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    memset(&args, 0, sizeof(args));
142a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle
1432fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    /* close object */
144125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
145125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_CLOSE, &args);
1462fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    memset(bo_gem, 0, sizeof(struct radeon_bo_gem));
1472fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    free(bo_gem);
1482fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return NULL;
1492fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1502fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
151125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_map(struct radeon_bo_int *boi, int write)
1522fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
153125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
1542fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_radeon_gem_mmap args;
1552fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int r;
1562fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    void *ptr;
1572fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
15819d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer    if (bo_gem->map_count++ != 0) {
15919d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer        return 0;
16019d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer    }
16119d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer    if (bo_gem->priv_ptr) {
1626bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse        goto wait;
163322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    }
164322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie
165125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    boi->ptr = NULL;
166a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle
167a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    /* Zero out args to make valgrind happy */
168a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    memset(&args, 0, sizeof(args));
169125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
1702fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.offset = 0;
171125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.size = (uint64_t)boi->size;
172125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
1732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            DRM_RADEON_GEM_MMAP,
1742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            &args,
1752fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            sizeof(args));
1762fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (r) {
1772fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
178125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie                boi, boi->handle, r);
1792fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return r;
1802fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
1816281cf1b4310ff0b7670677cb4113a89ebf0b619Emil Velikov    ptr = drm_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, boi->bom->fd, args.addr_ptr);
1822fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (ptr == MAP_FAILED)
1832fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return -errno;
184322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    bo_gem->priv_ptr = ptr;
1851978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airliewait:
186125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    boi->ptr = bo_gem->priv_ptr;
187125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = bo_wait(boi);
1881978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airlie    if (r)
189125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie        return r;
1901978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airlie    return 0;
1912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1922fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
193125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_unmap(struct radeon_bo_int *boi)
1942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
195125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
1962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
1972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (--bo_gem->map_count > 0) {
1982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return 0;
1992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
2006281cf1b4310ff0b7670677cb4113a89ebf0b619Emil Velikov    //drm_munmap(bo->ptr, bo->size);
201125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    boi->ptr = NULL;
2022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return 0;
2032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
2042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
205125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_wait(struct radeon_bo_int *boi)
2062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
2072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_radeon_gem_wait_idle args;
2082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int ret;
2092fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
210a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    /* Zero out args to make valgrind happy */
211a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    memset(&args, 0, sizeof(args));
212125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
2132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    do {
214a0178c00c70f4b47e09ed7564fc2ccde611231a0Mark Kettenis        ret = drmCommandWrite(boi->bom->fd, DRM_RADEON_GEM_WAIT_IDLE,
215a0178c00c70f4b47e09ed7564fc2ccde611231a0Mark Kettenis			      &args, sizeof(args));
2162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    } while (ret == -EBUSY);
2172fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return ret;
2182fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
2192fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
220125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_is_busy(struct radeon_bo_int *boi, uint32_t *domain)
221caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen{
222caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    struct drm_radeon_gem_busy args;
223caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    int ret;
224caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
225125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
226caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    args.domain = 0;
227caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
228125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    ret = drmCommandWriteRead(boi->bom->fd, DRM_RADEON_GEM_BUSY,
2296bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                              &args, sizeof(args));
230caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
231caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    *domain = args.domain;
232caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    return ret;
233caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen}
234caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
235125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_set_tiling(struct radeon_bo_int *boi, uint32_t tiling_flags,
2366bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                         uint32_t pitch)
2374507863058a10d00c982975daf396f83caee0fe2Dave Airlie{
2384507863058a10d00c982975daf396f83caee0fe2Dave Airlie    struct drm_radeon_gem_set_tiling args;
2394507863058a10d00c982975daf396f83caee0fe2Dave Airlie    int r;
2404507863058a10d00c982975daf396f83caee0fe2Dave Airlie
241125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
2424507863058a10d00c982975daf396f83caee0fe2Dave Airlie    args.tiling_flags = tiling_flags;
2434507863058a10d00c982975daf396f83caee0fe2Dave Airlie    args.pitch = pitch;
2444507863058a10d00c982975daf396f83caee0fe2Dave Airlie
245125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
2466bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            DRM_RADEON_GEM_SET_TILING,
2476bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            &args,
2486bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            sizeof(args));
2494507863058a10d00c982975daf396f83caee0fe2Dave Airlie    return r;
2504507863058a10d00c982975daf396f83caee0fe2Dave Airlie}
2514507863058a10d00c982975daf396f83caee0fe2Dave Airlie
252125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_get_tiling(struct radeon_bo_int *boi, uint32_t *tiling_flags,
2536bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                         uint32_t *pitch)
2544507863058a10d00c982975daf396f83caee0fe2Dave Airlie{
2558420743301a36dc1316fadf53bf8e1478068400aMarek Olšák    struct drm_radeon_gem_set_tiling args = {};
2564507863058a10d00c982975daf396f83caee0fe2Dave Airlie    int r;
2574507863058a10d00c982975daf396f83caee0fe2Dave Airlie
258125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
2594507863058a10d00c982975daf396f83caee0fe2Dave Airlie
260125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
2616bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            DRM_RADEON_GEM_GET_TILING,
2626bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            &args,
2636bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            sizeof(args));
2644507863058a10d00c982975daf396f83caee0fe2Dave Airlie
2654507863058a10d00c982975daf396f83caee0fe2Dave Airlie    if (r)
2666bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse        return r;
2674507863058a10d00c982975daf396f83caee0fe2Dave Airlie
2684507863058a10d00c982975daf396f83caee0fe2Dave Airlie    *tiling_flags = args.tiling_flags;
2694507863058a10d00c982975daf396f83caee0fe2Dave Airlie    *pitch = args.pitch;
2704507863058a10d00c982975daf396f83caee0fe2Dave Airlie    return r;
2714507863058a10d00c982975daf396f83caee0fe2Dave Airlie}
2724507863058a10d00c982975daf396f83caee0fe2Dave Airlie
273ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikovstatic const struct radeon_bo_funcs bo_gem_funcs = {
274ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_open = bo_open,
275ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_ref = bo_ref,
276ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_unref = bo_unref,
277ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_map = bo_map,
278ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_unmap = bo_unmap,
279ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_wait = bo_wait,
280ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_is_static = NULL,
281ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_set_tiling = bo_set_tiling,
282ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_get_tiling = bo_get_tiling,
283ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_is_busy = bo_is_busy,
284ec2b105492cae093cc78003239e9b6816d1a7384Emil Velikov    .bo_is_referenced_by_cs = NULL,
2852fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie};
2862fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
2870f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovstruct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
2882fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
2892fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct bo_manager_gem *bomg;
2902fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
2912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem));
2922fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (bomg == NULL) {
2932fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return NULL;
2942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
2952fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bomg->base.funcs = &bo_gem_funcs;
2962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bomg->base.fd = fd;
2972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return (struct radeon_bo_manager*)bomg;
2982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
2992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3000f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovvoid radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
3012fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
3022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
3032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (bom == NULL) {
3052fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return;
3062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
3072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    free(bomg);
3082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
3092fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3100f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovuint32_t
31158ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_name_bo(struct radeon_bo *bo)
3122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
3132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
3142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return bo_gem->name;
3152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
3162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3170f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovvoid *
31858ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_get_reloc_in_cs(struct radeon_bo *bo)
319966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen{
320966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
321966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen    return &bo_gem->reloc_in_cs;
322966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen}
323966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen
3240f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovint
32558ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
326fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie{
3270980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
328125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
329fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    struct drm_gem_flink flink;
330fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    int r;
331fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie
3320980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    if (bo_gem->name) {
3330980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse        *name = bo_gem->name;
3340980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse        return 0;
3350980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    }
336fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    flink.handle = bo->handle;
337125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_FLINK, &flink);
338fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    if (r) {
3396bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse        return r;
340fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    }
3410980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse    bo_gem->name = flink.name;
342fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    *name = flink.name;
343fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    return 0;
344fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie}
345fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie
3460f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovint
34758ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
3482fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
349125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
3502fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_radeon_gem_set_domain args;
3512fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int r;
3522fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3532fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.handle = bo->handle;
3542fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.read_domains = read_domains;
3552fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.write_domain = write_domain;
3562fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
357125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
3582fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            DRM_RADEON_GEM_SET_DOMAIN,
3592fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            &args,
3602fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            sizeof(args));
3612fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return r;
3622fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
3633163cfe4db925429760407e77140e2d595338bc2Dave Airlie
3640f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovint radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
3653163cfe4db925429760407e77140e2d595338bc2Dave Airlie{
3663163cfe4db925429760407e77140e2d595338bc2Dave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
3673163cfe4db925429760407e77140e2d595338bc2Dave Airlie    int ret;
3683163cfe4db925429760407e77140e2d595338bc2Dave Airlie
3693163cfe4db925429760407e77140e2d595338bc2Dave Airlie    ret = drmPrimeHandleToFD(bo_gem->base.bom->fd, bo->handle, DRM_CLOEXEC, handle);
3703163cfe4db925429760407e77140e2d595338bc2Dave Airlie    return ret;
3713163cfe4db925429760407e77140e2d595338bc2Dave Airlie}
3723163cfe4db925429760407e77140e2d595338bc2Dave Airlie
3730f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovstruct radeon_bo *
37458ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_bo_open_prime(struct radeon_bo_manager *bom, int fd_handle, uint32_t size)
3753163cfe4db925429760407e77140e2d595338bc2Dave Airlie{
3763163cfe4db925429760407e77140e2d595338bc2Dave Airlie    struct radeon_bo_gem *bo;
3773163cfe4db925429760407e77140e2d595338bc2Dave Airlie    int r;
3783163cfe4db925429760407e77140e2d595338bc2Dave Airlie    uint32_t handle;
3793163cfe4db925429760407e77140e2d595338bc2Dave Airlie
3803163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem));
3813163cfe4db925429760407e77140e2d595338bc2Dave Airlie    if (bo == NULL) {
3823163cfe4db925429760407e77140e2d595338bc2Dave Airlie        return NULL;
3833163cfe4db925429760407e77140e2d595338bc2Dave Airlie    }
3843163cfe4db925429760407e77140e2d595338bc2Dave Airlie
3853163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.bom = bom;
3863163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.handle = 0;
3873163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.size = size;
3883163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.alignment = 0;
3893163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.domains = RADEON_GEM_DOMAIN_GTT;
3903163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.flags = 0;
3913163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.ptr = NULL;
3923163cfe4db925429760407e77140e2d595338bc2Dave Airlie    atomic_set(&bo->reloc_in_cs, 0);
3933163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->map_count = 0;
3943163cfe4db925429760407e77140e2d595338bc2Dave Airlie
3953163cfe4db925429760407e77140e2d595338bc2Dave Airlie    r = drmPrimeFDToHandle(bom->fd, fd_handle, &handle);
3963163cfe4db925429760407e77140e2d595338bc2Dave Airlie    if (r != 0) {
3973163cfe4db925429760407e77140e2d595338bc2Dave Airlie	free(bo);
3983163cfe4db925429760407e77140e2d595338bc2Dave Airlie	return NULL;
3993163cfe4db925429760407e77140e2d595338bc2Dave Airlie    }
4003163cfe4db925429760407e77140e2d595338bc2Dave Airlie
4013163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->base.handle = handle;
4023163cfe4db925429760407e77140e2d595338bc2Dave Airlie    bo->name = handle;
4033163cfe4db925429760407e77140e2d595338bc2Dave Airlie
4043163cfe4db925429760407e77140e2d595338bc2Dave Airlie    radeon_bo_ref((struct radeon_bo *)bo);
4053163cfe4db925429760407e77140e2d595338bc2Dave Airlie    return (struct radeon_bo *)bo;
4063163cfe4db925429760407e77140e2d595338bc2Dave Airlie
4073163cfe4db925429760407e77140e2d595338bc2Dave Airlie}
408