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;
393 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
394 "%s:%d search drm-device by udev\n",
395 getpid(), __FUNCTION__, __LINE__);
399 TBM_SPRD_LOG("udev_new() failed.\n");
403 e = udev_enumerate_new(udev);
404 udev_enumerate_add_match_subsystem(e, "drm");
405 udev_enumerate_add_match_sysname(e, "card[0-9]*");
406 udev_enumerate_scan_devices(e);
408 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
409 device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
410 udev_list_entry_get_name(entry));
411 device_parent = udev_device_get_parent(device);
412 /* Not need unref device_parent. device_parent and device have same refcnt */
414 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
416 DBG("[%s] Found render device: '%s' (%s)\n",
418 udev_device_get_syspath(drm_device),
419 udev_device_get_sysname(device_parent));
423 udev_device_unref(device);
426 udev_enumerate_unref(e);
428 /* Get device file path. */
429 filepath = udev_device_get_devnode(drm_device);
431 TBM_SPRD_LOG("udev_device_get_devnode() failed.\n");
432 udev_device_unref(drm_device);
437 /* Open DRM device file and check validity. */
438 fd = open(filepath, O_RDWR | O_CLOEXEC);
440 TBM_SPRD_LOG("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
441 udev_device_unref(drm_device);
448 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);
669 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
670 TBM_SPRD_LOG("[libtbm-sprd:%d] "
671 "error: Fail to initialize the tgl\n",
674 close(bufmgr_sprd->tgl_fd);
683 _bufmgr_deinit_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
685 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
687 if (bufmgr_sprd->use_dma_fence)
690 if (bufmgr_sprd->tgl_fd >= 0)
691 close(bufmgr_sprd->tgl_fd);
694 #ifndef USE_CONTIG_ONLY
696 _get_sprd_flag_from_tbm (unsigned int ftbm)
698 unsigned int flags = 0;
701 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
702 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
703 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
704 * To be updated appropriately once DRM-GEM supports different heap id masks.
707 if (ftbm & TBM_BO_SCANOUT) {
708 flags = SPRD_BO_CONTIG;
710 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
713 if (ftbm & TBM_BO_WC)
715 else if (ftbm & TBM_BO_NONCACHABLE)
716 flags |= SPRD_BO_NONCACHABLE;
722 _get_tbm_flag_from_sprd (unsigned int fsprd)
724 unsigned int flags = 0;
726 if (fsprd & SPRD_BO_NONCONTIG)
727 flags |= TBM_BO_DEFAULT;
729 flags |= TBM_BO_SCANOUT;
731 if (fsprd & SPRD_BO_WC)
733 else if (fsprd & SPRD_BO_CACHABLE)
734 flags |= TBM_BO_DEFAULT;
736 flags |= TBM_BO_NONCACHABLE;
743 _get_name (int fd, unsigned int gem)
745 struct drm_gem_flink arg = {0,};
748 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
749 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
750 "error %s:%d fail to get flink gem=%d\n",
751 getpid(), __FUNCTION__, __LINE__, gem);
755 return (unsigned int)arg.name;
759 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
761 tbm_bo_handle bo_handle;
762 memset (&bo_handle, 0x0, sizeof (uint64_t));
765 case TBM_DEVICE_DEFAULT:
767 bo_handle.u32 = (uint32_t)bo_sprd->gem;
770 if (!bo_sprd->pBase) {
771 struct drm_sprd_gem_mmap arg = {0,};
773 arg.handle = bo_sprd->gem;
774 arg.size = bo_sprd->size;
775 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
776 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
777 "error %s:%d Cannot usrptr gem=%d\n",
778 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
779 return (tbm_bo_handle) NULL;
781 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
784 bo_handle.ptr = (void *)bo_sprd->pBase;
788 if (!bo_sprd->dmabuf) {
789 struct drm_prime_handle arg = {0, };
790 arg.handle = bo_sprd->gem;
791 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
792 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
793 "error %s:%d Cannot dmabuf=%d\n",
794 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
795 return (tbm_bo_handle) NULL;
797 bo_sprd->dmabuf = arg.fd;
800 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
807 //TODO : Add ioctl for GSP MAP once available.
808 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
813 if (!bo_sprd->dmabuf) {
814 struct drm_prime_handle arg = {0, };
816 arg.handle = bo_sprd->gem;
817 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
818 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
819 "error %s:%d Cannot dmabuf=%d\n",
820 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
821 return (tbm_bo_handle) NULL;
823 bo_sprd->dmabuf = arg.fd;
826 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
830 bo_handle.ptr = (void *) NULL;
838 tbm_sprd_bo_size (tbm_bo bo)
840 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
844 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
846 return bo_sprd->size;
850 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
852 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
855 tbm_bufmgr_sprd bufmgr_sprd;
856 unsigned int sprd_flags;
858 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
859 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
861 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
863 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
864 "error %s:%d fail to allocate the bo private\n",
865 getpid(), __FUNCTION__, __LINE__);
869 #ifdef USE_CONTIG_ONLY
870 flags = TBM_BO_SCANOUT;
871 sprd_flags = SPRD_BO_CONTIG;
873 sprd_flags = _get_sprd_flag_from_tbm (flags);
874 if ((flags & TBM_BO_SCANOUT) &&
876 sprd_flags |= SPRD_BO_NONCONTIG;
878 #endif // USE_CONTIG_ONLY
879 struct drm_sprd_gem_create arg = {0, };
880 arg.size = (uint64_t)size;
881 arg.flags = sprd_flags;
882 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
884 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
885 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
886 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
891 bo_sprd->fd = bufmgr_sprd->fd;
892 bo_sprd->gem = arg.handle;
893 bo_sprd->size = size;
894 bo_sprd->flags_tbm = flags;
895 bo_sprd->flags_sprd = sprd_flags;
896 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
898 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 0)) {
899 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
904 pthread_mutex_init(&bo_sprd->mutex, NULL);
906 if (bufmgr_sprd->use_dma_fence
907 && !bo_sprd->dmabuf) {
908 struct drm_prime_handle arg = {0, };
910 arg.handle = bo_sprd->gem;
911 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
912 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
913 "error %s:%d Cannot dmabuf=%d\n",
914 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
918 bo_sprd->dmabuf = arg.fd;
922 PrivGem *privGem = calloc (1, sizeof(PrivGem));
923 privGem->ref_count = 1;
924 privGem->bo_priv = bo_sprd;
925 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
926 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
927 "error %s:%d Cannot insert bo to Hash(%d)\n",
928 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
931 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
932 __FUNCTION__, bo_sprd->size,
933 bo_sprd->gem, bo_sprd->name,
936 return (void *)bo_sprd;
940 tbm_sprd_bo_free(tbm_bo bo)
943 tbm_bufmgr_sprd bufmgr_sprd;
948 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
949 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
951 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
952 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
954 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
955 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
957 if (bo_sprd->pBase) {
958 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
959 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
961 getpid(), __FUNCTION__, __LINE__);
966 if (bo_sprd->dmabuf) {
967 close (bo_sprd->dmabuf);
971 /* delete bo from hash */
972 PrivGem *privGem = NULL;
975 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
977 privGem->ref_count--;
978 if (privGem->ref_count == 0) {
979 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
984 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
985 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
986 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
989 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
991 /* Free gem handle */
992 struct drm_gem_close arg = {0, };
993 memset (&arg, 0, sizeof(arg));
994 arg.handle = bo_sprd->gem;
995 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
996 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
998 getpid(), __FUNCTION__, __LINE__);
1006 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
1008 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1010 tbm_bufmgr_sprd bufmgr_sprd;
1011 tbm_bo_sprd bo_sprd;
1012 PrivGem *privGem = NULL;
1015 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1016 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1018 ret = drmHashLookup (bufmgr_sprd->hashBos, key, (void **)&privGem);
1020 return privGem->bo_priv;
1023 struct drm_gem_open arg = {0, };
1024 struct drm_sprd_gem_info info = {0, };
1027 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
1028 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1029 "error %s:%d Cannot open gem name=%d\n",
1030 getpid(), __FUNCTION__, __LINE__, key);
1034 info.handle = arg.handle;
1035 if (drmCommandWriteRead(bufmgr_sprd->fd,
1038 sizeof(struct drm_sprd_gem_info))) {
1039 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1040 "error %s:%d Cannot get gem info=%d\n",
1041 getpid(), __FUNCTION__, __LINE__, key);
1045 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1047 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1048 "error %s:%d fail to allocate the bo private\n",
1049 getpid(), __FUNCTION__, __LINE__);
1053 bo_sprd->fd = bufmgr_sprd->fd;
1054 bo_sprd->gem = arg.handle;
1055 bo_sprd->size = arg.size;
1056 bo_sprd->flags_sprd = info.flags;
1057 bo_sprd->name = key;
1058 #ifdef USE_CONTIG_ONLY
1059 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1060 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1062 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1065 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1066 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
1071 if (!bo_sprd->dmabuf) {
1072 struct drm_prime_handle arg = {0, };
1074 arg.handle = bo_sprd->gem;
1075 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1076 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1077 "error %s:%d Cannot dmabuf=%d\n",
1078 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1082 bo_sprd->dmabuf = arg.fd;
1085 /* add bo to hash */
1086 privGem = calloc (1, sizeof(PrivGem));
1087 privGem->ref_count = 1;
1088 privGem->bo_priv = bo_sprd;
1089 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1090 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1091 "error %s:%d Cannot insert bo to Hash(%d)\n",
1092 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1095 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1096 __FUNCTION__, bo_sprd->size,
1097 bo_sprd->gem, bo_sprd->name,
1098 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1100 return (void *)bo_sprd;
1104 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
1106 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1108 tbm_bufmgr_sprd bufmgr_sprd;
1109 tbm_bo_sprd bo_sprd;
1110 PrivGem *privGem = NULL;
1114 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1115 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1117 //getting handle from fd
1118 unsigned int gem = 0;
1119 struct drm_prime_handle arg = {0, };
1123 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1124 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1125 bo, arg.fd, strerror(errno));
1130 name = _get_name (bufmgr_sprd->fd, gem);
1132 ret = drmHashLookup (bufmgr_sprd->hashBos, name, (void **)&privGem);
1134 if (gem == privGem->bo_priv->gem) {
1135 return privGem->bo_priv;
1139 unsigned int real_size = -1;
1140 struct drm_sprd_gem_info info = {0, };
1142 /* Determine size of bo. The fd-to-handle ioctl really should
1143 * return the size, but it doesn't. If we have kernel 3.12 or
1144 * later, we can lseek on the prime fd to get the size. Older
1145 * kernels will just fail, in which case we fall back to the
1146 * provided (estimated or guess size). */
1147 real_size = lseek(key, 0, SEEK_END);
1150 if (drmCommandWriteRead(bufmgr_sprd->fd,
1153 sizeof(struct drm_sprd_gem_info))) {
1154 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1155 bo, gem, key, strerror(errno));
1159 if (real_size == -1)
1160 real_size = info.size;
1162 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1164 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
1168 bo_sprd->fd = bufmgr_sprd->fd;
1170 bo_sprd->size = real_size;
1171 bo_sprd->flags_sprd = info.flags;
1172 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1174 bo_sprd->name = name;
1175 if (!bo_sprd->name) {
1176 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1177 bo, gem, key, strerror(errno));
1182 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1183 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
1188 /* add bo to hash */
1191 privGem = calloc (1, sizeof(PrivGem));
1193 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1194 "error %s:%d Fail to calloc privGem\n",
1195 getpid(), __FUNCTION__, __LINE__);
1200 privGem->ref_count = 1;
1201 privGem->bo_priv = bo_sprd;
1202 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1203 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1204 bo, bo_sprd->name, gem, key);
1207 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1210 bo_sprd->gem, bo_sprd->name,
1213 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1216 return (void *)bo_sprd;
1220 tbm_sprd_bo_export (tbm_bo bo)
1222 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1224 tbm_bo_sprd bo_sprd;
1226 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1227 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1229 if (!bo_sprd->name) {
1230 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1231 if (!bo_sprd->name) {
1232 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1233 "error %s:%d Cannot get name\n",
1234 getpid(), __FUNCTION__, __LINE__);
1239 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1240 __FUNCTION__, bo_sprd->size,
1241 bo_sprd->gem, bo_sprd->name,
1242 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1244 return (unsigned int)bo_sprd->name;
1248 tbm_sprd_bo_export_fd (tbm_bo bo)
1250 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, -1);
1252 tbm_bo_sprd bo_sprd;
1255 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1256 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, -1);
1258 struct drm_prime_handle arg = {0, };
1260 arg.handle = bo_sprd->gem;
1261 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1263 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
1264 bo, bo_sprd->gem, strerror(errno));
1265 return (tbm_fd) ret;
1268 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1271 bo_sprd->gem, bo_sprd->name,
1274 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1277 return (tbm_fd)arg.fd;
1281 static tbm_bo_handle
1282 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
1284 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1286 tbm_bo_handle bo_handle;
1287 tbm_bo_sprd bo_sprd;
1289 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1290 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1292 if (!bo_sprd->gem) {
1293 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1294 "error %s:%d Cannot map gem=%d\n",
1295 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1296 return (tbm_bo_handle) NULL;
1299 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1300 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1302 /*Get mapped bo_handle*/
1303 bo_handle = _sprd_bo_handle (bo_sprd, device);
1304 if (bo_handle.ptr == NULL) {
1305 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1306 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1307 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1308 return (tbm_bo_handle) NULL;
1314 static tbm_bo_handle
1315 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
1317 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1319 tbm_bo_handle bo_handle;
1320 tbm_bo_sprd bo_sprd;
1321 tbm_bufmgr_sprd bufmgr_sprd;
1323 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1324 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, (tbm_bo_handle) NULL);
1326 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1327 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1329 if (!bo_sprd->gem) {
1330 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1331 "error %s:%d Cannot map gem=%d\n",
1332 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1333 return (tbm_bo_handle) NULL;
1336 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1337 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1339 /*Get mapped bo_handle*/
1340 bo_handle = _sprd_bo_handle (bo_sprd, device);
1341 if (bo_handle.ptr == NULL) {
1342 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1343 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1344 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1345 return (tbm_bo_handle) NULL;
1348 if (bo_sprd->map_cnt == 0)
1349 _bo_set_cache_state (bufmgr_sprd, bo_sprd, device, opt);
1357 tbm_sprd_bo_unmap (tbm_bo bo)
1359 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1361 tbm_bo_sprd bo_sprd;
1362 tbm_bufmgr_sprd bufmgr_sprd;
1364 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1365 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1367 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1368 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1375 if (bo_sprd->map_cnt == 0)
1376 _bo_save_cache_state (bufmgr_sprd, bo_sprd);
1378 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1379 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1385 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1387 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1389 tbm_bufmgr_sprd bufmgr_sprd;
1390 tbm_bo_sprd bo_sprd;
1392 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1393 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1395 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1396 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1398 #if USE_BACKEND_LOCK
1401 if (bufmgr_sprd->use_dma_fence) {
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;
1493 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1494 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1496 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1497 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1499 #if USE_BACKEND_LOCK
1502 if (bufmgr_sprd->use_dma_fence) {
1503 struct dma_buf_fence fence;
1505 if (!bo_sprd->dma_fence[0].ctx) {
1506 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1511 if (!bo_sprd->dma_fence[0].type) {
1512 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1517 pthread_mutex_lock(&bo_sprd->mutex);
1518 fence.type = bo_sprd->dma_fence[0].type;
1519 fence.ctx = bo_sprd->dma_fence[0].ctx;
1521 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1522 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1523 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1525 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1526 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1527 pthread_mutex_unlock(&bo_sprd->mutex);
1529 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1531 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1532 "error %s:%d Can not set PUT FENCE(%s)\n",
1533 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1537 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1539 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1541 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1543 DBG ("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1544 getpid(), __FUNCTION__, bo_sprd->name);
1554 tbm_sprd_bufmgr_deinit (void *priv)
1556 SPRD_RETURN_IF_FAIL (priv != NULL);
1558 tbm_bufmgr_sprd bufmgr_sprd;
1560 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1562 if (bufmgr_sprd->hashBos) {
1566 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1568 drmHashDelete (bufmgr_sprd->hashBos, key);
1571 drmHashDestroy (bufmgr_sprd->hashBos);
1572 bufmgr_sprd->hashBos = NULL;
1575 if (bufmgr_sprd->bind_display)
1576 tbm_drm_helper_wl_auth_server_deinit();
1578 if (tbm_backend_is_display_server())
1579 tbm_drm_helper_unset_tbm_master_fd();
1581 if (bufmgr_sprd->device_name)
1582 free(bufmgr_sprd->device_name);
1584 _bufmgr_deinit_cache_state(bufmgr_sprd);
1586 close (bufmgr_sprd->fd);
1592 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1594 uint32_t *color_formats = NULL;
1596 color_formats = (uint32_t *)calloc (1,
1597 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1599 if ( color_formats == NULL ) {
1602 memcpy( color_formats, tbm_sprd_color_format_list ,
1603 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1606 *formats = color_formats;
1607 *num = TBM_COLOR_FORMAT_COUNT;
1615 * @brief get the plane data of the surface.
1616 * @param[in] width : the width of the surface
1617 * @param[in] height : the height of the surface
1618 * @param[in] format : the format of the surface
1619 * @param[in] plane_idx : the format of the surface
1620 * @param[out] size : the size of the plane
1621 * @param[out] offset : the offset of the plane
1622 * @param[out] pitch : the pitch of the plane
1623 * @param[out] padding : the padding of the plane
1624 * @return 1 if this function succeeds, otherwise 0.
1627 tbm_sprd_surface_get_plane_data(int width, int height,
1628 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1629 uint32_t *pitch, int *bo_idx)
1640 case TBM_FORMAT_XRGB4444:
1641 case TBM_FORMAT_XBGR4444:
1642 case TBM_FORMAT_RGBX4444:
1643 case TBM_FORMAT_BGRX4444:
1644 case TBM_FORMAT_ARGB4444:
1645 case TBM_FORMAT_ABGR4444:
1646 case TBM_FORMAT_RGBA4444:
1647 case TBM_FORMAT_BGRA4444:
1648 case TBM_FORMAT_XRGB1555:
1649 case TBM_FORMAT_XBGR1555:
1650 case TBM_FORMAT_RGBX5551:
1651 case TBM_FORMAT_BGRX5551:
1652 case TBM_FORMAT_ARGB1555:
1653 case TBM_FORMAT_ABGR1555:
1654 case TBM_FORMAT_RGBA5551:
1655 case TBM_FORMAT_BGRA5551:
1656 case TBM_FORMAT_RGB565:
1659 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1660 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1664 case TBM_FORMAT_RGB888:
1665 case TBM_FORMAT_BGR888:
1668 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1669 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1673 case TBM_FORMAT_XRGB8888:
1674 case TBM_FORMAT_XBGR8888:
1675 case TBM_FORMAT_RGBX8888:
1676 case TBM_FORMAT_BGRX8888:
1677 case TBM_FORMAT_ARGB8888:
1678 case TBM_FORMAT_ABGR8888:
1679 case TBM_FORMAT_RGBA8888:
1680 case TBM_FORMAT_BGRA8888:
1683 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1684 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1689 case TBM_FORMAT_YUYV:
1690 case TBM_FORMAT_YVYU:
1691 case TBM_FORMAT_UYVY:
1692 case TBM_FORMAT_VYUY:
1693 case TBM_FORMAT_AYUV:
1696 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1697 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1703 * index 0 = Y plane, [7:0] Y
1704 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1706 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1708 case TBM_FORMAT_NV12:
1709 case TBM_FORMAT_NV21:
1711 if (plane_idx == 0) {
1713 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1714 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1716 } else if ( plane_idx == 1 ) {
1717 _offset = width * height;
1718 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1719 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1724 case TBM_FORMAT_NV16:
1725 case TBM_FORMAT_NV61:
1727 //if(plane_idx == 0)
1730 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1731 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1736 //else if( plane_idx ==1 )
1739 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1740 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1747 * index 0: Y plane, [7:0] Y
1748 * index 1: Cb plane, [7:0] Cb
1749 * index 2: Cr plane, [7:0] Cr
1751 * index 1: Cr plane, [7:0] Cr
1752 * index 2: Cb plane, [7:0] Cb
1755 NATIVE_BUFFER_FORMAT_YV12
1756 NATIVE_BUFFER_FORMAT_I420
1758 case TBM_FORMAT_YUV410:
1759 case TBM_FORMAT_YVU410:
1762 case TBM_FORMAT_YUV411:
1763 case TBM_FORMAT_YVU411:
1764 case TBM_FORMAT_YUV420:
1765 case TBM_FORMAT_YVU420:
1767 //if(plane_idx == 0)
1770 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1771 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1776 //else if( plane_idx == 1 )
1779 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1780 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1785 //else if (plane_idx == 2 )
1788 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1789 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1793 case TBM_FORMAT_YUV422:
1794 case TBM_FORMAT_YVU422:
1796 //if(plane_idx == 0)
1799 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1800 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1805 //else if( plane_idx == 1 )
1808 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1809 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1814 //else if (plane_idx == 2 )
1817 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1818 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1822 case TBM_FORMAT_YUV444:
1823 case TBM_FORMAT_YVU444:
1825 //if(plane_idx == 0)
1828 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1829 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1834 //else if( plane_idx == 1 )
1837 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1838 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1843 //else if (plane_idx == 2 )
1846 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1847 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1865 tbm_sprd_bo_get_flags (tbm_bo bo)
1867 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1869 tbm_bo_sprd bo_sprd;
1871 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1872 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1874 return bo_sprd->flags_tbm;
1878 tbm_sprd_bufmgr_bind_native_display (tbm_bufmgr bufmgr, void *NativeDisplay)
1880 tbm_bufmgr_sprd bufmgr_sprd;
1882 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1883 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1885 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1886 bufmgr_sprd->device_name, 0)) {
1887 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1891 bufmgr_sprd->bind_display = NativeDisplay;
1896 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1898 static TBMModuleVersionInfo SprdVersRec = {
1904 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1907 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1909 tbm_bufmgr_sprd bufmgr_sprd;
1910 tbm_bufmgr_backend bufmgr_backend;
1915 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1917 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1921 if (tbm_backend_is_display_server()) {
1922 bufmgr_sprd->fd = -1;
1924 bufmgr_sprd->fd = tbm_drm_helper_get_master_fd();
1925 if (bufmgr_sprd->fd < 0)
1926 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1928 if (bufmgr_sprd->fd < 0) {
1929 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1934 tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
1936 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1938 if (!bufmgr_sprd->device_name)
1940 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1941 tbm_drm_helper_unset_tbm_master_fd();
1942 close(bufmgr_sprd->fd);
1948 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1949 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1956 bufmgr_sprd->hashBos = drmHashCreate ();
1958 //Check if the tbm manager supports dma fence or not.
1959 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1963 length = read(fp, buf, 1);
1965 if (length == 1 && buf[0] == '1')
1966 bufmgr_sprd->use_dma_fence = 1;
1971 if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
1972 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: init bufmgr cache state failed!\n", getpid());
1974 if (tbm_backend_is_display_server())
1975 tbm_drm_helper_unset_tbm_master_fd();
1977 close(bufmgr_sprd->fd);
1983 bufmgr_backend = tbm_backend_alloc();
1984 if (!bufmgr_backend) {
1985 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1987 _bufmgr_deinit_cache_state(bufmgr_sprd);
1989 if (tbm_backend_is_display_server())
1990 tbm_drm_helper_unset_tbm_master_fd();
1992 close(bufmgr_sprd->fd);
1998 bufmgr_backend->priv = (void *)bufmgr_sprd;
1999 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
2000 bufmgr_backend->bo_size = tbm_sprd_bo_size;
2001 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
2002 bufmgr_backend->bo_free = tbm_sprd_bo_free;
2003 bufmgr_backend->bo_import = tbm_sprd_bo_import;
2004 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
2005 bufmgr_backend->bo_export = tbm_sprd_bo_export;
2006 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
2007 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
2008 bufmgr_backend->bo_map = tbm_sprd_bo_map;
2009 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
2010 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
2011 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
2012 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
2013 bufmgr_backend->bo_lock = tbm_sprd_bo_lock;
2014 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
2015 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
2017 if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
2018 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
2019 tbm_backend_free (bufmgr_backend);
2021 _bufmgr_deinit_cache_state(bufmgr_sprd);
2023 if (tbm_backend_is_display_server())
2024 tbm_drm_helper_unset_tbm_master_fd();
2026 close(bufmgr_sprd->fd);
2035 env = getenv ("TBM_SPRD_DEBUG");
2037 bDebug = atoi (env);
2038 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
2045 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
2046 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2048 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2049 __FUNCTION__, bufmgr_sprd->fd);