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);
456 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
458 /* cache flush is managed by kernel side when using dma-fence. */
459 if (bufmgr_sprd->use_dma_fence)
462 struct drm_sprd_gem_cache_op cache_op = {0, };
465 /* if bo_sprd is null, do cache_flush_all */
468 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
469 cache_op.size = bo_sprd->size;
471 flags = TBM_SPRD_CACHE_FLUSH_ALL;
473 cache_op.usr_addr = 0;
477 if (flags & TBM_SPRD_CACHE_INV) {
478 if (flags & TBM_SPRD_CACHE_ALL)
479 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
481 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
484 if (flags & TBM_SPRD_CACHE_CLN) {
485 if (flags & TBM_SPRD_CACHE_ALL)
486 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
488 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
491 if (flags & TBM_SPRD_CACHE_ALL)
492 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
494 ret = drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
497 TBM_SPRD_LOG("[libtbm-sprd:%d] "
498 "error %s:%d fail to flush the cache.\n",
499 getpid(), __FUNCTION__, __LINE__);
508 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int import)
510 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
511 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
513 if (bufmgr_sprd->use_dma_fence)
516 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
519 tbm_bo_cache_state cache_state;
522 cache_state.data.isDirtied = DEVICE_NONE;
523 cache_state.data.isCached = 0;
524 cache_state.data.cntFlush = 0;
526 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
534 _bo_set_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int device, int opt)
537 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
538 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
541 unsigned short cntFlush = 0;
543 if (bufmgr_sprd->use_dma_fence)
546 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
549 /* get cache state of a bo */
550 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
552 /* get global cache flush count */
553 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
555 if (opt == TBM_DEVICE_CPU) {
556 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
557 bo_sprd->cache_state.data.isCached)
558 need_flush = TBM_SPRD_CACHE_INV;
560 bo_sprd->cache_state.data.isCached = 1;
561 if (opt & TBM_OPTION_WRITE)
562 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
564 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
565 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
568 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
569 bo_sprd->cache_state.data.isCached &&
570 bo_sprd->cache_state.data.cntFlush == cntFlush)
571 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
573 if (opt & TBM_OPTION_WRITE)
574 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
576 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
577 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
582 if (need_flush & TBM_SPRD_CACHE_ALL)
583 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
585 /* call cache flush */
586 _sprd_bo_cache_flush(bufmgr_sprd, bo_sprd, need_flush);
588 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
590 bo_sprd->cache_state.data.isCached,
591 bo_sprd->cache_state.data.isDirtied,
601 _bo_save_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
604 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
605 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
607 if (bufmgr_sprd->use_dma_fence)
610 unsigned short cntFlush = 0;
612 /* get global cache flush count */
613 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
615 /* save global cache flush count */
616 bo_sprd->cache_state.data.cntFlush = cntFlush;
617 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
624 _bo_destroy_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
626 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
627 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
629 if (bufmgr_sprd->use_dma_fence)
632 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
636 _bufmgr_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
638 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
640 if (bufmgr_sprd->use_dma_fence)
643 /* open tgl fd for saving cache flush data */
644 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
646 if (bufmgr_sprd->tgl_fd < 0) {
647 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
648 if (bufmgr_sprd->tgl_fd < 0) {
649 TBM_SPRD_LOG("[libtbm-sprd:%d] "
650 "error: Fail to open global_lock:%s\n",
651 getpid(), tgl_devfile);
657 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
658 TBM_SPRD_LOG("[libtbm-sprd:%d] "
659 "error: Fail to initialize the tgl\n",
662 close(bufmgr_sprd->tgl_fd);
671 _bufmgr_deinit_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
673 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
675 if (bufmgr_sprd->use_dma_fence)
678 if (bufmgr_sprd->tgl_fd >= 0)
679 close(bufmgr_sprd->tgl_fd);
682 #ifndef USE_CONTIG_ONLY
684 _get_sprd_flag_from_tbm(unsigned int ftbm)
686 unsigned int flags = 0;
689 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
690 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
691 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
692 * To be updated appropriately once DRM-GEM supports different heap id masks.
695 if (ftbm & TBM_BO_SCANOUT)
696 flags = SPRD_BO_CONTIG;
698 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
700 if (ftbm & TBM_BO_WC)
702 else if (ftbm & TBM_BO_NONCACHABLE)
703 flags |= SPRD_BO_NONCACHABLE;
709 _get_tbm_flag_from_sprd(unsigned int fsprd)
711 unsigned int flags = 0;
713 if (fsprd & SPRD_BO_NONCONTIG)
714 flags |= TBM_BO_DEFAULT;
716 flags |= TBM_BO_SCANOUT;
718 if (fsprd & SPRD_BO_WC)
720 else if (fsprd & SPRD_BO_CACHABLE)
721 flags |= TBM_BO_DEFAULT;
723 flags |= TBM_BO_NONCACHABLE;
730 _get_name(int fd, unsigned int gem)
732 struct drm_gem_flink arg = {0,};
735 if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
736 TBM_SPRD_LOG("[libtbm-sprd:%d] "
737 "error %s:%d fail to get flink gem=%d\n",
738 getpid(), __FUNCTION__, __LINE__, gem);
742 return (unsigned int)arg.name;
746 _sprd_bo_handle(tbm_bo_sprd bo_sprd, int device)
748 tbm_bo_handle bo_handle;
749 memset(&bo_handle, 0x0, sizeof(uint64_t));
752 case TBM_DEVICE_DEFAULT:
754 bo_handle.u32 = (uint32_t)bo_sprd->gem;
757 if (!bo_sprd->pBase) {
758 struct drm_sprd_gem_mmap arg = {0,};
760 arg.handle = bo_sprd->gem;
761 arg.size = bo_sprd->size;
762 if (drmCommandWriteRead(bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
763 TBM_SPRD_LOG("[libtbm-sprd:%d] "
764 "error %s:%d Cannot usrptr gem=%d\n",
765 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
766 return (tbm_bo_handle) NULL;
768 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
771 bo_handle.ptr = (void *)bo_sprd->pBase;
775 if (!bo_sprd->dmabuf) {
776 struct drm_prime_handle arg = {0, };
777 arg.handle = bo_sprd->gem;
778 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
779 TBM_SPRD_LOG("[libtbm-sprd:%d] "
780 "error %s:%d Cannot dmabuf=%d\n",
781 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
782 return (tbm_bo_handle) NULL;
784 bo_sprd->dmabuf = arg.fd;
787 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
794 //TODO : Add ioctl for GSP MAP once available.
795 DBG("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
800 if (!bo_sprd->dmabuf) {
801 struct drm_prime_handle arg = {0, };
803 arg.handle = bo_sprd->gem;
804 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
805 TBM_SPRD_LOG("[libtbm-sprd:%d] "
806 "error %s:%d Cannot dmabuf=%d\n",
807 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
808 return (tbm_bo_handle) NULL;
810 bo_sprd->dmabuf = arg.fd;
813 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
817 bo_handle.ptr = (void *) NULL;
825 tbm_sprd_bo_size(tbm_bo bo)
827 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
831 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
833 return bo_sprd->size;
837 tbm_sprd_bo_alloc(tbm_bo bo, int size, int flags)
839 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
842 tbm_bufmgr_sprd bufmgr_sprd;
843 unsigned int sprd_flags;
845 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
846 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
848 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
850 TBM_SPRD_LOG("[libtbm-sprd:%d] "
851 "error %s:%d fail to allocate the bo private\n",
852 getpid(), __FUNCTION__, __LINE__);
856 #ifdef USE_CONTIG_ONLY
857 flags = TBM_BO_SCANOUT;
858 sprd_flags = SPRD_BO_CONTIG;
860 sprd_flags = _get_sprd_flag_from_tbm(flags);
861 if ((flags & TBM_BO_SCANOUT) &&
863 sprd_flags |= SPRD_BO_NONCONTIG;
865 #endif // USE_CONTIG_ONLY
866 struct drm_sprd_gem_create arg = {0, };
867 arg.size = (uint64_t)size;
868 arg.flags = sprd_flags;
869 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
871 TBM_SPRD_LOG("[libtbm-sprd:%d] "
872 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
873 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
878 bo_sprd->fd = bufmgr_sprd->fd;
879 bo_sprd->gem = arg.handle;
880 bo_sprd->size = size;
881 bo_sprd->flags_tbm = flags;
882 bo_sprd->flags_sprd = sprd_flags;
883 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
885 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 0)) {
886 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
891 pthread_mutex_init(&bo_sprd->mutex, NULL);
893 if (bufmgr_sprd->use_dma_fence
894 && !bo_sprd->dmabuf) {
895 struct drm_prime_handle arg = {0, };
897 arg.handle = bo_sprd->gem;
898 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
899 TBM_SPRD_LOG("[libtbm-sprd:%d] "
900 "error %s:%d Cannot dmabuf=%d\n",
901 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
905 bo_sprd->dmabuf = arg.fd;
909 PrivGem *privGem = calloc(1, sizeof(PrivGem));
910 privGem->ref_count = 1;
911 privGem->bo_priv = bo_sprd;
912 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
913 TBM_SPRD_LOG("[libtbm-sprd:%d] "
914 "error %s:%d Cannot insert bo to Hash(%d)\n",
915 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
918 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
919 __FUNCTION__, bo_sprd->size,
920 bo_sprd->gem, bo_sprd->name,
923 return (void *)bo_sprd;
927 tbm_sprd_bo_free(tbm_bo bo)
930 tbm_bufmgr_sprd bufmgr_sprd;
935 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
936 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
938 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
939 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
941 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
942 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
944 if (bo_sprd->pBase) {
945 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
946 TBM_SPRD_LOG("[libtbm-sprd:%d] "
948 getpid(), __FUNCTION__, __LINE__);
953 if (bo_sprd->dmabuf) {
954 close(bo_sprd->dmabuf);
958 /* delete bo from hash */
959 PrivGem *privGem = NULL;
962 ret = drmHashLookup(bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
964 privGem->ref_count--;
965 if (privGem->ref_count == 0) {
966 drmHashDelete(bufmgr_sprd->hashBos, bo_sprd->name);
971 TBM_SPRD_LOG("[libtbm-sprd:%d] "
972 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
973 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
976 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
978 /* Free gem handle */
979 struct drm_gem_close arg = {0, };
980 memset(&arg, 0, sizeof(arg));
981 arg.handle = bo_sprd->gem;
982 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
983 TBM_SPRD_LOG("[libtbm-sprd:%d] "
985 getpid(), __FUNCTION__, __LINE__);
993 tbm_sprd_bo_import(tbm_bo bo, unsigned int key)
995 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
997 tbm_bufmgr_sprd bufmgr_sprd;
999 PrivGem *privGem = NULL;
1002 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1003 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1005 ret = drmHashLookup(bufmgr_sprd->hashBos, key, (void **)&privGem);
1007 return privGem->bo_priv;
1009 struct drm_gem_open arg = {0, };
1010 struct drm_sprd_gem_info info = {0, };
1013 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
1014 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1015 "error %s:%d Cannot open gem name=%d\n",
1016 getpid(), __FUNCTION__, __LINE__, key);
1020 info.handle = arg.handle;
1021 if (drmCommandWriteRead(bufmgr_sprd->fd,
1024 sizeof(struct drm_sprd_gem_info))) {
1025 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1026 "error %s:%d Cannot get gem info=%d\n",
1027 getpid(), __FUNCTION__, __LINE__, key);
1031 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1033 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1034 "error %s:%d fail to allocate the bo private\n",
1035 getpid(), __FUNCTION__, __LINE__);
1039 bo_sprd->fd = bufmgr_sprd->fd;
1040 bo_sprd->gem = arg.handle;
1041 bo_sprd->size = arg.size;
1042 bo_sprd->flags_sprd = info.flags;
1043 bo_sprd->name = key;
1044 #ifdef USE_CONTIG_ONLY
1045 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1046 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1048 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1051 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1052 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
1057 if (!bo_sprd->dmabuf) {
1058 struct drm_prime_handle arg = {0, };
1060 arg.handle = bo_sprd->gem;
1061 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1062 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1063 "error %s:%d Cannot dmabuf=%d\n",
1064 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1068 bo_sprd->dmabuf = arg.fd;
1071 /* add bo to hash */
1072 privGem = calloc(1, sizeof(PrivGem));
1073 privGem->ref_count = 1;
1074 privGem->bo_priv = bo_sprd;
1075 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1076 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1077 "error %s:%d Cannot insert bo to Hash(%d)\n",
1078 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1081 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1082 __FUNCTION__, bo_sprd->size,
1083 bo_sprd->gem, bo_sprd->name,
1084 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1086 return (void *)bo_sprd;
1090 tbm_sprd_bo_import_fd(tbm_bo bo, tbm_fd key)
1092 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1094 tbm_bufmgr_sprd bufmgr_sprd;
1095 tbm_bo_sprd bo_sprd;
1096 PrivGem *privGem = NULL;
1100 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1101 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1103 //getting handle from fd
1104 unsigned int gem = 0;
1105 struct drm_prime_handle arg = {0, };
1109 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1110 TBM_SPRD_LOG("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1111 bo, arg.fd, strerror(errno));
1116 name = _get_name(bufmgr_sprd->fd, gem);
1118 ret = drmHashLookup(bufmgr_sprd->hashBos, name, (void **)&privGem);
1120 if (gem == privGem->bo_priv->gem)
1121 return privGem->bo_priv;
1124 unsigned int real_size = -1;
1125 struct drm_sprd_gem_info info = {0, };
1127 /* Determine size of bo. The fd-to-handle ioctl really should
1128 * return the size, but it doesn't. If we have kernel 3.12 or
1129 * later, we can lseek on the prime fd to get the size. Older
1130 * kernels will just fail, in which case we fall back to the
1131 * provided (estimated or guess size). */
1132 real_size = lseek(key, 0, SEEK_END);
1135 if (drmCommandWriteRead(bufmgr_sprd->fd,
1138 sizeof(struct drm_sprd_gem_info))) {
1139 TBM_SPRD_LOG("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1140 bo, gem, key, strerror(errno));
1144 if (real_size == -1)
1145 real_size = info.size;
1147 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1149 TBM_SPRD_LOG("error bo:%p fail to allocate the bo private\n", bo);
1153 bo_sprd->fd = bufmgr_sprd->fd;
1155 bo_sprd->size = real_size;
1156 bo_sprd->flags_sprd = info.flags;
1157 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1159 bo_sprd->name = name;
1160 if (!bo_sprd->name) {
1161 TBM_SPRD_LOG("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1162 bo, gem, key, strerror(errno));
1167 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1168 TBM_SPRD_LOG("error fail init cache state(%d)\n", bo_sprd->name);
1173 /* add bo to hash */
1176 privGem = calloc(1, sizeof(PrivGem));
1178 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1179 "error %s:%d Fail to callocprivGem\n",
1180 getpid(), __FUNCTION__, __LINE__);
1185 privGem->ref_count = 1;
1186 privGem->bo_priv = bo_sprd;
1187 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1188 TBM_SPRD_LOG("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1189 bo, bo_sprd->name, gem, key);
1192 DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1195 bo_sprd->gem, bo_sprd->name,
1198 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1201 return (void *)bo_sprd;
1205 tbm_sprd_bo_export(tbm_bo bo)
1207 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1209 tbm_bo_sprd bo_sprd;
1211 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1212 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1214 if (!bo_sprd->name) {
1215 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1216 if (!bo_sprd->name) {
1217 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1218 "error %s:%d Cannot get name\n",
1219 getpid(), __FUNCTION__, __LINE__);
1224 DBG("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1225 __FUNCTION__, bo_sprd->size,
1226 bo_sprd->gem, bo_sprd->name,
1227 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1229 return (unsigned int)bo_sprd->name;
1233 tbm_sprd_bo_export_fd(tbm_bo bo)
1235 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, -1);
1237 tbm_bo_sprd bo_sprd;
1240 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1241 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, -1);
1243 struct drm_prime_handle arg = {0, };
1245 arg.handle = bo_sprd->gem;
1246 ret = drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1248 TBM_SPRD_LOG("error bo:%p Cannot dmabuf=%d (%s)\n",
1249 bo, bo_sprd->gem, strerror(errno));
1250 return (tbm_fd) ret;
1253 DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1256 bo_sprd->gem, bo_sprd->name,
1259 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1262 return (tbm_fd)arg.fd;
1266 static tbm_bo_handle
1267 tbm_sprd_bo_get_handle(tbm_bo bo, int device)
1269 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1271 tbm_bo_handle bo_handle;
1272 tbm_bo_sprd bo_sprd;
1274 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1275 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1277 if (!bo_sprd->gem) {
1278 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1279 "error %s:%d Cannot map gem=%d\n",
1280 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1281 return (tbm_bo_handle) NULL;
1284 DBG("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1285 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1287 /*Get mapped bo_handle*/
1288 bo_handle = _sprd_bo_handle(bo_sprd, device);
1289 if (bo_handle.ptr == NULL) {
1290 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1291 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1292 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1293 return (tbm_bo_handle) NULL;
1299 static tbm_bo_handle
1300 tbm_sprd_bo_map(tbm_bo bo, int device, int opt)
1302 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1304 tbm_bo_handle bo_handle;
1305 tbm_bo_sprd bo_sprd;
1306 tbm_bufmgr_sprd bufmgr_sprd;
1308 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1309 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, (tbm_bo_handle) NULL);
1311 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1312 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1314 if (!bo_sprd->gem) {
1315 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1316 "error %s:%d Cannot map gem=%d\n",
1317 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1318 return (tbm_bo_handle) NULL;
1321 DBG("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1322 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1324 /*Get mapped bo_handle*/
1325 bo_handle = _sprd_bo_handle(bo_sprd, device);
1326 if (bo_handle.ptr == NULL) {
1327 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1328 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1329 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1330 return (tbm_bo_handle) NULL;
1333 if (bo_sprd->map_cnt == 0)
1334 _bo_set_cache_state(bufmgr_sprd, bo_sprd, device, opt);
1342 tbm_sprd_bo_unmap(tbm_bo bo)
1344 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1346 tbm_bo_sprd bo_sprd;
1347 tbm_bufmgr_sprd bufmgr_sprd;
1349 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1350 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1352 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1353 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1360 if (bo_sprd->map_cnt == 0)
1361 _bo_save_cache_state(bufmgr_sprd, bo_sprd);
1363 DBG("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1364 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1370 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1372 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1374 tbm_bufmgr_sprd bufmgr_sprd;
1375 tbm_bo_sprd bo_sprd;
1377 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1378 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1380 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1381 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1383 #if USE_BACKEND_LOCK
1386 if (bufmgr_sprd->use_dma_fence) {
1388 struct dma_buf_fence fence;
1390 memset(&fence, 0, sizeof(struct dma_buf_fence));
1392 /* Check if the given type is valid or not. */
1393 if (opt & TBM_OPTION_WRITE) {
1394 if (device == TBM_DEVICE_CPU)
1395 fence.type = DMA_BUF_ACCESS_WRITE;
1396 else if (device == TBM_DEVICE_3D)
1397 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1399 DBG("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1400 getpid(), __FUNCTION__);
1403 } else if (opt & TBM_OPTION_READ) {
1404 if (device == TBM_DEVICE_CPU)
1405 fence.type = DMA_BUF_ACCESS_READ;
1406 else if (device == TBM_DEVICE_3D)
1407 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1409 DBG("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1410 getpid(), __FUNCTION__);
1414 TBM_SPRD_LOG("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1415 __FUNCTION__, __LINE__);
1419 /* Check if the tbm manager supports dma fence or not. */
1420 if (!bufmgr_sprd->use_dma_fence) {
1421 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1422 "error %s:%d Not support DMA FENCE(%s)\n",
1423 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1428 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1430 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1431 "error %s:%d Can not set GET FENCE(%s)\n",
1432 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1436 pthread_mutex_lock(&bo_sprd->mutex);
1438 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1439 if (bo_sprd->dma_fence[i].ctx == 0) {
1440 bo_sprd->dma_fence[i].type = fence.type;
1441 bo_sprd->dma_fence[i].ctx = fence.ctx;
1445 if (i == DMA_FENCE_LIST_MAX) {
1446 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1447 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1448 "error %s:%d fence list is full\n",
1449 getpid(), __FUNCTION__, __LINE__);
1451 pthread_mutex_unlock(&bo_sprd->mutex);
1453 DBG("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1455 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1458 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1460 DBG("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1461 getpid(), __FUNCTION__, bo_sprd->name);
1471 tbm_sprd_bo_unlock(tbm_bo bo)
1473 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1475 tbm_bufmgr_sprd bufmgr_sprd;
1476 tbm_bo_sprd bo_sprd;
1478 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1479 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1481 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1482 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1484 #if USE_BACKEND_LOCK
1487 if (bufmgr_sprd->use_dma_fence) {
1488 struct dma_buf_fence fence;
1490 if (!bo_sprd->dma_fence[0].ctx) {
1491 DBG("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1496 if (!bo_sprd->dma_fence[0].type) {
1497 DBG("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1502 pthread_mutex_lock(&bo_sprd->mutex);
1503 fence.type = bo_sprd->dma_fence[0].type;
1504 fence.ctx = bo_sprd->dma_fence[0].ctx;
1506 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1507 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1508 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1510 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1511 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1512 pthread_mutex_unlock(&bo_sprd->mutex);
1514 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1516 TBM_SPRD_LOG("[libtbm-sprd:%d] "
1517 "error %s:%d Can not set PUT FENCE(%s)\n",
1518 getpid(), __FUNCTION__, __LINE__, strerror(errno));
1522 DBG("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1524 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1526 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1528 DBG("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1529 getpid(), __FUNCTION__, bo_sprd->name);
1539 tbm_sprd_bufmgr_deinit(void *priv)
1541 SPRD_RETURN_IF_FAIL(priv != NULL);
1543 tbm_bufmgr_sprd bufmgr_sprd;
1545 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1547 if (bufmgr_sprd->hashBos) {
1551 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1553 drmHashDelete(bufmgr_sprd->hashBos, key);
1556 drmHashDestroy(bufmgr_sprd->hashBos);
1557 bufmgr_sprd->hashBos = NULL;
1560 if (bufmgr_sprd->bind_display)
1561 tbm_drm_helper_wl_auth_server_deinit();
1563 if (tbm_backend_is_display_server())
1564 tbm_drm_helper_unset_tbm_master_fd();
1566 if (bufmgr_sprd->device_name)
1567 free(bufmgr_sprd->device_name);
1569 _bufmgr_deinit_cache_state(bufmgr_sprd);
1571 close(bufmgr_sprd->fd);
1577 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1579 uint32_t *color_formats = NULL;
1581 color_formats = (uint32_t *)calloc(1,
1582 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1584 if (color_formats == NULL)
1587 memcpy(color_formats, tbm_sprd_color_format_list,
1588 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1591 *formats = color_formats;
1592 *num = TBM_COLOR_FORMAT_COUNT;
1600 * @brief get the plane data of the surface.
1601 * @param[in] width : the width of the surface
1602 * @param[in] height : the height of the surface
1603 * @param[in] format : the format of the surface
1604 * @param[in] plane_idx : the format of the surface
1605 * @param[out] size : the size of the plane
1606 * @param[out] offset : the offset of the plane
1607 * @param[out] pitch : the pitch of the plane
1608 * @param[out] padding : the padding of the plane
1609 * @return 1 if this function succeeds, otherwise 0.
1612 tbm_sprd_surface_get_plane_data(int width, int height,
1613 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1614 uint32_t *pitch, int *bo_idx)
1622 int _align_height = 0;
1626 case TBM_FORMAT_XRGB4444:
1627 case TBM_FORMAT_XBGR4444:
1628 case TBM_FORMAT_RGBX4444:
1629 case TBM_FORMAT_BGRX4444:
1630 case TBM_FORMAT_ARGB4444:
1631 case TBM_FORMAT_ABGR4444:
1632 case TBM_FORMAT_RGBA4444:
1633 case TBM_FORMAT_BGRA4444:
1634 case TBM_FORMAT_XRGB1555:
1635 case TBM_FORMAT_XBGR1555:
1636 case TBM_FORMAT_RGBX5551:
1637 case TBM_FORMAT_BGRX5551:
1638 case TBM_FORMAT_ARGB1555:
1639 case TBM_FORMAT_ABGR1555:
1640 case TBM_FORMAT_RGBA5551:
1641 case TBM_FORMAT_BGRA5551:
1642 case TBM_FORMAT_RGB565:
1645 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1646 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1650 case TBM_FORMAT_RGB888:
1651 case TBM_FORMAT_BGR888:
1654 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1655 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1659 case TBM_FORMAT_XRGB8888:
1660 case TBM_FORMAT_XBGR8888:
1661 case TBM_FORMAT_RGBX8888:
1662 case TBM_FORMAT_BGRX8888:
1663 case TBM_FORMAT_ARGB8888:
1664 case TBM_FORMAT_ABGR8888:
1665 case TBM_FORMAT_RGBA8888:
1666 case TBM_FORMAT_BGRA8888:
1669 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1670 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1675 case TBM_FORMAT_YUYV:
1676 case TBM_FORMAT_YVYU:
1677 case TBM_FORMAT_UYVY:
1678 case TBM_FORMAT_VYUY:
1679 case TBM_FORMAT_AYUV:
1682 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1683 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1689 * index 0 = Y plane, [7:0] Y
1690 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1692 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1694 case TBM_FORMAT_NV12:
1695 case TBM_FORMAT_NV21:
1697 if (plane_idx == 0) {
1699 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1700 _align_height = SIZE_ALIGN(height, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1701 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1703 } else if (plane_idx == 1) {
1704 _offset = width * height;
1705 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1706 _align_height = SIZE_ALIGN(height / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1707 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1712 case TBM_FORMAT_NV16:
1713 case TBM_FORMAT_NV61:
1715 //if(plane_idx == 0)
1718 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1719 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1724 //else if( plane_idx ==1 )
1727 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1728 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1735 * index 0: Y plane, [7:0] Y
1736 * index 1: Cb plane, [7:0] Cb
1737 * index 2: Cr plane, [7:0] Cr
1739 * index 1: Cr plane, [7:0] Cr
1740 * index 2: Cb plane, [7:0] Cb
1743 NATIVE_BUFFER_FORMAT_YV12
1744 NATIVE_BUFFER_FORMAT_I420
1746 case TBM_FORMAT_YUV410:
1747 case TBM_FORMAT_YVU410:
1750 case TBM_FORMAT_YUV411:
1751 case TBM_FORMAT_YVU411:
1752 case TBM_FORMAT_YUV420:
1753 case TBM_FORMAT_YVU420:
1755 //if(plane_idx == 0)
1758 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1759 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1764 //else if( plane_idx == 1 )
1767 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1768 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1773 //else if (plane_idx == 2 )
1776 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1777 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1781 case TBM_FORMAT_YUV422:
1782 case TBM_FORMAT_YVU422:
1784 //if(plane_idx == 0)
1787 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1788 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1793 //else if( plane_idx == 1 )
1796 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1797 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1802 //else if (plane_idx == 2 )
1805 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1806 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1810 case TBM_FORMAT_YUV444:
1811 case TBM_FORMAT_YVU444:
1813 //if(plane_idx == 0)
1816 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1817 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1822 //else if( plane_idx == 1 )
1825 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1826 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1831 //else if (plane_idx == 2 )
1834 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1835 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1853 tbm_sprd_bo_get_flags(tbm_bo bo)
1855 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1857 tbm_bo_sprd bo_sprd;
1859 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1860 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1862 return bo_sprd->flags_tbm;
1866 tbm_sprd_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1868 tbm_bufmgr_sprd bufmgr_sprd;
1870 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1871 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1873 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1874 bufmgr_sprd->device_name, 0)) {
1875 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1879 bufmgr_sprd->bind_display = NativeDisplay;
1884 MODULEINITPPROTO(init_tbm_bufmgr_priv);
1886 static TBMModuleVersionInfo SprdVersRec = {
1892 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1895 init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd)
1897 tbm_bufmgr_backend bufmgr_backend;
1898 tbm_bufmgr_sprd bufmgr_sprd;
1904 bufmgr_sprd = calloc(1, sizeof(struct _tbm_bufmgr_sprd));
1906 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1910 if (tbm_backend_is_display_server()) {
1911 bufmgr_sprd->fd = tbm_drm_helper_get_master_fd();
1912 if (bufmgr_sprd->fd < 0) {
1913 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1914 if (bufmgr_sprd->fd < 0) {
1915 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to open drm!\n", getpid());
1920 tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
1922 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1923 if (!bufmgr_sprd->device_name) {
1924 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1925 tbm_drm_helper_unset_tbm_master_fd();
1926 goto fail_get_device_name;
1929 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1930 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1931 goto fail_get_auth_info;
1936 bufmgr_sprd->hashBos = drmHashCreate();
1938 //Check if the tbm manager supports dma fence or not.
1939 fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1942 int length = read(fp, buf, 1);
1944 if (length == 1 && buf[0] == '1')
1945 bufmgr_sprd->use_dma_fence = 1;
1950 if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
1951 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to init bufmgr cache state\n", getpid());
1952 goto fail_init_cache_state;
1955 bufmgr_backend = tbm_backend_alloc();
1956 if (!bufmgr_backend) {
1957 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to alloc backend!\n", getpid());
1958 goto fail_alloc_backend;
1961 bufmgr_backend->priv = (void *)bufmgr_sprd;
1962 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1963 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1964 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1965 bufmgr_backend->bo_free = tbm_sprd_bo_free;
1966 bufmgr_backend->bo_import = tbm_sprd_bo_import;
1967 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1968 bufmgr_backend->bo_export = tbm_sprd_bo_export;
1969 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1970 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1971 bufmgr_backend->bo_map = tbm_sprd_bo_map;
1972 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1973 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1974 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1975 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1976 bufmgr_backend->bo_lock = tbm_sprd_bo_lock;
1977 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1978 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1980 if (!tbm_backend_init(bufmgr, bufmgr_backend)) {
1981 TBM_SPRD_LOG("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1982 goto fail_init_backend;
1989 env = getenv("TBM_SPRD_DEBUG");
1992 TBM_SPRD_LOG("TBM_SPRD_DEBUG=%s\n", env);
1998 DBG("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1999 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2000 DBG("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2001 __FUNCTION__, bufmgr_sprd->fd);
2006 tbm_backend_free(bufmgr_backend);
2008 _bufmgr_deinit_cache_state(bufmgr_sprd);
2009 fail_init_cache_state:
2010 if (bufmgr_sprd->hashBos)
2011 drmHashDestroy(bufmgr_sprd->hashBos);
2012 if (tbm_backend_is_display_server())
2013 tbm_drm_helper_unset_tbm_master_fd();
2014 fail_get_device_name:
2015 close(bufmgr_sprd->fd);