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");
91 memset(app_name, 0x00, sizeof(app_name));
93 if ( fgets(app_name, 100, f) == NULL ) {
100 if ( (slash = strrchr(app_name, '/')) != NULL ) {
101 memmove(app_name, slash + 1, strlen(slash));
108 #define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args)
109 #define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args)
111 #define TBM_SPRD_LOG(...)
115 #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
117 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
118 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128)
119 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
122 /* check condition */
123 #define SPRD_RETURN_IF_FAIL(cond) {\
125 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
129 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
131 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
136 struct dma_buf_info {
138 unsigned int fence_supported;
139 unsigned int padding;
142 #define DMA_BUF_ACCESS_READ 0x1
143 #define DMA_BUF_ACCESS_WRITE 0x2
144 #define DMA_BUF_ACCESS_DMA 0x4
145 #define DMA_BUF_ACCESS_MAX 0x8
147 #define DMA_FENCE_LIST_MAX 5
149 struct dma_buf_fence {
154 #define DMABUF_IOCTL_BASE 'F'
155 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
157 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
158 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
159 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
162 #define GLOBAL_KEY ((unsigned int)(-1))
164 #define TBM_SPRD_CACHE_INV 0x01 /**< cache invalidate */
165 #define TBM_SPRD_CACHE_CLN 0x02 /**< cache clean */
166 #define TBM_SPRD_CACHE_ALL 0x10 /**< cache all */
167 #define TBM_SPRD_CACHE_FLUSH (TBM_SPRD_CACHE_INV|TBM_SPRD_CACHE_CLN) /**< cache flush */
168 #define TBM_SPRD_CACHE_FLUSH_ALL (TBM_SPRD_CACHE_FLUSH|TBM_SPRD_CACHE_ALL) /**< cache flush all */
172 DEVICE_CA, /* cache aware device */
173 DEVICE_CO /* cache oblivious device */
176 typedef union _tbm_bo_cache_state tbm_bo_cache_state;
178 union _tbm_bo_cache_state {
181 unsigned int cntFlush: 16; /*Flush all index for sync */
182 unsigned int isCached: 1;
183 unsigned int isDirtied: 2;
187 typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd;
188 typedef struct _tbm_bo_sprd *tbm_bo_sprd;
190 typedef struct _sprd_private {
192 struct _tbm_bo_sprd *bo_priv;
195 /* tbm buffor object for sprd */
196 struct _tbm_bo_sprd {
199 unsigned int name; /* FLINK ID */
201 unsigned int gem; /* GEM Handle */
203 unsigned int dmabuf; /* fd for dmabuf */
205 void *pBase; /* virtual address */
209 unsigned int flags_sprd;
210 unsigned int flags_tbm;
214 pthread_mutex_t mutex;
215 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
219 tbm_bo_cache_state cache_state;
220 unsigned int map_cnt;
223 /* tbm bufmgr private for sprd */
224 struct _tbm_bufmgr_sprd {
236 char *STR_DEVICE[] = {
252 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
263 _tgl_init(int fd, unsigned int key)
265 struct tgl_attribute attr;
269 attr.timeout_ms = 1000;
271 err = ioctl(fd, TGL_IOC_INIT_LOCK, &attr);
273 TBM_SPRD_LOG("[libtbm-sprd:%d] error(%s) %s:%d key:%d\n",
274 getpid(), strerror(errno), __func__, __LINE__, key);
282 _tgl_destroy(int fd, unsigned int key)
286 err = ioctl(fd, TGL_IOC_DESTROY_LOCK, key);
288 TBM_SPRD_LOG("[libtbm-sprd:%d] "
289 "error(%s) %s:%d key:%d\n",
290 getpid(), strerror(errno), __func__, __LINE__, key);
298 _tgl_lock(int fd, unsigned int key)
302 err = ioctl(fd, TGL_IOC_LOCK_LOCK, key);
304 TBM_SPRD_LOG("[libtbm-sprd:%d] "
305 "error(%s) %s:%d key:%d\n",
306 getpid(), strerror(errno), __func__, __LINE__, key);
314 _tgl_unlock(int fd, unsigned int key)
318 err = ioctl(fd, TGL_IOC_UNLOCK_LOCK, key);
320 TBM_SPRD_LOG("[libtbm-sprd:%d] "
321 "error(%s) %s:%d key:%d\n",
322 getpid(), strerror(errno), __func__, __LINE__, key);
331 _tgl_set_data(int fd, unsigned int key, unsigned int val)
334 struct tgl_user_data arg;
338 err = ioctl(fd, TGL_IOC_SET_DATA, &arg);
340 TBM_SPRD_LOG("[libtbm-sprd:%d] "
341 "error(%s) %s:%d key:%d\n",
342 getpid(), strerror(errno), __func__, __LINE__, key);
349 static inline unsigned int
350 _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
353 struct tgl_user_data arg = { 0, };
356 err = ioctl(fd, TGL_IOC_GET_DATA, &arg);
358 TBM_SPRD_LOG("[libtbm-sprd:%d] "
359 "error(%s) %s:%d key:%d\n",
360 getpid(), strerror(errno), __func__, __LINE__, key);
365 *locked = arg.locked;
376 fd = drmOpen(SPRD_DRM_NAME, NULL);
378 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
379 "warning %s:%d fail to open drm\n",
380 getpid(), __FUNCTION__, __LINE__);
385 struct udev *udev = NULL;
386 struct udev_enumerate *e = NULL;
387 struct udev_list_entry *entry = NULL;
388 struct udev_device *device = NULL, *drm_device = NULL, *device_parent = NULL;
389 const char *filepath;
394 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
395 "%s:%d search drm-device by udev\n",
396 getpid(), __FUNCTION__, __LINE__);
400 TBM_SPRD_LOG("udev_new() failed.\n");
404 e = udev_enumerate_new(udev);
405 udev_enumerate_add_match_subsystem(e, "drm");
406 udev_enumerate_add_match_sysname(e, "card[0-9]*");
407 udev_enumerate_scan_devices(e);
409 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
410 device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
411 udev_list_entry_get_name(entry));
412 device_parent = udev_device_get_parent(device);
413 /* Not need unref device_parent. device_parent and device have same refcnt */
415 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
417 DBG("[%s] Found render device: '%s' (%s)\n",
419 udev_device_get_syspath(drm_device),
420 udev_device_get_sysname(device_parent));
424 udev_device_unref(device);
427 udev_enumerate_unref(e);
429 /* Get device file path. */
430 filepath = udev_device_get_devnode(drm_device);
432 TBM_SPRD_LOG("udev_device_get_devnode() failed.\n");
433 udev_device_unref(drm_device);
438 /* Open DRM device file and check validity. */
439 fd = open(filepath, O_RDWR | O_CLOEXEC);
441 TBM_SPRD_LOG("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
442 udev_device_unref(drm_device);
449 TBM_SPRD_LOG("fstat() failed %s.\n");
450 udev_device_unref(drm_device);
455 udev_device_unref(drm_device);
465 _sprd_bo_cache_flush (tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int flags)
467 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
468 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
470 /* cache flush is managed by kernel side when using dma-fence. */
471 if (bufmgr_sprd->use_dma_fence)
474 struct drm_sprd_gem_cache_op cache_op = {0, };
477 /* if bo_sprd is null, do cache_flush_all */
480 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
481 cache_op.size = bo_sprd->size;
483 flags = TBM_SPRD_CACHE_FLUSH_ALL;
485 cache_op.usr_addr = 0;
489 if (flags & TBM_SPRD_CACHE_INV) {
490 if (flags & TBM_SPRD_CACHE_ALL)
491 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
493 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
496 if (flags & TBM_SPRD_CACHE_CLN) {
497 if (flags & TBM_SPRD_CACHE_ALL)
498 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
500 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
503 if (flags & TBM_SPRD_CACHE_ALL)
504 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
506 ret = drmCommandWriteRead (bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
509 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
510 "error %s:%d fail to flush the cache.\n",
511 getpid(), __FUNCTION__, __LINE__);
520 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int import)
522 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
523 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
525 if (bufmgr_sprd->use_dma_fence)
528 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
531 tbm_bo_cache_state cache_state;
534 cache_state.data.isDirtied = DEVICE_NONE;
535 cache_state.data.isCached = 0;
536 cache_state.data.cntFlush = 0;
538 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
546 _bo_set_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int device, int opt)
549 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
550 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
553 unsigned short cntFlush = 0;
555 if (bufmgr_sprd->use_dma_fence)
558 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
561 /* get cache state of a bo */
562 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
564 /* get global cache flush count */
565 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
567 if (opt == TBM_DEVICE_CPU) {
568 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
569 bo_sprd->cache_state.data.isCached)
570 need_flush = TBM_SPRD_CACHE_INV;
572 bo_sprd->cache_state.data.isCached = 1;
573 if (opt & TBM_OPTION_WRITE)
574 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
576 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
577 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
580 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
581 bo_sprd->cache_state.data.isCached &&
582 bo_sprd->cache_state.data.cntFlush == cntFlush)
583 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
585 if (opt & TBM_OPTION_WRITE)
586 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
588 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
589 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
594 if (need_flush & TBM_SPRD_CACHE_ALL)
595 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
597 /* call cache flush */
598 _sprd_bo_cache_flush (bufmgr_sprd, bo_sprd, need_flush);
600 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
602 bo_sprd->cache_state.data.isCached,
603 bo_sprd->cache_state.data.isDirtied,
613 _bo_save_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
616 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
617 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
619 if (bufmgr_sprd->use_dma_fence)
622 unsigned short cntFlush = 0;
624 /* get global cache flush count */
625 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
627 /* save global cache flush count */
628 bo_sprd->cache_state.data.cntFlush = cntFlush;
629 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
636 _bo_destroy_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
638 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
639 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
641 if (bufmgr_sprd->use_dma_fence)
644 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
648 _bufmgr_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
650 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
652 if (bufmgr_sprd->use_dma_fence)
655 /* open tgl fd for saving cache flush data */
656 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
658 if (bufmgr_sprd->tgl_fd < 0) {
659 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
660 if (bufmgr_sprd->tgl_fd < 0) {
661 TBM_SPRD_LOG("[libtbm-sprd:%d] "
662 "error: Fail to open global_lock:%s\n",
663 getpid(), tgl_devfile);
665 close(bufmgr_sprd->tgl_fd);
671 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
672 TBM_SPRD_LOG("[libtbm-sprd:%d] "
673 "error: Fail to initialize the tgl\n",
676 close(bufmgr_sprd->tgl_fd);
685 _bufmgr_deinit_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
687 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
689 if (bufmgr_sprd->use_dma_fence)
692 if (bufmgr_sprd->tgl_fd >= 0)
693 close(bufmgr_sprd->tgl_fd);
696 #ifndef USE_CONTIG_ONLY
698 _get_sprd_flag_from_tbm (unsigned int ftbm)
700 unsigned int flags = 0;
703 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
704 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
705 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
706 * To be updated appropriately once DRM-GEM supports different heap id masks.
709 if (ftbm & TBM_BO_SCANOUT) {
710 flags = SPRD_BO_CONTIG;
712 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
715 if (ftbm & TBM_BO_WC)
717 else if (ftbm & TBM_BO_NONCACHABLE)
718 flags |= SPRD_BO_NONCACHABLE;
724 _get_tbm_flag_from_sprd (unsigned int fsprd)
726 unsigned int flags = 0;
728 if (fsprd & SPRD_BO_NONCONTIG)
729 flags |= TBM_BO_DEFAULT;
731 flags |= TBM_BO_SCANOUT;
733 if (fsprd & SPRD_BO_WC)
735 else if (fsprd & SPRD_BO_CACHABLE)
736 flags |= TBM_BO_DEFAULT;
738 flags |= TBM_BO_NONCACHABLE;
745 _get_name (int fd, unsigned int gem)
747 struct drm_gem_flink arg = {0,};
750 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
751 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
752 "error %s:%d fail to get flink gem=%d\n",
753 getpid(), __FUNCTION__, __LINE__, gem);
757 return (unsigned int)arg.name;
761 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
763 tbm_bo_handle bo_handle;
764 memset (&bo_handle, 0x0, sizeof (uint64_t));
767 case TBM_DEVICE_DEFAULT:
769 bo_handle.u32 = (uint32_t)bo_sprd->gem;
772 if (!bo_sprd->pBase) {
773 struct drm_sprd_gem_mmap arg = {0,};
775 arg.handle = bo_sprd->gem;
776 arg.size = bo_sprd->size;
777 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
778 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
779 "error %s:%d Cannot usrptr gem=%d\n",
780 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
781 return (tbm_bo_handle) NULL;
783 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
786 bo_handle.ptr = (void *)bo_sprd->pBase;
790 if (!bo_sprd->dmabuf) {
791 struct drm_prime_handle arg = {0, };
792 arg.handle = bo_sprd->gem;
793 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
794 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
795 "error %s:%d Cannot dmabuf=%d\n",
796 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
797 return (tbm_bo_handle) NULL;
799 bo_sprd->dmabuf = arg.fd;
802 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
809 //TODO : Add ioctl for GSP MAP once available.
810 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
815 if (!bo_sprd->dmabuf) {
816 struct drm_prime_handle arg = {0, };
818 arg.handle = bo_sprd->gem;
819 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
820 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
821 "error %s:%d Cannot dmabuf=%d\n",
822 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
823 return (tbm_bo_handle) NULL;
825 bo_sprd->dmabuf = arg.fd;
828 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
832 bo_handle.ptr = (void *) NULL;
840 tbm_sprd_bo_size (tbm_bo bo)
842 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
846 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
848 return bo_sprd->size;
852 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
854 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
857 tbm_bufmgr_sprd bufmgr_sprd;
858 unsigned int sprd_flags;
860 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
861 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
863 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
865 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
866 "error %s:%d fail to allocate the bo private\n",
867 getpid(), __FUNCTION__, __LINE__);
871 #ifdef USE_CONTIG_ONLY
872 flags = TBM_BO_SCANOUT;
873 sprd_flags = SPRD_BO_CONTIG;
875 sprd_flags = _get_sprd_flag_from_tbm (flags);
876 if ((flags & TBM_BO_SCANOUT) &&
878 sprd_flags |= SPRD_BO_NONCONTIG;
880 #endif // USE_CONTIG_ONLY
881 struct drm_sprd_gem_create arg = {0, };
882 arg.size = (uint64_t)size;
883 arg.flags = sprd_flags;
884 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
886 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
887 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
888 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
893 bo_sprd->fd = bufmgr_sprd->fd;
894 bo_sprd->gem = arg.handle;
895 bo_sprd->size = size;
896 bo_sprd->flags_tbm = flags;
897 bo_sprd->flags_sprd = sprd_flags;
898 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
900 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 0)) {
901 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
906 pthread_mutex_init(&bo_sprd->mutex, NULL);
908 if (bufmgr_sprd->use_dma_fence
909 && !bo_sprd->dmabuf) {
910 struct drm_prime_handle arg = {0, };
912 arg.handle = bo_sprd->gem;
913 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
914 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
915 "error %s:%d Cannot dmabuf=%d\n",
916 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
920 bo_sprd->dmabuf = arg.fd;
924 PrivGem *privGem = calloc (1, sizeof(PrivGem));
925 privGem->ref_count = 1;
926 privGem->bo_priv = bo_sprd;
927 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
928 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
929 "error %s:%d Cannot insert bo to Hash(%d)\n",
930 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
933 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
934 __FUNCTION__, bo_sprd->size,
935 bo_sprd->gem, bo_sprd->name,
938 return (void *)bo_sprd;
942 tbm_sprd_bo_free(tbm_bo bo)
945 tbm_bufmgr_sprd bufmgr_sprd;
950 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
951 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
953 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
954 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
956 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
957 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
959 if (bo_sprd->pBase) {
960 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
961 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
963 getpid(), __FUNCTION__, __LINE__);
968 if (bo_sprd->dmabuf) {
969 close (bo_sprd->dmabuf);
973 /* delete bo from hash */
974 PrivGem *privGem = NULL;
977 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
979 privGem->ref_count--;
980 if (privGem->ref_count == 0) {
981 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
986 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
987 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
988 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
991 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
993 /* Free gem handle */
994 struct drm_gem_close arg = {0, };
995 memset (&arg, 0, sizeof(arg));
996 arg.handle = bo_sprd->gem;
997 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
998 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1000 getpid(), __FUNCTION__, __LINE__);
1008 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
1010 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1012 tbm_bufmgr_sprd bufmgr_sprd;
1013 tbm_bo_sprd bo_sprd;
1014 PrivGem *privGem = NULL;
1017 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1018 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1020 ret = drmHashLookup (bufmgr_sprd->hashBos, key, (void **)&privGem);
1022 return privGem->bo_priv;
1025 struct drm_gem_open arg = {0, };
1026 struct drm_sprd_gem_info info = {0, };
1029 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
1030 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1031 "error %s:%d Cannot open gem name=%d\n",
1032 getpid(), __FUNCTION__, __LINE__, key);
1036 info.handle = arg.handle;
1037 if (drmCommandWriteRead(bufmgr_sprd->fd,
1040 sizeof(struct drm_sprd_gem_info))) {
1041 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1042 "error %s:%d Cannot get gem info=%d\n",
1043 getpid(), __FUNCTION__, __LINE__, key);
1047 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1049 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1050 "error %s:%d fail to allocate the bo private\n",
1051 getpid(), __FUNCTION__, __LINE__);
1055 bo_sprd->fd = bufmgr_sprd->fd;
1056 bo_sprd->gem = arg.handle;
1057 bo_sprd->size = arg.size;
1058 bo_sprd->flags_sprd = info.flags;
1059 bo_sprd->name = key;
1060 #ifdef USE_CONTIG_ONLY
1061 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1062 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1064 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1067 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1068 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
1073 if (!bo_sprd->dmabuf) {
1074 struct drm_prime_handle arg = {0, };
1076 arg.handle = bo_sprd->gem;
1077 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1078 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1079 "error %s:%d Cannot dmabuf=%d\n",
1080 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1084 bo_sprd->dmabuf = arg.fd;
1087 /* add bo to hash */
1088 privGem = calloc (1, sizeof(PrivGem));
1089 privGem->ref_count = 1;
1090 privGem->bo_priv = bo_sprd;
1091 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1092 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1093 "error %s:%d Cannot insert bo to Hash(%d)\n",
1094 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1097 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1098 __FUNCTION__, bo_sprd->size,
1099 bo_sprd->gem, bo_sprd->name,
1100 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1102 return (void *)bo_sprd;
1106 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
1108 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1110 tbm_bufmgr_sprd bufmgr_sprd;
1111 tbm_bo_sprd bo_sprd;
1112 PrivGem *privGem = NULL;
1116 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1117 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1119 //getting handle from fd
1120 unsigned int gem = 0;
1121 struct drm_prime_handle arg = {0, };
1125 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1126 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1127 bo, arg.fd, strerror(errno));
1132 name = _get_name (bufmgr_sprd->fd, gem);
1134 ret = drmHashLookup (bufmgr_sprd->hashBos, name, (void **)&privGem);
1136 if (gem == privGem->bo_priv->gem) {
1137 return privGem->bo_priv;
1141 unsigned int real_size = -1;
1142 struct drm_sprd_gem_info info = {0, };
1144 /* Determine size of bo. The fd-to-handle ioctl really should
1145 * return the size, but it doesn't. If we have kernel 3.12 or
1146 * later, we can lseek on the prime fd to get the size. Older
1147 * kernels will just fail, in which case we fall back to the
1148 * provided (estimated or guess size). */
1149 real_size = lseek(key, 0, SEEK_END);
1152 if (drmCommandWriteRead(bufmgr_sprd->fd,
1155 sizeof(struct drm_sprd_gem_info))) {
1156 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1157 bo, gem, key, strerror(errno));
1161 if (real_size == -1)
1162 real_size = info.size;
1164 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1166 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
1170 bo_sprd->fd = bufmgr_sprd->fd;
1172 bo_sprd->size = real_size;
1173 bo_sprd->flags_sprd = info.flags;
1174 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1176 bo_sprd->name = name;
1177 if (!bo_sprd->name) {
1178 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1179 bo, gem, key, strerror(errno));
1184 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1185 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
1190 /* add bo to hash */
1193 privGem = calloc (1, sizeof(PrivGem));
1195 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1196 "error %s:%d Fail to calloc privGem\n",
1197 getpid(), __FUNCTION__, __LINE__);
1202 privGem->ref_count = 1;
1203 privGem->bo_priv = bo_sprd;
1204 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1205 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1206 bo, bo_sprd->name, gem, key);
1209 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1212 bo_sprd->gem, bo_sprd->name,
1215 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1218 return (void *)bo_sprd;
1222 tbm_sprd_bo_export (tbm_bo bo)
1224 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1226 tbm_bo_sprd bo_sprd;
1228 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1229 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1231 if (!bo_sprd->name) {
1232 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1233 if (!bo_sprd->name) {
1234 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1235 "error %s:%d Cannot get name\n",
1236 getpid(), __FUNCTION__, __LINE__);
1241 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1242 __FUNCTION__, bo_sprd->size,
1243 bo_sprd->gem, bo_sprd->name,
1244 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1246 return (unsigned int)bo_sprd->name;
1250 tbm_sprd_bo_export_fd (tbm_bo bo)
1252 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, -1);
1254 tbm_bo_sprd bo_sprd;
1257 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1258 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, -1);
1260 struct drm_prime_handle arg = {0, };
1262 arg.handle = bo_sprd->gem;
1263 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1265 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
1266 bo, bo_sprd->gem, strerror(errno));
1267 return (tbm_fd) ret;
1270 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1273 bo_sprd->gem, bo_sprd->name,
1276 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1279 return (tbm_fd)arg.fd;
1283 static tbm_bo_handle
1284 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
1286 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1288 tbm_bo_handle bo_handle;
1289 tbm_bo_sprd bo_sprd;
1291 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1292 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1294 if (!bo_sprd->gem) {
1295 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1296 "error %s:%d Cannot map gem=%d\n",
1297 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1298 return (tbm_bo_handle) NULL;
1301 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1302 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1304 /*Get mapped bo_handle*/
1305 bo_handle = _sprd_bo_handle (bo_sprd, device);
1306 if (bo_handle.ptr == NULL) {
1307 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1308 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1309 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1310 return (tbm_bo_handle) NULL;
1316 static tbm_bo_handle
1317 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
1319 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1321 tbm_bo_handle bo_handle;
1322 tbm_bo_sprd bo_sprd;
1323 tbm_bufmgr_sprd bufmgr_sprd;
1325 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1326 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, (tbm_bo_handle) NULL);
1328 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1329 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1331 if (!bo_sprd->gem) {
1332 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1333 "error %s:%d Cannot map gem=%d\n",
1334 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1335 return (tbm_bo_handle) NULL;
1338 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1339 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1341 /*Get mapped bo_handle*/
1342 bo_handle = _sprd_bo_handle (bo_sprd, device);
1343 if (bo_handle.ptr == NULL) {
1344 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1345 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1346 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1347 return (tbm_bo_handle) NULL;
1350 if (bo_sprd->map_cnt == 0)
1351 _bo_set_cache_state (bufmgr_sprd, bo_sprd, device, opt);
1359 tbm_sprd_bo_unmap (tbm_bo bo)
1361 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1363 tbm_bo_sprd bo_sprd;
1364 tbm_bufmgr_sprd bufmgr_sprd;
1366 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1367 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1369 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1370 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1377 if (bo_sprd->map_cnt == 0)
1378 _bo_save_cache_state (bufmgr_sprd, bo_sprd);
1380 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1381 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1387 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1389 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1391 tbm_bufmgr_sprd bufmgr_sprd;
1392 tbm_bo_sprd bo_sprd;
1395 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1396 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1398 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1399 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1401 if (bufmgr_sprd->use_dma_fence) {
1402 #if USE_BACKEND_LOCK
1403 struct dma_buf_fence fence;
1405 memset(&fence, 0, sizeof(struct dma_buf_fence));
1407 /* Check if the given type is valid or not. */
1408 if (opt & TBM_OPTION_WRITE) {
1409 if (device == TBM_DEVICE_CPU)
1410 fence.type = DMA_BUF_ACCESS_WRITE;
1411 else if (device == TBM_DEVICE_3D)
1412 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1414 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1415 getpid(), __FUNCTION__);
1418 } else if (opt & TBM_OPTION_READ) {
1419 if (device == TBM_DEVICE_CPU)
1420 fence.type = DMA_BUF_ACCESS_READ;
1421 else if (device == TBM_DEVICE_3D)
1422 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1424 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1425 getpid(), __FUNCTION__);
1429 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1430 __FUNCTION__, __LINE__);
1434 /* Check if the tbm manager supports dma fence or not. */
1435 if (!bufmgr_sprd->use_dma_fence) {
1436 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1437 "error %s:%d Not support DMA FENCE(%s)\n",
1438 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1443 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1445 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1446 "error %s:%d Can not set GET FENCE(%s)\n",
1447 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1451 pthread_mutex_lock(&bo_sprd->mutex);
1453 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1454 if (bo_sprd->dma_fence[i].ctx == 0) {
1455 bo_sprd->dma_fence[i].type = fence.type;
1456 bo_sprd->dma_fence[i].ctx = fence.ctx;
1460 if (i == DMA_FENCE_LIST_MAX) {
1461 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1462 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1463 "error %s:%d fence list is full\n",
1464 getpid(), __FUNCTION__, __LINE__);
1466 pthread_mutex_unlock(&bo_sprd->mutex);
1468 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1470 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1473 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1475 DBG ("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1476 getpid(), __FUNCTION__, bo_sprd->name);
1486 tbm_sprd_bo_unlock(tbm_bo bo)
1488 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1490 tbm_bufmgr_sprd bufmgr_sprd;
1491 tbm_bo_sprd bo_sprd;
1494 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1495 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1497 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1498 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1500 if (bufmgr_sprd->use_dma_fence) {
1501 #if USE_BACKEND_LOCK
1502 struct dma_buf_fence fence;
1504 if (!bo_sprd->dma_fence[0].ctx) {
1505 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1510 if (!bo_sprd->dma_fence[0].type) {
1511 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1516 pthread_mutex_lock(&bo_sprd->mutex);
1517 fence.type = bo_sprd->dma_fence[0].type;
1518 fence.ctx = bo_sprd->dma_fence[0].ctx;
1520 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1521 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1522 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1524 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1525 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1526 pthread_mutex_unlock(&bo_sprd->mutex);
1528 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1530 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1531 "error %s:%d Can not set PUT FENCE(%s)\n",
1532 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1536 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1538 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1540 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1542 DBG ("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1543 getpid(), __FUNCTION__, bo_sprd->name);
1553 tbm_sprd_bufmgr_deinit (void *priv)
1555 SPRD_RETURN_IF_FAIL (priv != NULL);
1557 tbm_bufmgr_sprd bufmgr_sprd;
1559 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1561 if (bufmgr_sprd->hashBos) {
1565 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1567 drmHashDelete (bufmgr_sprd->hashBos, key);
1570 drmHashDestroy (bufmgr_sprd->hashBos);
1571 bufmgr_sprd->hashBos = NULL;
1574 if (bufmgr_sprd->bind_display)
1575 tbm_drm_helper_wl_auth_server_deinit();
1577 if (tbm_backend_is_display_server())
1578 tbm_drm_helper_unset_tbm_master_fd();
1580 if (bufmgr_sprd->device_name)
1581 free(bufmgr_sprd->device_name);
1583 _bufmgr_deinit_cache_state(bufmgr_sprd);
1585 close (bufmgr_sprd->fd);
1591 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1593 uint32_t *color_formats = NULL;
1595 color_formats = (uint32_t *)calloc (1,
1596 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1598 if ( color_formats == NULL ) {
1601 memcpy( color_formats, tbm_sprd_color_format_list ,
1602 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1605 *formats = color_formats;
1606 *num = TBM_COLOR_FORMAT_COUNT;
1614 * @brief get the plane data of the surface.
1615 * @param[in] width : the width of the surface
1616 * @param[in] height : the height of the surface
1617 * @param[in] format : the format of the surface
1618 * @param[in] plane_idx : the format of the surface
1619 * @param[out] size : the size of the plane
1620 * @param[out] offset : the offset of the plane
1621 * @param[out] pitch : the pitch of the plane
1622 * @param[out] padding : the padding of the plane
1623 * @return 1 if this function succeeds, otherwise 0.
1626 tbm_sprd_surface_get_plane_data(int width, int height,
1627 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1628 uint32_t *pitch, int *bo_idx)
1639 case TBM_FORMAT_XRGB4444:
1640 case TBM_FORMAT_XBGR4444:
1641 case TBM_FORMAT_RGBX4444:
1642 case TBM_FORMAT_BGRX4444:
1643 case TBM_FORMAT_ARGB4444:
1644 case TBM_FORMAT_ABGR4444:
1645 case TBM_FORMAT_RGBA4444:
1646 case TBM_FORMAT_BGRA4444:
1647 case TBM_FORMAT_XRGB1555:
1648 case TBM_FORMAT_XBGR1555:
1649 case TBM_FORMAT_RGBX5551:
1650 case TBM_FORMAT_BGRX5551:
1651 case TBM_FORMAT_ARGB1555:
1652 case TBM_FORMAT_ABGR1555:
1653 case TBM_FORMAT_RGBA5551:
1654 case TBM_FORMAT_BGRA5551:
1655 case TBM_FORMAT_RGB565:
1658 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1659 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1663 case TBM_FORMAT_RGB888:
1664 case TBM_FORMAT_BGR888:
1667 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1668 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1672 case TBM_FORMAT_XRGB8888:
1673 case TBM_FORMAT_XBGR8888:
1674 case TBM_FORMAT_RGBX8888:
1675 case TBM_FORMAT_BGRX8888:
1676 case TBM_FORMAT_ARGB8888:
1677 case TBM_FORMAT_ABGR8888:
1678 case TBM_FORMAT_RGBA8888:
1679 case TBM_FORMAT_BGRA8888:
1682 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1683 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1688 case TBM_FORMAT_YUYV:
1689 case TBM_FORMAT_YVYU:
1690 case TBM_FORMAT_UYVY:
1691 case TBM_FORMAT_VYUY:
1692 case TBM_FORMAT_AYUV:
1695 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1696 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1702 * index 0 = Y plane, [7:0] Y
1703 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1705 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1707 case TBM_FORMAT_NV12:
1708 case TBM_FORMAT_NV21:
1710 if (plane_idx == 0) {
1712 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1713 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1715 } else if ( plane_idx == 1 ) {
1716 _offset = width * height;
1717 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1718 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1723 case TBM_FORMAT_NV16:
1724 case TBM_FORMAT_NV61:
1726 //if(plane_idx == 0)
1729 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1730 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1735 //else if( plane_idx ==1 )
1738 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1739 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1746 * index 0: Y plane, [7:0] Y
1747 * index 1: Cb plane, [7:0] Cb
1748 * index 2: Cr plane, [7:0] Cr
1750 * index 1: Cr plane, [7:0] Cr
1751 * index 2: Cb plane, [7:0] Cb
1754 NATIVE_BUFFER_FORMAT_YV12
1755 NATIVE_BUFFER_FORMAT_I420
1757 case TBM_FORMAT_YUV410:
1758 case TBM_FORMAT_YVU410:
1761 case TBM_FORMAT_YUV411:
1762 case TBM_FORMAT_YVU411:
1763 case TBM_FORMAT_YUV420:
1764 case TBM_FORMAT_YVU420:
1766 //if(plane_idx == 0)
1769 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1770 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1775 //else if( plane_idx == 1 )
1778 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1779 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1784 //else if (plane_idx == 2 )
1787 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1788 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1792 case TBM_FORMAT_YUV422:
1793 case TBM_FORMAT_YVU422:
1795 //if(plane_idx == 0)
1798 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1799 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1804 //else if( plane_idx == 1 )
1807 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1808 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1813 //else if (plane_idx == 2 )
1816 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1817 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1821 case TBM_FORMAT_YUV444:
1822 case TBM_FORMAT_YVU444:
1824 //if(plane_idx == 0)
1827 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1828 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1833 //else if( plane_idx == 1 )
1836 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1837 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1842 //else if (plane_idx == 2 )
1845 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1846 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1864 tbm_sprd_bo_get_flags (tbm_bo bo)
1866 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1868 tbm_bo_sprd bo_sprd;
1870 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1871 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1873 return bo_sprd->flags_tbm;
1877 tbm_sprd_bufmgr_bind_native_display (tbm_bufmgr bufmgr, void *NativeDisplay)
1879 tbm_bufmgr_sprd bufmgr_sprd;
1881 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1882 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1884 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1885 bufmgr_sprd->device_name, 0)) {
1886 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1890 bufmgr_sprd->bind_display = NativeDisplay;
1895 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1897 static TBMModuleVersionInfo SprdVersRec = {
1903 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1906 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1908 tbm_bufmgr_sprd bufmgr_sprd;
1909 tbm_bufmgr_backend bufmgr_backend;
1914 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1916 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1920 if (tbm_backend_is_display_server()) {
1923 bufmgr_sprd->fd = -1;
1924 master_fd = tbm_drm_helper_get_master_fd();
1926 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1928 bufmgr_sprd->fd = master_fd;
1930 if (bufmgr_sprd->fd < 0) {
1931 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1936 tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
1938 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1940 if (!bufmgr_sprd->device_name)
1942 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1943 close(bufmgr_sprd->fd);
1949 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1950 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1957 bufmgr_sprd->hashBos = drmHashCreate ();
1959 //Check if the tbm manager supports dma fence or not.
1960 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1964 length = read(fp, buf, 1);
1966 if (length == 1 && buf[0] == '1')
1967 bufmgr_sprd->use_dma_fence = 1;
1972 if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
1973 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: init bufmgr cache state failed!\n", getpid());
1975 tbm_drm_helper_unset_tbm_master_fd();
1976 close(bufmgr_sprd->fd);
1982 bufmgr_backend = tbm_backend_alloc();
1983 if (!bufmgr_backend) {
1984 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1986 _bufmgr_deinit_cache_state(bufmgr_sprd);
1988 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 tbm_drm_helper_unset_tbm_master_fd();
2021 close(bufmgr_sprd->fd);
2030 env = getenv ("TBM_SPRD_DEBUG");
2032 bDebug = atoi (env);
2033 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
2040 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
2041 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2043 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2044 __FUNCTION__, bufmgr_sprd->fd);