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 4
67 #define LOG_TAG "TBM_BACKEND"
69 static int bDebug = 0;
71 #define SPRD_DRM_NAME "sprd"
76 static char app_name[128] = {0, };
77 static int initialized = 0;
84 /* get the application name */
85 f = fopen("/proc/self/cmdline", "r");
89 if (fgets(app_name, 100, f) == NULL) {
96 slash = strrchr(app_name, '/');
98 memmove(app_name, slash + 1, strlen(slash));
104 #define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", _target_name(), ##args)
105 #define DBG(fmt, args...) if (bDebug&01) LOGE("[%s]" fmt, _target_name(), ##args)
107 #define TBM_SPRD_LOG(...)
111 #define SIZE_ALIGN(value, base) (((value) + ((base) - 1)) & ~((base) - 1))
113 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
114 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128)
115 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
118 /* check condition */
119 #define SPRD_RETURN_IF_FAIL(cond) {\
121 TBM_SPRD_LOG("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
125 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
127 TBM_SPRD_LOG("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
132 struct dma_buf_info {
134 unsigned int fence_supported;
135 unsigned int padding;
138 #define DMA_BUF_ACCESS_READ 0x1
139 #define DMA_BUF_ACCESS_WRITE 0x2
140 #define DMA_BUF_ACCESS_DMA 0x4
141 #define DMA_BUF_ACCESS_MAX 0x8
143 #define DMA_FENCE_LIST_MAX 5
145 struct dma_buf_fence {
150 #define DMABUF_IOCTL_BASE 'F'
151 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
153 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
154 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
155 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
158 #define GLOBAL_KEY ((unsigned int)(-1))
160 #define TBM_SPRD_CACHE_INV 0x01 /**< cache invalidate */
161 #define TBM_SPRD_CACHE_CLN 0x02 /**< cache clean */
162 #define TBM_SPRD_CACHE_ALL 0x10 /**< cache all */
163 #define TBM_SPRD_CACHE_FLUSH (TBM_SPRD_CACHE_INV|TBM_SPRD_CACHE_CLN) /**< cache flush */
164 #define TBM_SPRD_CACHE_FLUSH_ALL (TBM_SPRD_CACHE_FLUSH|TBM_SPRD_CACHE_ALL) /**< cache flush all */
168 DEVICE_CA, /* cache aware device */
169 DEVICE_CO /* cache oblivious device */
172 typedef union _tbm_bo_cache_state tbm_bo_cache_state;
174 union _tbm_bo_cache_state {
177 unsigned int cntFlush:16; /*Flush all index for sync */
178 unsigned int isCached:1;
179 unsigned int isDirtied:2;
183 typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd;
184 typedef struct _tbm_bo_sprd *tbm_bo_sprd;
186 typedef struct _sprd_private {
188 struct _tbm_bo_sprd *bo_priv;
191 /* tbm buffor object for sprd */
192 struct _tbm_bo_sprd {
195 unsigned int name; /* FLINK ID */
197 unsigned int gem; /* GEM Handle */
199 unsigned int dmabuf; /* fd for dmabuf */
201 void *pBase; /* virtual address */
205 unsigned int flags_sprd;
206 unsigned int flags_tbm;
210 pthread_mutex_t mutex;
211 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
215 tbm_bo_cache_state cache_state;
216 unsigned int map_cnt;
219 /* tbm bufmgr private for sprd */
220 struct _tbm_bufmgr_sprd {
232 char *STR_DEVICE[] = {
248 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = {
256 _tgl_init(int fd, unsigned int key)
258 struct tgl_attribute attr;
262 attr.timeout_ms = 1000;
264 err = ioctl(fd, TGL_IOC_INIT_LOCK, &attr);
266 TBM_SPRD_LOG("[libtbm-sprd:%d] error(%s) %s:%d key:%d\n",
267 getpid(), strerror(errno), __func__, __LINE__, key);
275 _tgl_destroy(int fd, unsigned int key)
279 err = ioctl(fd, TGL_IOC_DESTROY_LOCK, key);
281 TBM_SPRD_LOG("[libtbm-sprd:%d] "
282 "error(%s) %s:%d key:%d\n",
283 getpid(), strerror(errno), __func__, __LINE__, key);
291 _tgl_lock(int fd, unsigned int key)
295 err = ioctl(fd, TGL_IOC_LOCK_LOCK, key);
297 TBM_SPRD_LOG("[libtbm-sprd:%d] "
298 "error(%s) %s:%d key:%d\n",
299 getpid(), strerror(errno), __func__, __LINE__, key);
307 _tgl_unlock(int fd, unsigned int key)
311 err = ioctl(fd, TGL_IOC_UNLOCK_LOCK, key);
313 TBM_SPRD_LOG("[libtbm-sprd:%d] "
314 "error(%s) %s:%d key:%d\n",
315 getpid(), strerror(errno), __func__, __LINE__, key);
324 _tgl_set_data(int fd, unsigned int key, unsigned int val)
327 struct tgl_user_data arg;
331 err = ioctl(fd, TGL_IOC_SET_DATA, &arg);
333 TBM_SPRD_LOG("[libtbm-sprd:%d] "
334 "error(%s) %s:%d key:%d\n",
335 getpid(), strerror(errno), __func__, __LINE__, key);
342 static inline unsigned int
343 _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
346 struct tgl_user_data arg = { 0, };
349 err = ioctl(fd, TGL_IOC_GET_DATA, &arg);
351 TBM_SPRD_LOG("[libtbm-sprd:%d] "
352 "error(%s) %s:%d key:%d\n",
353 getpid(), strerror(errno), __func__, __LINE__, key);
358 *locked = arg.locked;
365 _tbm_sprd_open_drm(void)
368 struct udev_device *drm_device = NULL;
369 struct udev_list_entry *entry = NULL;
370 struct udev_enumerate *e;
371 const char *filepath;
377 fd = drmOpen(SPRD_DRM_NAME, NULL);
382 TBM_SPRD_LOG("[libtbm-sprd:%d] warning %s:%d fail to open drm, "
383 "so search drm-device by udev\n",
384 getpid(), __FUNCTION__, __LINE__);
388 TBM_SPRD_LOG("udev_new() failed.\n");
392 e = udev_enumerate_new(udev);
393 udev_enumerate_add_match_subsystem(e, "drm");
394 udev_enumerate_add_match_sysname(e, "card[0-9]*");
395 udev_enumerate_scan_devices(e);
397 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
398 struct udev_device *device, *device_parent;
400 device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
401 udev_list_entry_get_name(entry));
402 device_parent = udev_device_get_parent(device);
403 /* Not need unref device_parent. device_parent and device have same refcnt */
405 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
407 DBG("[%s] Found render device: '%s' (%s)\n",
409 udev_device_get_syspath(drm_device),
410 udev_device_get_sysname(device_parent));
414 udev_device_unref(device);
417 udev_enumerate_unref(e);
419 /* Get device file path. */
420 filepath = udev_device_get_devnode(drm_device);
422 TBM_SPRD_LOG("udev_device_get_devnode() failed.\n");
423 udev_device_unref(drm_device);
428 udev_device_unref(drm_device);
431 /* Open DRM device file and check validity. */
432 fd = open(filepath, O_RDWR | O_CLOEXEC);
434 TBM_SPRD_LOG("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
439 TBM_SPRD_LOG("fstat() failed %s.\n");
444 TBM_SPRD_LOG("[libtbm-sprd:%d] warning %s:%d fail to open drm\n",
445 getpid(), __FUNCTION__, __LINE__);
453 _sprd_bo_cache_flush(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int flags)
455 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
457 /* cache flush is managed by kernel side when using dma-fence. */
458 if (bufmgr_sprd->use_dma_fence)
461 struct drm_sprd_gem_cache_op cache_op = {0, };
464 /* if bo_sprd is null, do cache_flush_all */
467 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
468 cache_op.size = bo_sprd->size;
470 flags = TBM_SPRD_CACHE_FLUSH_ALL;
472 cache_op.usr_addr = 0;
476 if (flags & TBM_SPRD_CACHE_INV) {
477 if (flags & TBM_SPRD_CACHE_ALL)
478 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
480 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
483 if (flags & TBM_SPRD_CACHE_CLN) {
484 if (flags & TBM_SPRD_CACHE_ALL)
485 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
487 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
490 if (flags & TBM_SPRD_CACHE_ALL)
491 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
493 ret = drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
496 TBM_SPRD_LOG("[libtbm-sprd:%d] "
497 "error %s:%d fail to flush the cache.\n",
498 getpid(), __FUNCTION__, __LINE__);
507 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int import)
509 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
510 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
512 if (bufmgr_sprd->use_dma_fence)
515 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
518 tbm_bo_cache_state cache_state;
521 cache_state.data.isDirtied = DEVICE_NONE;
522 cache_state.data.isCached = 0;
523 cache_state.data.cntFlush = 0;
525 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
533 _bo_set_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int device, int opt)
536 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
537 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
540 unsigned short cntFlush = 0;
542 if (bufmgr_sprd->use_dma_fence)
545 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
548 /* get cache state of a bo */
549 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
551 /* get global cache flush count */
552 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
554 if (opt == TBM_DEVICE_CPU) {
555 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
556 bo_sprd->cache_state.data.isCached)
557 need_flush = TBM_SPRD_CACHE_INV;
559 bo_sprd->cache_state.data.isCached = 1;
560 if (opt & TBM_OPTION_WRITE)
561 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
563 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
564 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
567 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
568 bo_sprd->cache_state.data.isCached &&
569 bo_sprd->cache_state.data.cntFlush == cntFlush)
570 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
572 if (opt & TBM_OPTION_WRITE)
573 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
575 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
576 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
581 if (need_flush & TBM_SPRD_CACHE_ALL)
582 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
584 /* call cache flush */
585 _sprd_bo_cache_flush(bufmgr_sprd, bo_sprd, need_flush);
587 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
589 bo_sprd->cache_state.data.isCached,
590 bo_sprd->cache_state.data.isDirtied,
600 _bo_save_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
603 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
604 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
606 if (bufmgr_sprd->use_dma_fence)
609 unsigned short cntFlush = 0;
611 /* get global cache flush count */
612 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
614 /* save global cache flush count */
615 bo_sprd->cache_state.data.cntFlush = cntFlush;
616 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
623 _bo_destroy_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
625 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
626 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
628 if (bufmgr_sprd->use_dma_fence)
631 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
635 _bufmgr_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
637 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
639 if (bufmgr_sprd->use_dma_fence)
642 /* open tgl fd for saving cache flush data */
643 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
645 if (bufmgr_sprd->tgl_fd < 0) {
646 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
647 if (bufmgr_sprd->tgl_fd < 0) {
648 TBM_SPRD_LOG("[libtbm-sprd:%d] "
649 "error: Fail to open global_lock:%s\n",
650 getpid(), tgl_devfile);
656 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
657 TBM_SPRD_LOG("[libtbm-sprd:%d] "
658 "error: Fail to initialize the tgl\n",
661 close(bufmgr_sprd->tgl_fd);
670 _bufmgr_deinit_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
672 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
674 if (bufmgr_sprd->use_dma_fence)
677 if (bufmgr_sprd->tgl_fd >= 0)
678 close(bufmgr_sprd->tgl_fd);
681 #ifndef USE_CONTIG_ONLY
683 _get_sprd_flag_from_tbm(unsigned int ftbm)
685 unsigned int flags = 0;
688 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
689 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
690 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
691 * To be updated appropriately once DRM-GEM supports different heap id masks.
694 if (ftbm & TBM_BO_SCANOUT)
695 flags = SPRD_BO_CONTIG;
697 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
699 if (ftbm & TBM_BO_WC)
701 else if (ftbm & TBM_BO_NONCACHABLE)
702 flags |= SPRD_BO_NONCACHABLE;
708 _get_tbm_flag_from_sprd(unsigned int fsprd)
710 unsigned int flags = 0;
712 if (fsprd & SPRD_BO_NONCONTIG)
713 flags |= TBM_BO_DEFAULT;
715 flags |= TBM_BO_SCANOUT;
717 if (fsprd & SPRD_BO_WC)
719 else if (fsprd & SPRD_BO_CACHABLE)
720 flags |= TBM_BO_DEFAULT;
722 flags |= TBM_BO_NONCACHABLE;
729 _get_name(int fd, unsigned int gem)
731 struct drm_gem_flink arg = {0,};
734 if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
735 TBM_SPRD_LOG("[libtbm-sprd:%d] "
736 "error %s:%d fail to get flink gem=%d\n",
737 getpid(), __FUNCTION__, __LINE__, gem);
741 return (unsigned int)arg.name;
745 _sprd_bo_handle(tbm_bo_sprd bo_sprd, int device)
747 tbm_bo_handle bo_handle;
748 memset(&bo_handle, 0x0, sizeof(uint64_t));
751 case TBM_DEVICE_DEFAULT:
753 bo_handle.u32 = (uint32_t)bo_sprd->gem;
756 if (!bo_sprd->pBase) {
757 struct drm_sprd_gem_mmap arg = {0,};
759 arg.handle = bo_sprd->gem;
760 arg.size = bo_sprd->size;
761 if (drmCommandWriteRead(bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
762 TBM_SPRD_LOG("[libtbm-sprd:%d] "
763 "error %s:%d Cannot usrptr gem=%d\n",
764 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
765 return (tbm_bo_handle) NULL;
767 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
770 bo_handle.ptr = (void *)bo_sprd->pBase;
774 if (!bo_sprd->dmabuf) {
775 struct drm_prime_handle arg = {0, };
776 arg.handle = bo_sprd->gem;
777 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
778 TBM_SPRD_LOG("[libtbm-sprd:%d] "
779 "error %s:%d Cannot dmabuf=%d\n",
780 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
781 return (tbm_bo_handle) NULL;
783 bo_sprd->dmabuf = arg.fd;
786 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
793 //TODO : Add ioctl for GSP MAP once available.
794 DBG("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
799 if (!bo_sprd->dmabuf) {
800 struct drm_prime_handle arg = {0, };
802 arg.handle = bo_sprd->gem;
803 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
804 TBM_SPRD_LOG("[libtbm-sprd:%d] "
805 "error %s:%d Cannot dmabuf=%d\n",
806 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
807 return (tbm_bo_handle) NULL;
809 bo_sprd->dmabuf = arg.fd;
812 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
816 bo_handle.ptr = (void *) NULL;
824 tbm_sprd_bo_size(tbm_bo bo)
826 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
830 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
832 return bo_sprd->size;
836 tbm_sprd_bo_alloc(tbm_bo bo, int size, int flags)
838 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
841 tbm_bufmgr_sprd bufmgr_sprd;
842 unsigned int sprd_flags;
844 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
845 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
847 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
849 TBM_SPRD_LOG("[libtbm-sprd:%d] "
850 "error %s:%d fail to allocate the bo private\n",
851 getpid(), __FUNCTION__, __LINE__);
855 #ifdef USE_CONTIG_ONLY
856 flags = TBM_BO_SCANOUT;
857 sprd_flags = SPRD_BO_CONTIG;
859 sprd_flags = _get_sprd_flag_from_tbm(flags);
860 if ((flags & TBM_BO_SCANOUT) &&
862 sprd_flags |= SPRD_BO_NONCONTIG;
864 #endif // USE_CONTIG_ONLY
865 struct drm_sprd_gem_create arg = {0, };
866 arg.size = (uint64_t)size;
867 arg.flags = sprd_flags;
868 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
870 TBM_SPRD_LOG("[libtbm-sprd:%d] "
871 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
872 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
877 bo_sprd->fd = bufmgr_sprd->fd;
878 bo_sprd->gem = arg.handle;
879 bo_sprd->size = size;
880 bo_sprd->flags_tbm = flags;
881 bo_sprd->flags_sprd = sprd_flags;
882 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
884 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 0)) {
885 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
890 pthread_mutex_init(&bo_sprd->mutex, NULL);
892 if (bufmgr_sprd->use_dma_fence
893 && !bo_sprd->dmabuf) {
894 struct drm_prime_handle arg = {0, };
896 arg.handle = bo_sprd->gem;
897 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
898 TBM_SPRD_LOG("[libtbm-sprd:%d] "
899 "error %s:%d Cannot dmabuf=%d\n",
900 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
904 bo_sprd->dmabuf = arg.fd;
908 PrivGem *privGem = calloc(1, sizeof(PrivGem));
909 privGem->ref_count = 1;
910 privGem->bo_priv = bo_sprd;
911 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
912 TBM_SPRD_LOG("[libtbm-sprd:%d] "
913 "error %s:%d Cannot insert bo to Hash(%d)\n",
914 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
917 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
918 __FUNCTION__, bo_sprd->size,
919 bo_sprd->gem, bo_sprd->name,
922 return (void *)bo_sprd;
926 tbm_sprd_bo_free(tbm_bo bo)
929 tbm_bufmgr_sprd bufmgr_sprd;
934 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
935 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
937 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
938 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
940 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
941 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
943 if (bo_sprd->pBase) {
944 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
945 TBM_SPRD_LOG("[libtbm-sprd:%d] "
947 getpid(), __FUNCTION__, __LINE__);
952 if (bo_sprd->dmabuf) {
953 close(bo_sprd->dmabuf);
957 /* delete bo from hash */
958 PrivGem *privGem = NULL;
961 ret = drmHashLookup(bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
963 privGem->ref_count--;
964 if (privGem->ref_count == 0) {
965 drmHashDelete(bufmgr_sprd->hashBos, bo_sprd->name);
970 TBM_SPRD_LOG("[libtbm-sprd:%d] "
971 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
972 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
975 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
977 /* Free gem handle */
978 struct drm_gem_close arg = {0, };
979 memset(&arg, 0, sizeof(arg));
980 arg.handle = bo_sprd->gem;
981 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
982 TBM_SPRD_LOG("[libtbm-sprd:%d] "
984 getpid(), __FUNCTION__, __LINE__);
992 tbm_sprd_bo_import(tbm_bo bo, unsigned int key)
994 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
996 tbm_bufmgr_sprd bufmgr_sprd;
998 PrivGem *privGem = NULL;
1001 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1002 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1004 ret = drmHashLookup(bufmgr_sprd->hashBos, key, (void **)&privGem);
1006 return privGem->bo_priv;
1008 struct drm_gem_open arg = {0, };
1009 struct drm_sprd_gem_info info = {0, };
1012 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
1013 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1014 "error %s:%d Cannot open gem name=%d\n",
1015 getpid(), __FUNCTION__, __LINE__, key);
1019 info.handle = arg.handle;
1020 if (drmCommandWriteRead(bufmgr_sprd->fd,
1023 sizeof(struct drm_sprd_gem_info))) {
1024 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1025 "error %s:%d Cannot get gem info=%d\n",
1026 getpid(), __FUNCTION__, __LINE__, key);
1030 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1032 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1033 "error %s:%d fail to allocate the bo private\n",
1034 getpid(), __FUNCTION__, __LINE__);
1038 bo_sprd->fd = bufmgr_sprd->fd;
1039 bo_sprd->gem = arg.handle;
1040 bo_sprd->size = arg.size;
1041 bo_sprd->flags_sprd = info.flags;
1042 bo_sprd->name = key;
1043 #ifdef USE_CONTIG_ONLY
1044 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1045 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1047 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1050 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1051 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
1056 if (!bo_sprd->dmabuf) {
1057 struct drm_prime_handle arg = {0, };
1059 arg.handle = bo_sprd->gem;
1060 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1061 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1062 "error %s:%d Cannot dmabuf=%d\n",
1063 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1067 bo_sprd->dmabuf = arg.fd;
1070 /* add bo to hash */
1071 privGem = calloc(1, sizeof(PrivGem));
1072 privGem->ref_count = 1;
1073 privGem->bo_priv = bo_sprd;
1074 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1075 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1076 "error %s:%d Cannot insert bo to Hash(%d)\n",
1077 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1080 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1081 __FUNCTION__, bo_sprd->size,
1082 bo_sprd->gem, bo_sprd->name,
1083 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1085 return (void *)bo_sprd;
1089 tbm_sprd_bo_import_fd(tbm_bo bo, tbm_fd key)
1091 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1093 tbm_bufmgr_sprd bufmgr_sprd;
1094 tbm_bo_sprd bo_sprd;
1095 PrivGem *privGem = NULL;
1099 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1100 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1102 //getting handle from fd
1103 unsigned int gem = 0;
1104 struct drm_prime_handle arg = {0, };
1108 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1109 TBM_SPRD_LOG("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1110 bo, arg.fd, strerror(errno));
1115 name = _get_name(bufmgr_sprd->fd, gem);
1117 ret = drmHashLookup(bufmgr_sprd->hashBos, name, (void **)&privGem);
1119 if (gem == privGem->bo_priv->gem)
1120 return privGem->bo_priv;
1123 unsigned int real_size = -1;
1124 struct drm_sprd_gem_info info = {0, };
1126 /* Determine size of bo. The fd-to-handle ioctl really should
1127 * return the size, but it doesn't. If we have kernel 3.12 or
1128 * later, we can lseek on the prime fd to get the size. Older
1129 * kernels will just fail, in which case we fall back to the
1130 * provided (estimated or guess size). */
1131 real_size = lseek(key, 0, SEEK_END);
1134 if (drmCommandWriteRead(bufmgr_sprd->fd,
1137 sizeof(struct drm_sprd_gem_info))) {
1138 TBM_SPRD_LOG("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1139 bo, gem, key, strerror(errno));
1143 if (real_size == -1)
1144 real_size = info.size;
1146 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1148 TBM_SPRD_LOG("error bo:%p fail to allocate the bo private\n", bo);
1152 bo_sprd->fd = bufmgr_sprd->fd;
1154 bo_sprd->size = real_size;
1155 bo_sprd->flags_sprd = info.flags;
1156 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1158 bo_sprd->name = name;
1159 if (!bo_sprd->name) {
1160 TBM_SPRD_LOG("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1161 bo, gem, key, strerror(errno));
1166 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1167 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
1172 /* add bo to hash */
1175 privGem = calloc(1, sizeof(PrivGem));
1177 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1178 "error %s:%d Fail to callocprivGem\n",
1179 getpid(), __FUNCTION__, __LINE__);
1184 privGem->ref_count = 1;
1185 privGem->bo_priv = bo_sprd;
1186 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1187 TBM_SPRD_LOG("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1188 bo, bo_sprd->name, gem, key);
1191 DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1194 bo_sprd->gem, bo_sprd->name,
1197 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1200 return (void *)bo_sprd;
1204 tbm_sprd_bo_export(tbm_bo bo)
1206 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1208 tbm_bo_sprd bo_sprd;
1210 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1211 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1213 if (!bo_sprd->name) {
1214 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1215 if (!bo_sprd->name) {
1216 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1217 "error %s:%d Cannot get name\n",
1218 getpid(), __FUNCTION__, __LINE__);
1223 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1224 __FUNCTION__, bo_sprd->size,
1225 bo_sprd->gem, bo_sprd->name,
1226 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1228 return (unsigned int)bo_sprd->name;
1232 tbm_sprd_bo_export_fd(tbm_bo bo)
1234 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, -1);
1236 tbm_bo_sprd bo_sprd;
1239 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1240 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, -1);
1242 struct drm_prime_handle arg = {0, };
1244 arg.handle = bo_sprd->gem;
1245 ret = drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1247 TBM_SPRD_LOG("error bo:%p Cannot dmabuf=%d (%s)\n",
1248 bo, bo_sprd->gem, strerror(errno));
1249 return (tbm_fd) ret;
1252 DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1255 bo_sprd->gem, bo_sprd->name,
1258 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1261 return (tbm_fd)arg.fd;
1265 static tbm_bo_handle
1266 tbm_sprd_bo_get_handle(tbm_bo bo, int device)
1268 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1270 tbm_bo_handle bo_handle;
1271 tbm_bo_sprd bo_sprd;
1273 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1274 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1276 if (!bo_sprd->gem) {
1277 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1278 "error %s:%d Cannot map gem=%d\n",
1279 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1280 return (tbm_bo_handle) NULL;
1283 DBG("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1284 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1286 /*Get mapped bo_handle*/
1287 bo_handle = _sprd_bo_handle(bo_sprd, device);
1288 if (bo_handle.ptr == NULL) {
1289 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1290 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1291 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1292 return (tbm_bo_handle) NULL;
1298 static tbm_bo_handle
1299 tbm_sprd_bo_map(tbm_bo bo, int device, int opt)
1301 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1303 tbm_bo_handle bo_handle;
1304 tbm_bo_sprd bo_sprd;
1305 tbm_bufmgr_sprd bufmgr_sprd;
1307 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1308 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, (tbm_bo_handle) NULL);
1310 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1311 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1313 if (!bo_sprd->gem) {
1314 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1315 "error %s:%d Cannot map gem=%d\n",
1316 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1317 return (tbm_bo_handle) NULL;
1320 DBG("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1321 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1323 /*Get mapped bo_handle*/
1324 bo_handle = _sprd_bo_handle(bo_sprd, device);
1325 if (bo_handle.ptr == NULL) {
1326 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1327 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1328 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1329 return (tbm_bo_handle) NULL;
1332 if (bo_sprd->map_cnt == 0)
1333 _bo_set_cache_state(bufmgr_sprd, bo_sprd, device, opt);
1341 tbm_sprd_bo_unmap(tbm_bo bo)
1343 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1345 tbm_bo_sprd bo_sprd;
1346 tbm_bufmgr_sprd bufmgr_sprd;
1348 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1349 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1351 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1352 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1359 if (bo_sprd->map_cnt == 0)
1360 _bo_save_cache_state(bufmgr_sprd, bo_sprd);
1362 DBG("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1363 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1369 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1371 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1373 tbm_bufmgr_sprd bufmgr_sprd;
1374 tbm_bo_sprd bo_sprd;
1376 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1377 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1379 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1380 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1382 #if USE_BACKEND_LOCK
1385 if (bufmgr_sprd->use_dma_fence) {
1387 struct dma_buf_fence fence;
1389 memset(&fence, 0, sizeof(struct dma_buf_fence));
1391 /* Check if the given type is valid or not. */
1392 if (opt & TBM_OPTION_WRITE) {
1393 if (device == TBM_DEVICE_CPU)
1394 fence.type = DMA_BUF_ACCESS_WRITE;
1395 else if (device == TBM_DEVICE_3D)
1396 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1398 DBG("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1399 getpid(), __FUNCTION__);
1402 } else if (opt & TBM_OPTION_READ) {
1403 if (device == TBM_DEVICE_CPU)
1404 fence.type = DMA_BUF_ACCESS_READ;
1405 else if (device == TBM_DEVICE_3D)
1406 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1408 DBG("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1409 getpid(), __FUNCTION__);
1413 TBM_SPRD_LOG("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1414 __FUNCTION__, __LINE__);
1418 /* Check if the tbm manager supports dma fence or not. */
1419 if (!bufmgr_sprd->use_dma_fence) {
1420 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1421 "error %s:%d Not support DMA FENCE(%s)\n",
1422 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1427 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1429 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1430 "error %s:%d Can not set GET FENCE(%s)\n",
1431 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1435 pthread_mutex_lock(&bo_sprd->mutex);
1437 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1438 if (bo_sprd->dma_fence[i].ctx == 0) {
1439 bo_sprd->dma_fence[i].type = fence.type;
1440 bo_sprd->dma_fence[i].ctx = fence.ctx;
1444 if (i == DMA_FENCE_LIST_MAX) {
1445 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1446 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1447 "error %s:%d fence list is full\n",
1448 getpid(), __FUNCTION__, __LINE__);
1450 pthread_mutex_unlock(&bo_sprd->mutex);
1452 DBG("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1454 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1457 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1459 DBG("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1460 getpid(), __FUNCTION__, bo_sprd->name);
1470 tbm_sprd_bo_unlock(tbm_bo bo)
1472 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1474 tbm_bufmgr_sprd bufmgr_sprd;
1475 tbm_bo_sprd bo_sprd;
1477 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1478 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1480 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1481 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1483 #if USE_BACKEND_LOCK
1486 if (bufmgr_sprd->use_dma_fence) {
1487 struct dma_buf_fence fence;
1489 if (!bo_sprd->dma_fence[0].ctx) {
1490 DBG("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1495 if (!bo_sprd->dma_fence[0].type) {
1496 DBG("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1501 pthread_mutex_lock(&bo_sprd->mutex);
1502 fence.type = bo_sprd->dma_fence[0].type;
1503 fence.ctx = bo_sprd->dma_fence[0].ctx;
1505 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1506 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1507 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1509 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1510 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1511 pthread_mutex_unlock(&bo_sprd->mutex);
1513 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1515 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1516 "error %s:%d Can not set PUT FENCE(%s)\n",
1517 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1521 DBG("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1523 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1525 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1527 DBG("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1528 getpid(), __FUNCTION__, bo_sprd->name);
1538 tbm_sprd_bufmgr_deinit(void *priv)
1540 SPRD_RETURN_IF_FAIL(priv != NULL);
1542 tbm_bufmgr_sprd bufmgr_sprd;
1544 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1546 if (bufmgr_sprd->hashBos) {
1550 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1552 drmHashDelete(bufmgr_sprd->hashBos, key);
1555 drmHashDestroy(bufmgr_sprd->hashBos);
1556 bufmgr_sprd->hashBos = NULL;
1559 if (bufmgr_sprd->bind_display)
1560 tbm_drm_helper_wl_auth_server_deinit();
1562 if (tbm_backend_is_display_server())
1563 tbm_drm_helper_unset_tbm_master_fd();
1565 if (bufmgr_sprd->device_name)
1566 free(bufmgr_sprd->device_name);
1568 _bufmgr_deinit_cache_state(bufmgr_sprd);
1570 close(bufmgr_sprd->fd);
1576 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1578 uint32_t *color_formats = NULL;
1580 color_formats = (uint32_t *)calloc(1,
1581 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1583 if (color_formats == NULL)
1586 memcpy(color_formats, tbm_sprd_color_format_list,
1587 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1590 *formats = color_formats;
1591 *num = TBM_COLOR_FORMAT_COUNT;
1599 * @brief get the plane data of the surface.
1600 * @param[in] width : the width of the surface
1601 * @param[in] height : the height of the surface
1602 * @param[in] format : the format of the surface
1603 * @param[in] plane_idx : the format of the surface
1604 * @param[out] size : the size of the plane
1605 * @param[out] offset : the offset of the plane
1606 * @param[out] pitch : the pitch of the plane
1607 * @param[out] padding : the padding of the plane
1608 * @return 1 if this function succeeds, otherwise 0.
1611 tbm_sprd_surface_get_plane_data(int width, int height,
1612 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1613 uint32_t *pitch, int *bo_idx)
1621 int _align_height = 0;
1625 case TBM_FORMAT_XRGB4444:
1626 case TBM_FORMAT_XBGR4444:
1627 case TBM_FORMAT_RGBX4444:
1628 case TBM_FORMAT_BGRX4444:
1629 case TBM_FORMAT_ARGB4444:
1630 case TBM_FORMAT_ABGR4444:
1631 case TBM_FORMAT_RGBA4444:
1632 case TBM_FORMAT_BGRA4444:
1633 case TBM_FORMAT_XRGB1555:
1634 case TBM_FORMAT_XBGR1555:
1635 case TBM_FORMAT_RGBX5551:
1636 case TBM_FORMAT_BGRX5551:
1637 case TBM_FORMAT_ARGB1555:
1638 case TBM_FORMAT_ABGR1555:
1639 case TBM_FORMAT_RGBA5551:
1640 case TBM_FORMAT_BGRA5551:
1641 case TBM_FORMAT_RGB565:
1644 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1645 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1649 case TBM_FORMAT_RGB888:
1650 case TBM_FORMAT_BGR888:
1653 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1654 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1658 case TBM_FORMAT_XRGB8888:
1659 case TBM_FORMAT_XBGR8888:
1660 case TBM_FORMAT_RGBX8888:
1661 case TBM_FORMAT_BGRX8888:
1662 case TBM_FORMAT_ARGB8888:
1663 case TBM_FORMAT_ABGR8888:
1664 case TBM_FORMAT_RGBA8888:
1665 case TBM_FORMAT_BGRA8888:
1668 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1669 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1674 case TBM_FORMAT_YUYV:
1675 case TBM_FORMAT_YVYU:
1676 case TBM_FORMAT_UYVY:
1677 case TBM_FORMAT_VYUY:
1678 case TBM_FORMAT_AYUV:
1681 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1682 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1688 * index 0 = Y plane, [7:0] Y
1689 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1691 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1693 case TBM_FORMAT_NV12:
1694 case TBM_FORMAT_NV21:
1696 if (plane_idx == 0) {
1698 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1699 _align_height = SIZE_ALIGN(height, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1700 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1702 } else if (plane_idx == 1) {
1703 _offset = width * height;
1704 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1705 _align_height = SIZE_ALIGN(height / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1706 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1711 case TBM_FORMAT_NV16:
1712 case TBM_FORMAT_NV61:
1714 //if(plane_idx == 0)
1717 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1718 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1723 //else if( plane_idx ==1 )
1726 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1727 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1734 * index 0: Y plane, [7:0] Y
1735 * index 1: Cb plane, [7:0] Cb
1736 * index 2: Cr plane, [7:0] Cr
1738 * index 1: Cr plane, [7:0] Cr
1739 * index 2: Cb plane, [7:0] Cb
1742 NATIVE_BUFFER_FORMAT_YV12
1743 NATIVE_BUFFER_FORMAT_I420
1745 case TBM_FORMAT_YUV410:
1746 case TBM_FORMAT_YVU410:
1749 case TBM_FORMAT_YUV411:
1750 case TBM_FORMAT_YVU411:
1751 case TBM_FORMAT_YUV420:
1752 case TBM_FORMAT_YVU420:
1754 //if(plane_idx == 0)
1757 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1758 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1763 //else if( plane_idx == 1 )
1766 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1767 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1772 //else if (plane_idx == 2 )
1775 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1776 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1780 case TBM_FORMAT_YUV422:
1781 case TBM_FORMAT_YVU422:
1783 //if(plane_idx == 0)
1786 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1787 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1792 //else if( plane_idx == 1 )
1795 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1796 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1801 //else if (plane_idx == 2 )
1804 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1805 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1809 case TBM_FORMAT_YUV444:
1810 case TBM_FORMAT_YVU444:
1812 //if(plane_idx == 0)
1815 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1816 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1821 //else if( plane_idx == 1 )
1824 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1825 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1830 //else if (plane_idx == 2 )
1833 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1834 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1852 tbm_sprd_bo_get_flags(tbm_bo bo)
1854 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1856 tbm_bo_sprd bo_sprd;
1858 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1859 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1861 return bo_sprd->flags_tbm;
1865 tbm_sprd_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1867 tbm_bufmgr_sprd bufmgr_sprd;
1869 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1870 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1872 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1873 bufmgr_sprd->device_name, 0)) {
1874 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1878 bufmgr_sprd->bind_display = NativeDisplay;
1883 MODULEINITPPROTO(init_tbm_bufmgr_priv);
1885 static TBMModuleVersionInfo SprdVersRec = {
1891 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1894 init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd)
1896 tbm_bufmgr_backend bufmgr_backend;
1897 tbm_bufmgr_sprd bufmgr_sprd;
1903 bufmgr_sprd = calloc(1, sizeof(struct _tbm_bufmgr_sprd));
1905 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1909 if (tbm_backend_is_display_server()) {
1910 bufmgr_sprd->fd = tbm_drm_helper_get_master_fd();
1911 if (bufmgr_sprd->fd < 0) {
1912 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1913 if (bufmgr_sprd->fd < 0) {
1914 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to open drm!\n", getpid());
1919 tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
1921 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1922 if (!bufmgr_sprd->device_name) {
1923 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1924 tbm_drm_helper_unset_tbm_master_fd();
1925 goto fail_get_device_name;
1928 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1929 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1930 goto fail_get_auth_info;
1935 bufmgr_sprd->hashBos = drmHashCreate();
1937 //Check if the tbm manager supports dma fence or not.
1938 fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1941 int length = read(fp, buf, 1);
1943 if (length == 1 && buf[0] == '1')
1944 bufmgr_sprd->use_dma_fence = 1;
1949 if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
1950 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to init bufmgr cache state\n", getpid());
1951 goto fail_init_cache_state;
1954 bufmgr_backend = tbm_backend_alloc();
1955 if (!bufmgr_backend) {
1956 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to alloc backend!\n", getpid());
1957 goto fail_alloc_backend;
1960 bufmgr_backend->priv = (void *)bufmgr_sprd;
1961 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1962 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1963 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1964 bufmgr_backend->bo_free = tbm_sprd_bo_free;
1965 bufmgr_backend->bo_import = tbm_sprd_bo_import;
1966 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1967 bufmgr_backend->bo_export = tbm_sprd_bo_export;
1968 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1969 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1970 bufmgr_backend->bo_map = tbm_sprd_bo_map;
1971 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1972 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1973 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1974 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1975 bufmgr_backend->bo_lock = tbm_sprd_bo_lock;
1976 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1977 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1979 if (!tbm_backend_init(bufmgr, bufmgr_backend)) {
1980 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1981 goto fail_init_backend;
1988 env = getenv("TBM_SPRD_DEBUG");
1991 TBM_SPRD_LOG("TBM_SPRD_DEBUG=%s\n", env);
1997 DBG("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1998 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1999 DBG("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2000 __FUNCTION__, bufmgr_sprd->fd);
2005 tbm_backend_free(bufmgr_backend);
2007 _bufmgr_deinit_cache_state(bufmgr_sprd);
2008 fail_init_cache_state:
2009 if (bufmgr_sprd->hashBos)
2010 drmHashDestroy(bufmgr_sprd->hashBos);
2011 if (tbm_backend_is_display_server())
2012 tbm_drm_helper_unset_tbm_master_fd();
2013 fail_get_device_name:
2014 close(bufmgr_sprd->fd);