1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
43 #include <sys/ioctl.h>
44 #include <sys/types.h>
51 #include <tbm_bufmgr.h>
52 #include <tbm_bufmgr_backend.h>
53 #include <drm/sprd_drm.h>
55 #include <tbm_surface.h>
56 #include <tbm_drm_helper.h>
59 #include "tbm_bufmgr_tgl.h"
61 //#define USE_CONTIG_ONLY
64 #define TBM_COLOR_FORMAT_COUNT 8
67 #define LOG_TAG "TBM_BACKEND"
69 static int bDebug = 0;
71 #define SPRD_DRM_NAME "sprd"
78 static int initialized = 0;
79 static char app_name[128];
84 /* get the application name */
85 f = fopen("/proc/self/cmdline", "r");
90 memset(app_name, 0x00, sizeof(app_name));
92 if (fgets(app_name, 100, f) == NULL) {
99 if ((slash = strrchr(app_name, '/')) != NULL)
100 memmove(app_name, slash + 1, strlen(slash));
106 #define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args)
107 #define DBG(fmt, args...) if (bDebug&01) LOGE("[%s]" fmt, target_name(), ##args)
109 #define TBM_SPRD_LOG(...)
113 #define SIZE_ALIGN(value, base) (((value) + ((base) - 1)) & ~((base) - 1))
115 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
116 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128)
117 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
120 /* check condition */
121 #define SPRD_RETURN_IF_FAIL(cond) {\
123 TBM_SPRD_LOG("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
127 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
129 TBM_SPRD_LOG("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
134 struct dma_buf_info {
136 unsigned int fence_supported;
137 unsigned int padding;
140 #define DMA_BUF_ACCESS_READ 0x1
141 #define DMA_BUF_ACCESS_WRITE 0x2
142 #define DMA_BUF_ACCESS_DMA 0x4
143 #define DMA_BUF_ACCESS_MAX 0x8
145 #define DMA_FENCE_LIST_MAX 5
147 struct dma_buf_fence {
152 #define DMABUF_IOCTL_BASE 'F'
153 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
155 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
156 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
157 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
160 #define GLOBAL_KEY ((unsigned int)(-1))
162 #define TBM_SPRD_CACHE_INV 0x01 /**< cache invalidate */
163 #define TBM_SPRD_CACHE_CLN 0x02 /**< cache clean */
164 #define TBM_SPRD_CACHE_ALL 0x10 /**< cache all */
165 #define TBM_SPRD_CACHE_FLUSH (TBM_SPRD_CACHE_INV|TBM_SPRD_CACHE_CLN) /**< cache flush */
166 #define TBM_SPRD_CACHE_FLUSH_ALL (TBM_SPRD_CACHE_FLUSH|TBM_SPRD_CACHE_ALL) /**< cache flush all */
170 DEVICE_CA, /* cache aware device */
171 DEVICE_CO /* cache oblivious device */
174 typedef union _tbm_bo_cache_state tbm_bo_cache_state;
176 union _tbm_bo_cache_state {
179 unsigned int cntFlush:16; /*Flush all index for sync */
180 unsigned int isCached:1;
181 unsigned int isDirtied:2;
185 typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd;
186 typedef struct _tbm_bo_sprd *tbm_bo_sprd;
188 typedef struct _sprd_private {
190 struct _tbm_bo_sprd *bo_priv;
193 /* tbm buffor object for sprd */
194 struct _tbm_bo_sprd {
197 unsigned int name; /* FLINK ID */
199 unsigned int gem; /* GEM Handle */
201 unsigned int dmabuf; /* fd for dmabuf */
203 void *pBase; /* virtual address */
207 unsigned int flags_sprd;
208 unsigned int flags_tbm;
212 pthread_mutex_t mutex;
213 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
217 tbm_bo_cache_state cache_state;
218 unsigned int map_cnt;
221 /* tbm bufmgr private for sprd */
222 struct _tbm_bufmgr_sprd {
234 char *STR_DEVICE[] = {
250 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
261 _tgl_init(int fd, unsigned int key)
263 struct tgl_attribute attr;
267 attr.timeout_ms = 1000;
269 err = ioctl(fd, TGL_IOC_INIT_LOCK, &attr);
271 TBM_SPRD_LOG("[libtbm-sprd:%d] error(%s) %s:%d key:%d\n",
272 getpid(), strerror(errno), __func__, __LINE__, key);
280 _tgl_destroy(int fd, unsigned int key)
284 err = ioctl(fd, TGL_IOC_DESTROY_LOCK, key);
286 TBM_SPRD_LOG("[libtbm-sprd:%d] "
287 "error(%s) %s:%d key:%d\n",
288 getpid(), strerror(errno), __func__, __LINE__, key);
296 _tgl_lock(int fd, unsigned int key)
300 err = ioctl(fd, TGL_IOC_LOCK_LOCK, key);
302 TBM_SPRD_LOG("[libtbm-sprd:%d] "
303 "error(%s) %s:%d key:%d\n",
304 getpid(), strerror(errno), __func__, __LINE__, key);
312 _tgl_unlock(int fd, unsigned int key)
316 err = ioctl(fd, TGL_IOC_UNLOCK_LOCK, key);
318 TBM_SPRD_LOG("[libtbm-sprd:%d] "
319 "error(%s) %s:%d key:%d\n",
320 getpid(), strerror(errno), __func__, __LINE__, key);
329 _tgl_set_data(int fd, unsigned int key, unsigned int val)
332 struct tgl_user_data arg;
336 err = ioctl(fd, TGL_IOC_SET_DATA, &arg);
338 TBM_SPRD_LOG("[libtbm-sprd:%d] "
339 "error(%s) %s:%d key:%d\n",
340 getpid(), strerror(errno), __func__, __LINE__, key);
347 static inline unsigned int
348 _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
351 struct tgl_user_data arg = { 0, };
354 err = ioctl(fd, TGL_IOC_GET_DATA, &arg);
356 TBM_SPRD_LOG("[libtbm-sprd:%d] "
357 "error(%s) %s:%d key:%d\n",
358 getpid(), strerror(errno), __func__, __LINE__, key);
363 *locked = arg.locked;
374 fd = drmOpen(SPRD_DRM_NAME, NULL);
376 TBM_SPRD_LOG("[libtbm-sprd:%d] "
377 "warning %s:%d fail to open drm\n",
378 getpid(), __FUNCTION__, __LINE__);
383 struct udev *udev = NULL;
384 struct udev_enumerate *e = NULL;
385 struct udev_list_entry *entry = NULL;
386 struct udev_device *device = NULL, *drm_device = NULL, *device_parent = NULL;
387 const char *filepath;
391 TBM_SPRD_LOG("[libtbm-sprd:%d] "
392 "%s:%d search drm-device by udev\n",
393 getpid(), __FUNCTION__, __LINE__);
397 TBM_SPRD_LOG("udev_new() failed.\n");
401 e = udev_enumerate_new(udev);
402 udev_enumerate_add_match_subsystem(e, "drm");
403 udev_enumerate_add_match_sysname(e, "card[0-9]*");
404 udev_enumerate_scan_devices(e);
406 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
407 device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
408 udev_list_entry_get_name(entry));
409 device_parent = udev_device_get_parent(device);
410 /* Not need unref device_parent. device_parent and device have same refcnt */
412 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
414 DBG("[%s] Found render device: '%s' (%s)\n",
416 udev_device_get_syspath(drm_device),
417 udev_device_get_sysname(device_parent));
421 udev_device_unref(device);
424 udev_enumerate_unref(e);
426 /* Get device file path. */
427 filepath = udev_device_get_devnode(drm_device);
429 TBM_SPRD_LOG("udev_device_get_devnode() failed.\n");
430 udev_device_unref(drm_device);
435 /* Open DRM device file and check validity. */
436 fd = open(filepath, O_RDWR | O_CLOEXEC);
438 TBM_SPRD_LOG("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
439 udev_device_unref(drm_device);
446 TBM_SPRD_LOG("fstat() failed %s.\n");
448 udev_device_unref(drm_device);
453 udev_device_unref(drm_device);
463 _sprd_bo_cache_flush(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int flags)
465 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
466 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
468 /* cache flush is managed by kernel side when using dma-fence. */
469 if (bufmgr_sprd->use_dma_fence)
472 struct drm_sprd_gem_cache_op cache_op = {0, };
475 /* if bo_sprd is null, do cache_flush_all */
478 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
479 cache_op.size = bo_sprd->size;
481 flags = TBM_SPRD_CACHE_FLUSH_ALL;
483 cache_op.usr_addr = 0;
487 if (flags & TBM_SPRD_CACHE_INV) {
488 if (flags & TBM_SPRD_CACHE_ALL)
489 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
491 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
494 if (flags & TBM_SPRD_CACHE_CLN) {
495 if (flags & TBM_SPRD_CACHE_ALL)
496 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
498 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
501 if (flags & TBM_SPRD_CACHE_ALL)
502 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
504 ret = drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
507 TBM_SPRD_LOG("[libtbm-sprd:%d] "
508 "error %s:%d fail to flush the cache.\n",
509 getpid(), __FUNCTION__, __LINE__);
518 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int import)
520 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
521 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
523 if (bufmgr_sprd->use_dma_fence)
526 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
529 tbm_bo_cache_state cache_state;
532 cache_state.data.isDirtied = DEVICE_NONE;
533 cache_state.data.isCached = 0;
534 cache_state.data.cntFlush = 0;
536 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
544 _bo_set_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int device, int opt)
547 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
548 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
551 unsigned short cntFlush = 0;
553 if (bufmgr_sprd->use_dma_fence)
556 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
559 /* get cache state of a bo */
560 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
562 /* get global cache flush count */
563 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
565 if (opt == TBM_DEVICE_CPU) {
566 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
567 bo_sprd->cache_state.data.isCached)
568 need_flush = TBM_SPRD_CACHE_INV;
570 bo_sprd->cache_state.data.isCached = 1;
571 if (opt & TBM_OPTION_WRITE)
572 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
574 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
575 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
578 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
579 bo_sprd->cache_state.data.isCached &&
580 bo_sprd->cache_state.data.cntFlush == cntFlush)
581 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
583 if (opt & TBM_OPTION_WRITE)
584 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
586 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
587 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
592 if (need_flush & TBM_SPRD_CACHE_ALL)
593 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
595 /* call cache flush */
596 _sprd_bo_cache_flush(bufmgr_sprd, bo_sprd, need_flush);
598 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
600 bo_sprd->cache_state.data.isCached,
601 bo_sprd->cache_state.data.isDirtied,
611 _bo_save_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
614 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
615 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
617 if (bufmgr_sprd->use_dma_fence)
620 unsigned short cntFlush = 0;
622 /* get global cache flush count */
623 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
625 /* save global cache flush count */
626 bo_sprd->cache_state.data.cntFlush = cntFlush;
627 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
634 _bo_destroy_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
636 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
637 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
639 if (bufmgr_sprd->use_dma_fence)
642 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
646 _bufmgr_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
648 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
650 if (bufmgr_sprd->use_dma_fence)
653 /* open tgl fd for saving cache flush data */
654 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
656 if (bufmgr_sprd->tgl_fd < 0) {
657 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
658 if (bufmgr_sprd->tgl_fd < 0) {
659 TBM_SPRD_LOG("[libtbm-sprd:%d] "
660 "error: Fail to open global_lock:%s\n",
661 getpid(), tgl_devfile);
667 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
668 TBM_SPRD_LOG("[libtbm-sprd:%d] "
669 "error: Fail to initialize the tgl\n",
672 close(bufmgr_sprd->tgl_fd);
681 _bufmgr_deinit_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
683 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
685 if (bufmgr_sprd->use_dma_fence)
688 if (bufmgr_sprd->tgl_fd >= 0)
689 close(bufmgr_sprd->tgl_fd);
692 #ifndef USE_CONTIG_ONLY
694 _get_sprd_flag_from_tbm(unsigned int ftbm)
696 unsigned int flags = 0;
699 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
700 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
701 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
702 * To be updated appropriately once DRM-GEM supports different heap id masks.
705 if (ftbm & TBM_BO_SCANOUT)
706 flags = SPRD_BO_CONTIG;
708 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
710 if (ftbm & TBM_BO_WC)
712 else if (ftbm & TBM_BO_NONCACHABLE)
713 flags |= SPRD_BO_NONCACHABLE;
719 _get_tbm_flag_from_sprd(unsigned int fsprd)
721 unsigned int flags = 0;
723 if (fsprd & SPRD_BO_NONCONTIG)
724 flags |= TBM_BO_DEFAULT;
726 flags |= TBM_BO_SCANOUT;
728 if (fsprd & SPRD_BO_WC)
730 else if (fsprd & SPRD_BO_CACHABLE)
731 flags |= TBM_BO_DEFAULT;
733 flags |= TBM_BO_NONCACHABLE;
740 _get_name(int fd, unsigned int gem)
742 struct drm_gem_flink arg = {0,};
745 if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
746 TBM_SPRD_LOG("[libtbm-sprd:%d] "
747 "error %s:%d fail to get flink gem=%d\n",
748 getpid(), __FUNCTION__, __LINE__, gem);
752 return (unsigned int)arg.name;
756 _sprd_bo_handle(tbm_bo_sprd bo_sprd, int device)
758 tbm_bo_handle bo_handle;
759 memset(&bo_handle, 0x0, sizeof(uint64_t));
762 case TBM_DEVICE_DEFAULT:
764 bo_handle.u32 = (uint32_t)bo_sprd->gem;
767 if (!bo_sprd->pBase) {
768 struct drm_sprd_gem_mmap arg = {0,};
770 arg.handle = bo_sprd->gem;
771 arg.size = bo_sprd->size;
772 if (drmCommandWriteRead(bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
773 TBM_SPRD_LOG("[libtbm-sprd:%d] "
774 "error %s:%d Cannot usrptr gem=%d\n",
775 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
776 return (tbm_bo_handle) NULL;
778 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
781 bo_handle.ptr = (void *)bo_sprd->pBase;
785 if (!bo_sprd->dmabuf) {
786 struct drm_prime_handle arg = {0, };
787 arg.handle = bo_sprd->gem;
788 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
789 TBM_SPRD_LOG("[libtbm-sprd:%d] "
790 "error %s:%d Cannot dmabuf=%d\n",
791 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
792 return (tbm_bo_handle) NULL;
794 bo_sprd->dmabuf = arg.fd;
797 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
804 //TODO : Add ioctl for GSP MAP once available.
805 DBG("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
810 if (!bo_sprd->dmabuf) {
811 struct drm_prime_handle arg = {0, };
813 arg.handle = bo_sprd->gem;
814 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
815 TBM_SPRD_LOG("[libtbm-sprd:%d] "
816 "error %s:%d Cannot dmabuf=%d\n",
817 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
818 return (tbm_bo_handle) NULL;
820 bo_sprd->dmabuf = arg.fd;
823 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
827 bo_handle.ptr = (void *) NULL;
835 tbm_sprd_bo_size(tbm_bo bo)
837 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
841 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
843 return bo_sprd->size;
847 tbm_sprd_bo_alloc(tbm_bo bo, int size, int flags)
849 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
852 tbm_bufmgr_sprd bufmgr_sprd;
853 unsigned int sprd_flags;
855 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
856 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
858 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
860 TBM_SPRD_LOG("[libtbm-sprd:%d] "
861 "error %s:%d fail to allocate the bo private\n",
862 getpid(), __FUNCTION__, __LINE__);
866 #ifdef USE_CONTIG_ONLY
867 flags = TBM_BO_SCANOUT;
868 sprd_flags = SPRD_BO_CONTIG;
870 sprd_flags = _get_sprd_flag_from_tbm(flags);
871 if ((flags & TBM_BO_SCANOUT) &&
873 sprd_flags |= SPRD_BO_NONCONTIG;
875 #endif // USE_CONTIG_ONLY
876 struct drm_sprd_gem_create arg = {0, };
877 arg.size = (uint64_t)size;
878 arg.flags = sprd_flags;
879 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
881 TBM_SPRD_LOG("[libtbm-sprd:%d] "
882 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
883 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
888 bo_sprd->fd = bufmgr_sprd->fd;
889 bo_sprd->gem = arg.handle;
890 bo_sprd->size = size;
891 bo_sprd->flags_tbm = flags;
892 bo_sprd->flags_sprd = sprd_flags;
893 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
895 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 0)) {
896 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
901 pthread_mutex_init(&bo_sprd->mutex, NULL);
903 if (bufmgr_sprd->use_dma_fence
904 && !bo_sprd->dmabuf) {
905 struct drm_prime_handle arg = {0, };
907 arg.handle = bo_sprd->gem;
908 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
909 TBM_SPRD_LOG("[libtbm-sprd:%d] "
910 "error %s:%d Cannot dmabuf=%d\n",
911 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
915 bo_sprd->dmabuf = arg.fd;
919 PrivGem *privGem = calloc(1, sizeof(PrivGem));
920 privGem->ref_count = 1;
921 privGem->bo_priv = bo_sprd;
922 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
923 TBM_SPRD_LOG("[libtbm-sprd:%d] "
924 "error %s:%d Cannot insert bo to Hash(%d)\n",
925 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
928 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
929 __FUNCTION__, bo_sprd->size,
930 bo_sprd->gem, bo_sprd->name,
933 return (void *)bo_sprd;
937 tbm_sprd_bo_free(tbm_bo bo)
940 tbm_bufmgr_sprd bufmgr_sprd;
945 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
946 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
948 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
949 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
951 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
952 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
954 if (bo_sprd->pBase) {
955 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
956 TBM_SPRD_LOG("[libtbm-sprd:%d] "
958 getpid(), __FUNCTION__, __LINE__);
963 if (bo_sprd->dmabuf) {
964 close(bo_sprd->dmabuf);
968 /* delete bo from hash */
969 PrivGem *privGem = NULL;
972 ret = drmHashLookup(bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
974 privGem->ref_count--;
975 if (privGem->ref_count == 0) {
976 drmHashDelete(bufmgr_sprd->hashBos, bo_sprd->name);
981 TBM_SPRD_LOG("[libtbm-sprd:%d] "
982 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
983 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
986 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
988 /* Free gem handle */
989 struct drm_gem_close arg = {0, };
990 memset(&arg, 0, sizeof(arg));
991 arg.handle = bo_sprd->gem;
992 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
993 TBM_SPRD_LOG("[libtbm-sprd:%d] "
995 getpid(), __FUNCTION__, __LINE__);
1003 tbm_sprd_bo_import(tbm_bo bo, unsigned int key)
1005 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1007 tbm_bufmgr_sprd bufmgr_sprd;
1008 tbm_bo_sprd bo_sprd;
1009 PrivGem *privGem = NULL;
1012 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1013 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1015 ret = drmHashLookup(bufmgr_sprd->hashBos, key, (void **)&privGem);
1017 return privGem->bo_priv;
1019 struct drm_gem_open arg = {0, };
1020 struct drm_sprd_gem_info info = {0, };
1023 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
1024 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1025 "error %s:%d Cannot open gem name=%d\n",
1026 getpid(), __FUNCTION__, __LINE__, key);
1030 info.handle = arg.handle;
1031 if (drmCommandWriteRead(bufmgr_sprd->fd,
1034 sizeof(struct drm_sprd_gem_info))) {
1035 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1036 "error %s:%d Cannot get gem info=%d\n",
1037 getpid(), __FUNCTION__, __LINE__, key);
1041 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1043 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1044 "error %s:%d fail to allocate the bo private\n",
1045 getpid(), __FUNCTION__, __LINE__);
1049 bo_sprd->fd = bufmgr_sprd->fd;
1050 bo_sprd->gem = arg.handle;
1051 bo_sprd->size = arg.size;
1052 bo_sprd->flags_sprd = info.flags;
1053 bo_sprd->name = key;
1054 #ifdef USE_CONTIG_ONLY
1055 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1056 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1058 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1061 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1062 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
1067 if (!bo_sprd->dmabuf) {
1068 struct drm_prime_handle arg = {0, };
1070 arg.handle = bo_sprd->gem;
1071 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1072 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1073 "error %s:%d Cannot dmabuf=%d\n",
1074 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1078 bo_sprd->dmabuf = arg.fd;
1081 /* add bo to hash */
1082 privGem = calloc(1, sizeof(PrivGem));
1083 privGem->ref_count = 1;
1084 privGem->bo_priv = bo_sprd;
1085 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1086 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1087 "error %s:%d Cannot insert bo to Hash(%d)\n",
1088 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1091 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1092 __FUNCTION__, bo_sprd->size,
1093 bo_sprd->gem, bo_sprd->name,
1094 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1096 return (void *)bo_sprd;
1100 tbm_sprd_bo_import_fd(tbm_bo bo, tbm_fd key)
1102 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1104 tbm_bufmgr_sprd bufmgr_sprd;
1105 tbm_bo_sprd bo_sprd;
1106 PrivGem *privGem = NULL;
1110 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1111 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1113 //getting handle from fd
1114 unsigned int gem = 0;
1115 struct drm_prime_handle arg = {0, };
1119 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1120 TBM_SPRD_LOG("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1121 bo, arg.fd, strerror(errno));
1126 name = _get_name(bufmgr_sprd->fd, gem);
1128 ret = drmHashLookup(bufmgr_sprd->hashBos, name, (void **)&privGem);
1130 if (gem == privGem->bo_priv->gem)
1131 return privGem->bo_priv;
1134 unsigned int real_size = -1;
1135 struct drm_sprd_gem_info info = {0, };
1137 /* Determine size of bo. The fd-to-handle ioctl really should
1138 * return the size, but it doesn't. If we have kernel 3.12 or
1139 * later, we can lseek on the prime fd to get the size. Older
1140 * kernels will just fail, in which case we fall back to the
1141 * provided (estimated or guess size). */
1142 real_size = lseek(key, 0, SEEK_END);
1145 if (drmCommandWriteRead(bufmgr_sprd->fd,
1148 sizeof(struct drm_sprd_gem_info))) {
1149 TBM_SPRD_LOG("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1150 bo, gem, key, strerror(errno));
1154 if (real_size == -1)
1155 real_size = info.size;
1157 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1159 TBM_SPRD_LOG("error bo:%p fail to allocate the bo private\n", bo);
1163 bo_sprd->fd = bufmgr_sprd->fd;
1165 bo_sprd->size = real_size;
1166 bo_sprd->flags_sprd = info.flags;
1167 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1169 bo_sprd->name = name;
1170 if (!bo_sprd->name) {
1171 TBM_SPRD_LOG("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1172 bo, gem, key, strerror(errno));
1177 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1178 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
1183 /* add bo to hash */
1186 privGem = calloc(1, sizeof(PrivGem));
1188 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1189 "error %s:%d Fail to callocprivGem\n",
1190 getpid(), __FUNCTION__, __LINE__);
1195 privGem->ref_count = 1;
1196 privGem->bo_priv = bo_sprd;
1197 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1198 TBM_SPRD_LOG("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1199 bo, bo_sprd->name, gem, key);
1202 DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1205 bo_sprd->gem, bo_sprd->name,
1208 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1211 return (void *)bo_sprd;
1215 tbm_sprd_bo_export(tbm_bo bo)
1217 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1219 tbm_bo_sprd bo_sprd;
1221 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1222 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1224 if (!bo_sprd->name) {
1225 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1226 if (!bo_sprd->name) {
1227 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1228 "error %s:%d Cannot get name\n",
1229 getpid(), __FUNCTION__, __LINE__);
1234 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1235 __FUNCTION__, bo_sprd->size,
1236 bo_sprd->gem, bo_sprd->name,
1237 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1239 return (unsigned int)bo_sprd->name;
1243 tbm_sprd_bo_export_fd(tbm_bo bo)
1245 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, -1);
1247 tbm_bo_sprd bo_sprd;
1250 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1251 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, -1);
1253 struct drm_prime_handle arg = {0, };
1255 arg.handle = bo_sprd->gem;
1256 ret = drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1258 TBM_SPRD_LOG("error bo:%p Cannot dmabuf=%d (%s)\n",
1259 bo, bo_sprd->gem, strerror(errno));
1260 return (tbm_fd) ret;
1263 DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1266 bo_sprd->gem, bo_sprd->name,
1269 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1272 return (tbm_fd)arg.fd;
1276 static tbm_bo_handle
1277 tbm_sprd_bo_get_handle(tbm_bo bo, int device)
1279 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1281 tbm_bo_handle bo_handle;
1282 tbm_bo_sprd bo_sprd;
1284 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1285 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1287 if (!bo_sprd->gem) {
1288 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1289 "error %s:%d Cannot map gem=%d\n",
1290 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1291 return (tbm_bo_handle) NULL;
1294 DBG("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1295 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1297 /*Get mapped bo_handle*/
1298 bo_handle = _sprd_bo_handle(bo_sprd, device);
1299 if (bo_handle.ptr == NULL) {
1300 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1301 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1302 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1303 return (tbm_bo_handle) NULL;
1309 static tbm_bo_handle
1310 tbm_sprd_bo_map(tbm_bo bo, int device, int opt)
1312 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1314 tbm_bo_handle bo_handle;
1315 tbm_bo_sprd bo_sprd;
1316 tbm_bufmgr_sprd bufmgr_sprd;
1318 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1319 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, (tbm_bo_handle) NULL);
1321 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1322 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1324 if (!bo_sprd->gem) {
1325 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1326 "error %s:%d Cannot map gem=%d\n",
1327 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1328 return (tbm_bo_handle) NULL;
1331 DBG("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1332 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1334 /*Get mapped bo_handle*/
1335 bo_handle = _sprd_bo_handle(bo_sprd, device);
1336 if (bo_handle.ptr == NULL) {
1337 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1338 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1339 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1340 return (tbm_bo_handle) NULL;
1343 if (bo_sprd->map_cnt == 0)
1344 _bo_set_cache_state(bufmgr_sprd, bo_sprd, device, opt);
1352 tbm_sprd_bo_unmap(tbm_bo bo)
1354 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1356 tbm_bo_sprd bo_sprd;
1357 tbm_bufmgr_sprd bufmgr_sprd;
1359 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1360 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1362 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1363 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1370 if (bo_sprd->map_cnt == 0)
1371 _bo_save_cache_state(bufmgr_sprd, bo_sprd);
1373 DBG("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1374 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1380 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1382 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1384 tbm_bufmgr_sprd bufmgr_sprd;
1385 tbm_bo_sprd bo_sprd;
1387 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1388 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1390 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1391 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1393 #if USE_BACKEND_LOCK
1396 if (bufmgr_sprd->use_dma_fence) {
1398 struct dma_buf_fence fence;
1400 memset(&fence, 0, sizeof(struct dma_buf_fence));
1402 /* Check if the given type is valid or not. */
1403 if (opt & TBM_OPTION_WRITE) {
1404 if (device == TBM_DEVICE_CPU)
1405 fence.type = DMA_BUF_ACCESS_WRITE;
1406 else if (device == TBM_DEVICE_3D)
1407 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1409 DBG("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1410 getpid(), __FUNCTION__);
1413 } else if (opt & TBM_OPTION_READ) {
1414 if (device == TBM_DEVICE_CPU)
1415 fence.type = DMA_BUF_ACCESS_READ;
1416 else if (device == TBM_DEVICE_3D)
1417 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1419 DBG("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1420 getpid(), __FUNCTION__);
1424 TBM_SPRD_LOG("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1425 __FUNCTION__, __LINE__);
1429 /* Check if the tbm manager supports dma fence or not. */
1430 if (!bufmgr_sprd->use_dma_fence) {
1431 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1432 "error %s:%d Not support DMA FENCE(%s)\n",
1433 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1438 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1440 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1441 "error %s:%d Can not set GET FENCE(%s)\n",
1442 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1446 pthread_mutex_lock(&bo_sprd->mutex);
1448 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1449 if (bo_sprd->dma_fence[i].ctx == 0) {
1450 bo_sprd->dma_fence[i].type = fence.type;
1451 bo_sprd->dma_fence[i].ctx = fence.ctx;
1455 if (i == DMA_FENCE_LIST_MAX) {
1456 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1457 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1458 "error %s:%d fence list is full\n",
1459 getpid(), __FUNCTION__, __LINE__);
1461 pthread_mutex_unlock(&bo_sprd->mutex);
1463 DBG("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1465 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1468 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1470 DBG("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1471 getpid(), __FUNCTION__, bo_sprd->name);
1481 tbm_sprd_bo_unlock(tbm_bo bo)
1483 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1485 tbm_bufmgr_sprd bufmgr_sprd;
1486 tbm_bo_sprd bo_sprd;
1488 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1489 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1491 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1492 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1494 #if USE_BACKEND_LOCK
1497 if (bufmgr_sprd->use_dma_fence) {
1498 struct dma_buf_fence fence;
1500 if (!bo_sprd->dma_fence[0].ctx) {
1501 DBG("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1506 if (!bo_sprd->dma_fence[0].type) {
1507 DBG("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1512 pthread_mutex_lock(&bo_sprd->mutex);
1513 fence.type = bo_sprd->dma_fence[0].type;
1514 fence.ctx = bo_sprd->dma_fence[0].ctx;
1516 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1517 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1518 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1520 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1521 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1522 pthread_mutex_unlock(&bo_sprd->mutex);
1524 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1526 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1527 "error %s:%d Can not set PUT FENCE(%s)\n",
1528 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1532 DBG("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1534 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1536 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1538 DBG("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1539 getpid(), __FUNCTION__, bo_sprd->name);
1549 tbm_sprd_bufmgr_deinit(void *priv)
1551 SPRD_RETURN_IF_FAIL(priv != NULL);
1553 tbm_bufmgr_sprd bufmgr_sprd;
1555 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1557 if (bufmgr_sprd->hashBos) {
1561 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1563 drmHashDelete(bufmgr_sprd->hashBos, key);
1566 drmHashDestroy(bufmgr_sprd->hashBos);
1567 bufmgr_sprd->hashBos = NULL;
1570 if (bufmgr_sprd->bind_display)
1571 tbm_drm_helper_wl_auth_server_deinit();
1573 if (tbm_backend_is_display_server())
1574 tbm_drm_helper_unset_tbm_master_fd();
1576 if (bufmgr_sprd->device_name)
1577 free(bufmgr_sprd->device_name);
1579 _bufmgr_deinit_cache_state(bufmgr_sprd);
1581 close(bufmgr_sprd->fd);
1587 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1589 uint32_t *color_formats = NULL;
1591 color_formats = (uint32_t *)calloc(1,
1592 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1594 if (color_formats == NULL)
1597 memcpy(color_formats, tbm_sprd_color_format_list,
1598 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1601 *formats = color_formats;
1602 *num = TBM_COLOR_FORMAT_COUNT;
1610 * @brief get the plane data of the surface.
1611 * @param[in] width : the width of the surface
1612 * @param[in] height : the height of the surface
1613 * @param[in] format : the format of the surface
1614 * @param[in] plane_idx : the format of the surface
1615 * @param[out] size : the size of the plane
1616 * @param[out] offset : the offset of the plane
1617 * @param[out] pitch : the pitch of the plane
1618 * @param[out] padding : the padding of the plane
1619 * @return 1 if this function succeeds, otherwise 0.
1622 tbm_sprd_surface_get_plane_data(int width, int height,
1623 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1624 uint32_t *pitch, int *bo_idx)
1632 int _align_height = 0;
1636 case TBM_FORMAT_XRGB4444:
1637 case TBM_FORMAT_XBGR4444:
1638 case TBM_FORMAT_RGBX4444:
1639 case TBM_FORMAT_BGRX4444:
1640 case TBM_FORMAT_ARGB4444:
1641 case TBM_FORMAT_ABGR4444:
1642 case TBM_FORMAT_RGBA4444:
1643 case TBM_FORMAT_BGRA4444:
1644 case TBM_FORMAT_XRGB1555:
1645 case TBM_FORMAT_XBGR1555:
1646 case TBM_FORMAT_RGBX5551:
1647 case TBM_FORMAT_BGRX5551:
1648 case TBM_FORMAT_ARGB1555:
1649 case TBM_FORMAT_ABGR1555:
1650 case TBM_FORMAT_RGBA5551:
1651 case TBM_FORMAT_BGRA5551:
1652 case TBM_FORMAT_RGB565:
1655 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1656 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1660 case TBM_FORMAT_RGB888:
1661 case TBM_FORMAT_BGR888:
1664 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1665 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1669 case TBM_FORMAT_XRGB8888:
1670 case TBM_FORMAT_XBGR8888:
1671 case TBM_FORMAT_RGBX8888:
1672 case TBM_FORMAT_BGRX8888:
1673 case TBM_FORMAT_ARGB8888:
1674 case TBM_FORMAT_ABGR8888:
1675 case TBM_FORMAT_RGBA8888:
1676 case TBM_FORMAT_BGRA8888:
1679 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1680 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1685 case TBM_FORMAT_YUYV:
1686 case TBM_FORMAT_YVYU:
1687 case TBM_FORMAT_UYVY:
1688 case TBM_FORMAT_VYUY:
1689 case TBM_FORMAT_AYUV:
1692 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1693 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1699 * index 0 = Y plane, [7:0] Y
1700 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1702 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1704 case TBM_FORMAT_NV12:
1705 case TBM_FORMAT_NV21:
1707 if (plane_idx == 0) {
1709 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1710 _align_height = SIZE_ALIGN(height, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1711 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1713 } else if (plane_idx == 1) {
1714 _offset = width * height;
1715 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1716 _align_height = SIZE_ALIGN(height / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1717 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1722 case TBM_FORMAT_NV16:
1723 case TBM_FORMAT_NV61:
1725 //if(plane_idx == 0)
1728 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1729 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1734 //else if( plane_idx ==1 )
1737 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1738 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1745 * index 0: Y plane, [7:0] Y
1746 * index 1: Cb plane, [7:0] Cb
1747 * index 2: Cr plane, [7:0] Cr
1749 * index 1: Cr plane, [7:0] Cr
1750 * index 2: Cb plane, [7:0] Cb
1753 NATIVE_BUFFER_FORMAT_YV12
1754 NATIVE_BUFFER_FORMAT_I420
1756 case TBM_FORMAT_YUV410:
1757 case TBM_FORMAT_YVU410:
1760 case TBM_FORMAT_YUV411:
1761 case TBM_FORMAT_YVU411:
1762 case TBM_FORMAT_YUV420:
1763 case TBM_FORMAT_YVU420:
1765 //if(plane_idx == 0)
1768 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1769 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1774 //else if( plane_idx == 1 )
1777 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1778 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1783 //else if (plane_idx == 2 )
1786 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1787 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1791 case TBM_FORMAT_YUV422:
1792 case TBM_FORMAT_YVU422:
1794 //if(plane_idx == 0)
1797 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1798 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1803 //else if( plane_idx == 1 )
1806 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1807 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1812 //else if (plane_idx == 2 )
1815 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1816 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1820 case TBM_FORMAT_YUV444:
1821 case TBM_FORMAT_YVU444:
1823 //if(plane_idx == 0)
1826 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1827 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1832 //else if( plane_idx == 1 )
1835 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1836 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1841 //else if (plane_idx == 2 )
1844 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1845 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1863 tbm_sprd_bo_get_flags(tbm_bo bo)
1865 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1867 tbm_bo_sprd bo_sprd;
1869 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1870 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1872 return bo_sprd->flags_tbm;
1876 tbm_sprd_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1878 tbm_bufmgr_sprd bufmgr_sprd;
1880 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1881 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1883 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1884 bufmgr_sprd->device_name, 0)) {
1885 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1889 bufmgr_sprd->bind_display = NativeDisplay;
1894 MODULEINITPPROTO(init_tbm_bufmgr_priv);
1896 static TBMModuleVersionInfo SprdVersRec = {
1902 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1905 init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd)
1907 tbm_bufmgr_sprd bufmgr_sprd;
1908 tbm_bufmgr_backend bufmgr_backend;
1913 bufmgr_sprd = calloc(1, sizeof(struct _tbm_bufmgr_sprd));
1915 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1919 if (tbm_backend_is_display_server()) {
1920 bufmgr_sprd->fd = -1;
1922 bufmgr_sprd->fd = tbm_drm_helper_get_master_fd();
1923 if (bufmgr_sprd->fd < 0)
1924 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1926 if (bufmgr_sprd->fd < 0) {
1927 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1932 tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
1934 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1936 if (!bufmgr_sprd->device_name) {
1937 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1938 tbm_drm_helper_unset_tbm_master_fd();
1939 close(bufmgr_sprd->fd);
1945 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1946 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1953 bufmgr_sprd->hashBos = drmHashCreate();
1955 //Check if the tbm manager supports dma fence or not.
1956 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1960 length = read(fp, buf, 1);
1962 if (length == 1 && buf[0] == '1')
1963 bufmgr_sprd->use_dma_fence = 1;
1968 if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
1969 TBM_SPRD_LOG("[libtbm-sprd:%d] error: init bufmgr cache state failed!\n", getpid());
1971 if (tbm_backend_is_display_server())
1972 tbm_drm_helper_unset_tbm_master_fd();
1974 close(bufmgr_sprd->fd);
1980 bufmgr_backend = tbm_backend_alloc();
1981 if (!bufmgr_backend) {
1982 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1984 _bufmgr_deinit_cache_state(bufmgr_sprd);
1986 if (tbm_backend_is_display_server())
1987 tbm_drm_helper_unset_tbm_master_fd();
1989 close(bufmgr_sprd->fd);
1995 bufmgr_backend->priv = (void *)bufmgr_sprd;
1996 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1997 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1998 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1999 bufmgr_backend->bo_free = tbm_sprd_bo_free;
2000 bufmgr_backend->bo_import = tbm_sprd_bo_import;
2001 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
2002 bufmgr_backend->bo_export = tbm_sprd_bo_export;
2003 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
2004 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
2005 bufmgr_backend->bo_map = tbm_sprd_bo_map;
2006 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
2007 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
2008 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
2009 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
2010 bufmgr_backend->bo_lock = tbm_sprd_bo_lock;
2011 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
2012 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
2014 if (!tbm_backend_init(bufmgr, bufmgr_backend)) {
2015 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
2016 tbm_backend_free(bufmgr_backend);
2018 _bufmgr_deinit_cache_state(bufmgr_sprd);
2020 if (tbm_backend_is_display_server())
2021 tbm_drm_helper_unset_tbm_master_fd();
2023 close(bufmgr_sprd->fd);
2032 env = getenv("TBM_SPRD_DEBUG");
2035 TBM_SPRD_LOG("TBM_SPRD_DEBUG=%s\n", env);
2042 DBG("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
2043 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2045 DBG("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2046 __FUNCTION__, bufmgr_sprd->fd);