1d722e3fbSopenharmony_ci/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 2d722e3fbSopenharmony_ci 3d722e3fbSopenharmony_ci/* 4d722e3fbSopenharmony_ci * Copyright (C) 2011 Texas Instruments, Inc 5d722e3fbSopenharmony_ci * 6d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 9d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12d722e3fbSopenharmony_ci * 13d722e3fbSopenharmony_ci * The above copyright notice and this permission notice (including the next 14d722e3fbSopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 15d722e3fbSopenharmony_ci * Software. 16d722e3fbSopenharmony_ci * 17d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20d722e3fbSopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21d722e3fbSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22d722e3fbSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23d722e3fbSopenharmony_ci * SOFTWARE. 24d722e3fbSopenharmony_ci * 25d722e3fbSopenharmony_ci * Authors: 26d722e3fbSopenharmony_ci * Rob Clark <rob@ti.com> 27d722e3fbSopenharmony_ci */ 28d722e3fbSopenharmony_ci 29d722e3fbSopenharmony_ci#include <stdlib.h> 30d722e3fbSopenharmony_ci#include <linux/stddef.h> 31d722e3fbSopenharmony_ci#include <linux/types.h> 32d722e3fbSopenharmony_ci#include <errno.h> 33d722e3fbSopenharmony_ci#include <sys/mman.h> 34d722e3fbSopenharmony_ci#include <fcntl.h> 35d722e3fbSopenharmony_ci#include <unistd.h> 36d722e3fbSopenharmony_ci#include <pthread.h> 37d722e3fbSopenharmony_ci 38d722e3fbSopenharmony_ci#include <libdrm_macros.h> 39d722e3fbSopenharmony_ci#include <xf86drm.h> 40d722e3fbSopenharmony_ci#include <xf86atomic.h> 41d722e3fbSopenharmony_ci 42d722e3fbSopenharmony_ci#include "omap_drm.h" 43d722e3fbSopenharmony_ci#include "omap_drmif.h" 44d722e3fbSopenharmony_ci 45d722e3fbSopenharmony_ci#define __round_mask(x, y) ((__typeof__(x))((y)-1)) 46d722e3fbSopenharmony_ci#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) 47d722e3fbSopenharmony_ci#define PAGE_SIZE 4096 48d722e3fbSopenharmony_ci 49d722e3fbSopenharmony_cistatic pthread_mutex_t table_lock = PTHREAD_MUTEX_INITIALIZER; 50d722e3fbSopenharmony_cistatic void * dev_table; 51d722e3fbSopenharmony_ci 52d722e3fbSopenharmony_cistruct omap_device { 53d722e3fbSopenharmony_ci int fd; 54d722e3fbSopenharmony_ci atomic_t refcnt; 55d722e3fbSopenharmony_ci 56d722e3fbSopenharmony_ci /* The handle_table is used to track GEM bo handles associated w/ 57d722e3fbSopenharmony_ci * this fd. This is needed, in particular, when importing 58d722e3fbSopenharmony_ci * dmabuf's because we don't want multiple 'struct omap_bo's 59d722e3fbSopenharmony_ci * floating around with the same handle. Otherwise, when the 60d722e3fbSopenharmony_ci * first one is omap_bo_del()'d the handle becomes no longer 61d722e3fbSopenharmony_ci * valid, and the remaining 'struct omap_bo's are left pointing 62d722e3fbSopenharmony_ci * to an invalid handle (and possible a GEM bo that is already 63d722e3fbSopenharmony_ci * free'd). 64d722e3fbSopenharmony_ci */ 65d722e3fbSopenharmony_ci void *handle_table; 66d722e3fbSopenharmony_ci}; 67d722e3fbSopenharmony_ci 68d722e3fbSopenharmony_ci/* a GEM buffer object allocated from the DRM device */ 69d722e3fbSopenharmony_cistruct omap_bo { 70d722e3fbSopenharmony_ci struct omap_device *dev; 71d722e3fbSopenharmony_ci void *map; /* userspace mmap'ing (if there is one) */ 72d722e3fbSopenharmony_ci uint32_t size; 73d722e3fbSopenharmony_ci uint32_t handle; 74d722e3fbSopenharmony_ci uint32_t name; /* flink global handle (DRI2 name) */ 75d722e3fbSopenharmony_ci uint64_t offset; /* offset to mmap() */ 76d722e3fbSopenharmony_ci int fd; /* dmabuf handle */ 77d722e3fbSopenharmony_ci atomic_t refcnt; 78d722e3fbSopenharmony_ci}; 79d722e3fbSopenharmony_ci 80d722e3fbSopenharmony_cistatic struct omap_device * omap_device_new_impl(int fd) 81d722e3fbSopenharmony_ci{ 82d722e3fbSopenharmony_ci struct omap_device *dev = calloc(sizeof(*dev), 1); 83d722e3fbSopenharmony_ci if (!dev) 84d722e3fbSopenharmony_ci return NULL; 85d722e3fbSopenharmony_ci dev->fd = fd; 86d722e3fbSopenharmony_ci atomic_set(&dev->refcnt, 1); 87d722e3fbSopenharmony_ci dev->handle_table = drmHashCreate(); 88d722e3fbSopenharmony_ci return dev; 89d722e3fbSopenharmony_ci} 90d722e3fbSopenharmony_ci 91d722e3fbSopenharmony_cidrm_public struct omap_device * omap_device_new(int fd) 92d722e3fbSopenharmony_ci{ 93d722e3fbSopenharmony_ci struct omap_device *dev = NULL; 94d722e3fbSopenharmony_ci 95d722e3fbSopenharmony_ci pthread_mutex_lock(&table_lock); 96d722e3fbSopenharmony_ci 97d722e3fbSopenharmony_ci if (!dev_table) 98d722e3fbSopenharmony_ci dev_table = drmHashCreate(); 99d722e3fbSopenharmony_ci 100d722e3fbSopenharmony_ci if (drmHashLookup(dev_table, fd, (void **)&dev)) { 101d722e3fbSopenharmony_ci /* not found, create new device */ 102d722e3fbSopenharmony_ci dev = omap_device_new_impl(fd); 103d722e3fbSopenharmony_ci drmHashInsert(dev_table, fd, dev); 104d722e3fbSopenharmony_ci } else { 105d722e3fbSopenharmony_ci /* found, just incr refcnt */ 106d722e3fbSopenharmony_ci dev = omap_device_ref(dev); 107d722e3fbSopenharmony_ci } 108d722e3fbSopenharmony_ci 109d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 110d722e3fbSopenharmony_ci 111d722e3fbSopenharmony_ci return dev; 112d722e3fbSopenharmony_ci} 113d722e3fbSopenharmony_ci 114d722e3fbSopenharmony_cidrm_public struct omap_device * omap_device_ref(struct omap_device *dev) 115d722e3fbSopenharmony_ci{ 116d722e3fbSopenharmony_ci atomic_inc(&dev->refcnt); 117d722e3fbSopenharmony_ci return dev; 118d722e3fbSopenharmony_ci} 119d722e3fbSopenharmony_ci 120d722e3fbSopenharmony_cidrm_public void omap_device_del(struct omap_device *dev) 121d722e3fbSopenharmony_ci{ 122d722e3fbSopenharmony_ci if (!atomic_dec_and_test(&dev->refcnt)) 123d722e3fbSopenharmony_ci return; 124d722e3fbSopenharmony_ci pthread_mutex_lock(&table_lock); 125d722e3fbSopenharmony_ci drmHashDestroy(dev->handle_table); 126d722e3fbSopenharmony_ci drmHashDelete(dev_table, dev->fd); 127d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 128d722e3fbSopenharmony_ci free(dev); 129d722e3fbSopenharmony_ci} 130d722e3fbSopenharmony_ci 131d722e3fbSopenharmony_cidrm_public int 132d722e3fbSopenharmony_ciomap_get_param(struct omap_device *dev, uint64_t param, uint64_t *value) 133d722e3fbSopenharmony_ci{ 134d722e3fbSopenharmony_ci struct drm_omap_param req = { 135d722e3fbSopenharmony_ci .param = param, 136d722e3fbSopenharmony_ci }; 137d722e3fbSopenharmony_ci int ret; 138d722e3fbSopenharmony_ci 139d722e3fbSopenharmony_ci ret = drmCommandWriteRead(dev->fd, DRM_OMAP_GET_PARAM, &req, sizeof(req)); 140d722e3fbSopenharmony_ci if (ret) { 141d722e3fbSopenharmony_ci return ret; 142d722e3fbSopenharmony_ci } 143d722e3fbSopenharmony_ci 144d722e3fbSopenharmony_ci *value = req.value; 145d722e3fbSopenharmony_ci 146d722e3fbSopenharmony_ci return 0; 147d722e3fbSopenharmony_ci} 148d722e3fbSopenharmony_ci 149d722e3fbSopenharmony_cidrm_public int 150d722e3fbSopenharmony_ciomap_set_param(struct omap_device *dev, uint64_t param, uint64_t value) 151d722e3fbSopenharmony_ci{ 152d722e3fbSopenharmony_ci struct drm_omap_param req = { 153d722e3fbSopenharmony_ci .param = param, 154d722e3fbSopenharmony_ci .value = value, 155d722e3fbSopenharmony_ci }; 156d722e3fbSopenharmony_ci return drmCommandWrite(dev->fd, DRM_OMAP_SET_PARAM, &req, sizeof(req)); 157d722e3fbSopenharmony_ci} 158d722e3fbSopenharmony_ci 159d722e3fbSopenharmony_ci/* lookup a buffer from it's handle, call w/ table_lock held: */ 160d722e3fbSopenharmony_cistatic struct omap_bo * lookup_bo(struct omap_device *dev, 161d722e3fbSopenharmony_ci uint32_t handle) 162d722e3fbSopenharmony_ci{ 163d722e3fbSopenharmony_ci struct omap_bo *bo = NULL; 164d722e3fbSopenharmony_ci if (!drmHashLookup(dev->handle_table, handle, (void **)&bo)) { 165d722e3fbSopenharmony_ci /* found, incr refcnt and return: */ 166d722e3fbSopenharmony_ci bo = omap_bo_ref(bo); 167d722e3fbSopenharmony_ci } 168d722e3fbSopenharmony_ci return bo; 169d722e3fbSopenharmony_ci} 170d722e3fbSopenharmony_ci 171d722e3fbSopenharmony_ci/* allocate a new buffer object, call w/ table_lock held */ 172d722e3fbSopenharmony_cistatic struct omap_bo * bo_from_handle(struct omap_device *dev, 173d722e3fbSopenharmony_ci uint32_t handle) 174d722e3fbSopenharmony_ci{ 175d722e3fbSopenharmony_ci struct omap_bo *bo = calloc(sizeof(*bo), 1); 176d722e3fbSopenharmony_ci if (!bo) { 177d722e3fbSopenharmony_ci drmCloseBufferHandle(dev->fd, handle); 178d722e3fbSopenharmony_ci return NULL; 179d722e3fbSopenharmony_ci } 180d722e3fbSopenharmony_ci bo->dev = omap_device_ref(dev); 181d722e3fbSopenharmony_ci bo->handle = handle; 182d722e3fbSopenharmony_ci bo->fd = -1; 183d722e3fbSopenharmony_ci atomic_set(&bo->refcnt, 1); 184d722e3fbSopenharmony_ci /* add ourselves to the handle table: */ 185d722e3fbSopenharmony_ci drmHashInsert(dev->handle_table, handle, bo); 186d722e3fbSopenharmony_ci return bo; 187d722e3fbSopenharmony_ci} 188d722e3fbSopenharmony_ci 189d722e3fbSopenharmony_ci/* allocate a new buffer object */ 190d722e3fbSopenharmony_cistatic struct omap_bo * omap_bo_new_impl(struct omap_device *dev, 191d722e3fbSopenharmony_ci union omap_gem_size size, uint32_t flags) 192d722e3fbSopenharmony_ci{ 193d722e3fbSopenharmony_ci struct omap_bo *bo = NULL; 194d722e3fbSopenharmony_ci struct drm_omap_gem_new req = { 195d722e3fbSopenharmony_ci .size = size, 196d722e3fbSopenharmony_ci .flags = flags, 197d722e3fbSopenharmony_ci }; 198d722e3fbSopenharmony_ci 199d722e3fbSopenharmony_ci if (size.bytes == 0) { 200d722e3fbSopenharmony_ci goto fail; 201d722e3fbSopenharmony_ci } 202d722e3fbSopenharmony_ci 203d722e3fbSopenharmony_ci if (drmCommandWriteRead(dev->fd, DRM_OMAP_GEM_NEW, &req, sizeof(req))) { 204d722e3fbSopenharmony_ci goto fail; 205d722e3fbSopenharmony_ci } 206d722e3fbSopenharmony_ci 207d722e3fbSopenharmony_ci pthread_mutex_lock(&table_lock); 208d722e3fbSopenharmony_ci bo = bo_from_handle(dev, req.handle); 209d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 210d722e3fbSopenharmony_ci 211d722e3fbSopenharmony_ci if (flags & OMAP_BO_TILED) { 212d722e3fbSopenharmony_ci bo->size = round_up(size.tiled.width, PAGE_SIZE) * size.tiled.height; 213d722e3fbSopenharmony_ci } else { 214d722e3fbSopenharmony_ci bo->size = size.bytes; 215d722e3fbSopenharmony_ci } 216d722e3fbSopenharmony_ci 217d722e3fbSopenharmony_ci return bo; 218d722e3fbSopenharmony_ci 219d722e3fbSopenharmony_cifail: 220d722e3fbSopenharmony_ci free(bo); 221d722e3fbSopenharmony_ci return NULL; 222d722e3fbSopenharmony_ci} 223d722e3fbSopenharmony_ci 224d722e3fbSopenharmony_ci 225d722e3fbSopenharmony_ci/* allocate a new (un-tiled) buffer object */ 226d722e3fbSopenharmony_cidrm_public struct omap_bo * 227d722e3fbSopenharmony_ciomap_bo_new(struct omap_device *dev, uint32_t size, uint32_t flags) 228d722e3fbSopenharmony_ci{ 229d722e3fbSopenharmony_ci union omap_gem_size gsize = { 230d722e3fbSopenharmony_ci .bytes = size, 231d722e3fbSopenharmony_ci }; 232d722e3fbSopenharmony_ci if (flags & OMAP_BO_TILED) { 233d722e3fbSopenharmony_ci return NULL; 234d722e3fbSopenharmony_ci } 235d722e3fbSopenharmony_ci return omap_bo_new_impl(dev, gsize, flags); 236d722e3fbSopenharmony_ci} 237d722e3fbSopenharmony_ci 238d722e3fbSopenharmony_ci/* allocate a new buffer object */ 239d722e3fbSopenharmony_cidrm_public struct omap_bo * 240d722e3fbSopenharmony_ciomap_bo_new_tiled(struct omap_device *dev, uint32_t width, 241d722e3fbSopenharmony_ci uint32_t height, uint32_t flags) 242d722e3fbSopenharmony_ci{ 243d722e3fbSopenharmony_ci union omap_gem_size gsize = { 244d722e3fbSopenharmony_ci .tiled = { 245d722e3fbSopenharmony_ci .width = width, 246d722e3fbSopenharmony_ci .height = height, 247d722e3fbSopenharmony_ci }, 248d722e3fbSopenharmony_ci }; 249d722e3fbSopenharmony_ci if (!(flags & OMAP_BO_TILED)) { 250d722e3fbSopenharmony_ci return NULL; 251d722e3fbSopenharmony_ci } 252d722e3fbSopenharmony_ci return omap_bo_new_impl(dev, gsize, flags); 253d722e3fbSopenharmony_ci} 254d722e3fbSopenharmony_ci 255d722e3fbSopenharmony_cidrm_public struct omap_bo *omap_bo_ref(struct omap_bo *bo) 256d722e3fbSopenharmony_ci{ 257d722e3fbSopenharmony_ci atomic_inc(&bo->refcnt); 258d722e3fbSopenharmony_ci return bo; 259d722e3fbSopenharmony_ci} 260d722e3fbSopenharmony_ci 261d722e3fbSopenharmony_ci/* get buffer info */ 262d722e3fbSopenharmony_cistatic int get_buffer_info(struct omap_bo *bo) 263d722e3fbSopenharmony_ci{ 264d722e3fbSopenharmony_ci struct drm_omap_gem_info req = { 265d722e3fbSopenharmony_ci .handle = bo->handle, 266d722e3fbSopenharmony_ci }; 267d722e3fbSopenharmony_ci int ret = drmCommandWriteRead(bo->dev->fd, DRM_OMAP_GEM_INFO, 268d722e3fbSopenharmony_ci &req, sizeof(req)); 269d722e3fbSopenharmony_ci if (ret) { 270d722e3fbSopenharmony_ci return ret; 271d722e3fbSopenharmony_ci } 272d722e3fbSopenharmony_ci 273d722e3fbSopenharmony_ci /* really all we need for now is mmap offset */ 274d722e3fbSopenharmony_ci bo->offset = req.offset; 275d722e3fbSopenharmony_ci bo->size = req.size; 276d722e3fbSopenharmony_ci 277d722e3fbSopenharmony_ci return 0; 278d722e3fbSopenharmony_ci} 279d722e3fbSopenharmony_ci 280d722e3fbSopenharmony_ci/* import a buffer object from DRI2 name */ 281d722e3fbSopenharmony_cidrm_public struct omap_bo * 282d722e3fbSopenharmony_ciomap_bo_from_name(struct omap_device *dev, uint32_t name) 283d722e3fbSopenharmony_ci{ 284d722e3fbSopenharmony_ci struct omap_bo *bo = NULL; 285d722e3fbSopenharmony_ci struct drm_gem_open req = { 286d722e3fbSopenharmony_ci .name = name, 287d722e3fbSopenharmony_ci }; 288d722e3fbSopenharmony_ci 289d722e3fbSopenharmony_ci pthread_mutex_lock(&table_lock); 290d722e3fbSopenharmony_ci 291d722e3fbSopenharmony_ci if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) { 292d722e3fbSopenharmony_ci goto fail; 293d722e3fbSopenharmony_ci } 294d722e3fbSopenharmony_ci 295d722e3fbSopenharmony_ci bo = lookup_bo(dev, req.handle); 296d722e3fbSopenharmony_ci if (!bo) { 297d722e3fbSopenharmony_ci bo = bo_from_handle(dev, req.handle); 298d722e3fbSopenharmony_ci bo->name = name; 299d722e3fbSopenharmony_ci } 300d722e3fbSopenharmony_ci 301d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 302d722e3fbSopenharmony_ci 303d722e3fbSopenharmony_ci return bo; 304d722e3fbSopenharmony_ci 305d722e3fbSopenharmony_cifail: 306d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 307d722e3fbSopenharmony_ci free(bo); 308d722e3fbSopenharmony_ci return NULL; 309d722e3fbSopenharmony_ci} 310d722e3fbSopenharmony_ci 311d722e3fbSopenharmony_ci/* import a buffer from dmabuf fd, does not take ownership of the 312d722e3fbSopenharmony_ci * fd so caller should close() the fd when it is otherwise done 313d722e3fbSopenharmony_ci * with it (even if it is still using the 'struct omap_bo *') 314d722e3fbSopenharmony_ci */ 315d722e3fbSopenharmony_cidrm_public struct omap_bo * 316d722e3fbSopenharmony_ciomap_bo_from_dmabuf(struct omap_device *dev, int fd) 317d722e3fbSopenharmony_ci{ 318d722e3fbSopenharmony_ci struct omap_bo *bo = NULL; 319d722e3fbSopenharmony_ci struct drm_prime_handle req = { 320d722e3fbSopenharmony_ci .fd = fd, 321d722e3fbSopenharmony_ci }; 322d722e3fbSopenharmony_ci int ret; 323d722e3fbSopenharmony_ci 324d722e3fbSopenharmony_ci pthread_mutex_lock(&table_lock); 325d722e3fbSopenharmony_ci 326d722e3fbSopenharmony_ci ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req); 327d722e3fbSopenharmony_ci if (ret) { 328d722e3fbSopenharmony_ci goto fail; 329d722e3fbSopenharmony_ci } 330d722e3fbSopenharmony_ci 331d722e3fbSopenharmony_ci bo = lookup_bo(dev, req.handle); 332d722e3fbSopenharmony_ci if (!bo) { 333d722e3fbSopenharmony_ci bo = bo_from_handle(dev, req.handle); 334d722e3fbSopenharmony_ci } 335d722e3fbSopenharmony_ci 336d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 337d722e3fbSopenharmony_ci 338d722e3fbSopenharmony_ci return bo; 339d722e3fbSopenharmony_ci 340d722e3fbSopenharmony_cifail: 341d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 342d722e3fbSopenharmony_ci free(bo); 343d722e3fbSopenharmony_ci return NULL; 344d722e3fbSopenharmony_ci} 345d722e3fbSopenharmony_ci 346d722e3fbSopenharmony_ci/* destroy a buffer object */ 347d722e3fbSopenharmony_cidrm_public void omap_bo_del(struct omap_bo *bo) 348d722e3fbSopenharmony_ci{ 349d722e3fbSopenharmony_ci if (!bo) { 350d722e3fbSopenharmony_ci return; 351d722e3fbSopenharmony_ci } 352d722e3fbSopenharmony_ci 353d722e3fbSopenharmony_ci if (!atomic_dec_and_test(&bo->refcnt)) 354d722e3fbSopenharmony_ci return; 355d722e3fbSopenharmony_ci 356d722e3fbSopenharmony_ci if (bo->map) { 357d722e3fbSopenharmony_ci munmap(bo->map, bo->size); 358d722e3fbSopenharmony_ci } 359d722e3fbSopenharmony_ci 360d722e3fbSopenharmony_ci if (bo->fd >= 0) { 361d722e3fbSopenharmony_ci close(bo->fd); 362d722e3fbSopenharmony_ci } 363d722e3fbSopenharmony_ci 364d722e3fbSopenharmony_ci if (bo->handle) { 365d722e3fbSopenharmony_ci pthread_mutex_lock(&table_lock); 366d722e3fbSopenharmony_ci drmHashDelete(bo->dev->handle_table, bo->handle); 367d722e3fbSopenharmony_ci drmCloseBufferHandle(bo->dev->fd, bo->handle); 368d722e3fbSopenharmony_ci pthread_mutex_unlock(&table_lock); 369d722e3fbSopenharmony_ci } 370d722e3fbSopenharmony_ci 371d722e3fbSopenharmony_ci omap_device_del(bo->dev); 372d722e3fbSopenharmony_ci 373d722e3fbSopenharmony_ci free(bo); 374d722e3fbSopenharmony_ci} 375d722e3fbSopenharmony_ci 376d722e3fbSopenharmony_ci/* get the global flink/DRI2 buffer name */ 377d722e3fbSopenharmony_cidrm_public int omap_bo_get_name(struct omap_bo *bo, uint32_t *name) 378d722e3fbSopenharmony_ci{ 379d722e3fbSopenharmony_ci if (!bo->name) { 380d722e3fbSopenharmony_ci struct drm_gem_flink req = { 381d722e3fbSopenharmony_ci .handle = bo->handle, 382d722e3fbSopenharmony_ci }; 383d722e3fbSopenharmony_ci int ret; 384d722e3fbSopenharmony_ci 385d722e3fbSopenharmony_ci ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req); 386d722e3fbSopenharmony_ci if (ret) { 387d722e3fbSopenharmony_ci return ret; 388d722e3fbSopenharmony_ci } 389d722e3fbSopenharmony_ci 390d722e3fbSopenharmony_ci bo->name = req.name; 391d722e3fbSopenharmony_ci } 392d722e3fbSopenharmony_ci 393d722e3fbSopenharmony_ci *name = bo->name; 394d722e3fbSopenharmony_ci 395d722e3fbSopenharmony_ci return 0; 396d722e3fbSopenharmony_ci} 397d722e3fbSopenharmony_ci 398d722e3fbSopenharmony_cidrm_public uint32_t omap_bo_handle(struct omap_bo *bo) 399d722e3fbSopenharmony_ci{ 400d722e3fbSopenharmony_ci return bo->handle; 401d722e3fbSopenharmony_ci} 402d722e3fbSopenharmony_ci 403d722e3fbSopenharmony_ci/* caller owns the dmabuf fd that is returned and is responsible 404d722e3fbSopenharmony_ci * to close() it when done 405d722e3fbSopenharmony_ci */ 406d722e3fbSopenharmony_cidrm_public int omap_bo_dmabuf(struct omap_bo *bo) 407d722e3fbSopenharmony_ci{ 408d722e3fbSopenharmony_ci if (bo->fd < 0) { 409d722e3fbSopenharmony_ci struct drm_prime_handle req = { 410d722e3fbSopenharmony_ci .handle = bo->handle, 411d722e3fbSopenharmony_ci .flags = DRM_CLOEXEC | DRM_RDWR, 412d722e3fbSopenharmony_ci }; 413d722e3fbSopenharmony_ci int ret; 414d722e3fbSopenharmony_ci 415d722e3fbSopenharmony_ci ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req); 416d722e3fbSopenharmony_ci if (ret) { 417d722e3fbSopenharmony_ci return ret; 418d722e3fbSopenharmony_ci } 419d722e3fbSopenharmony_ci 420d722e3fbSopenharmony_ci bo->fd = req.fd; 421d722e3fbSopenharmony_ci } 422d722e3fbSopenharmony_ci return dup(bo->fd); 423d722e3fbSopenharmony_ci} 424d722e3fbSopenharmony_ci 425d722e3fbSopenharmony_cidrm_public uint32_t omap_bo_size(struct omap_bo *bo) 426d722e3fbSopenharmony_ci{ 427d722e3fbSopenharmony_ci if (!bo->size) { 428d722e3fbSopenharmony_ci get_buffer_info(bo); 429d722e3fbSopenharmony_ci } 430d722e3fbSopenharmony_ci return bo->size; 431d722e3fbSopenharmony_ci} 432d722e3fbSopenharmony_ci 433d722e3fbSopenharmony_cidrm_public void *omap_bo_map(struct omap_bo *bo) 434d722e3fbSopenharmony_ci{ 435d722e3fbSopenharmony_ci if (!bo->map) { 436d722e3fbSopenharmony_ci if (!bo->offset) { 437d722e3fbSopenharmony_ci get_buffer_info(bo); 438d722e3fbSopenharmony_ci } 439d722e3fbSopenharmony_ci 440d722e3fbSopenharmony_ci bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE, 441d722e3fbSopenharmony_ci MAP_SHARED, bo->dev->fd, bo->offset); 442d722e3fbSopenharmony_ci if (bo->map == MAP_FAILED) { 443d722e3fbSopenharmony_ci bo->map = NULL; 444d722e3fbSopenharmony_ci } 445d722e3fbSopenharmony_ci } 446d722e3fbSopenharmony_ci return bo->map; 447d722e3fbSopenharmony_ci} 448d722e3fbSopenharmony_ci 449d722e3fbSopenharmony_cidrm_public int omap_bo_cpu_prep(struct omap_bo *bo, enum omap_gem_op op) 450d722e3fbSopenharmony_ci{ 451d722e3fbSopenharmony_ci struct drm_omap_gem_cpu_prep req = { 452d722e3fbSopenharmony_ci .handle = bo->handle, 453d722e3fbSopenharmony_ci .op = op, 454d722e3fbSopenharmony_ci }; 455d722e3fbSopenharmony_ci return drmCommandWrite(bo->dev->fd, 456d722e3fbSopenharmony_ci DRM_OMAP_GEM_CPU_PREP, &req, sizeof(req)); 457d722e3fbSopenharmony_ci} 458d722e3fbSopenharmony_ci 459d722e3fbSopenharmony_cidrm_public int omap_bo_cpu_fini(struct omap_bo *bo, enum omap_gem_op op) 460d722e3fbSopenharmony_ci{ 461d722e3fbSopenharmony_ci struct drm_omap_gem_cpu_fini req = { 462d722e3fbSopenharmony_ci .handle = bo->handle, 463d722e3fbSopenharmony_ci .op = op, 464d722e3fbSopenharmony_ci .nregions = 0, 465d722e3fbSopenharmony_ci }; 466d722e3fbSopenharmony_ci return drmCommandWrite(bo->dev->fd, 467d722e3fbSopenharmony_ci DRM_OMAP_GEM_CPU_FINI, &req, sizeof(req)); 468d722e3fbSopenharmony_ci} 469