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);
330 _tgl_set_data(int fd, unsigned int key, unsigned int val)
333 struct tgl_user_data arg;
337 err = ioctl(fd, TGL_IOC_SET_DATA, &arg);
339 TBM_SPRD_LOG("[libtbm-sprd:%d] "
340 "error(%s) %s:%d key:%d\n",
341 getpid(), strerror(errno), __func__, __LINE__, key);
348 static inline unsigned int
349 _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
352 struct tgl_user_data arg = { 0, };
355 err = ioctl(fd, TGL_IOC_GET_DATA, &arg);
357 TBM_SPRD_LOG("[libtbm-sprd:%d] "
358 "error(%s) %s:%d key:%d\n",
359 getpid(), strerror(errno), __func__, __LINE__, key);
364 *locked = arg.locked;
375 fd = drmOpen(SPRD_DRM_NAME, NULL);
377 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
378 "warning %s:%d fail to open drm\n",
379 getpid(), __FUNCTION__, __LINE__);
384 struct udev *udev = NULL;
385 struct udev_enumerate *e = NULL;
386 struct udev_list_entry *entry = NULL;
387 struct udev_device *device = NULL, *drm_device = NULL, *device_parent = NULL;
388 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");
449 udev_device_unref(drm_device);
454 udev_device_unref(drm_device);
463 _sprd_bo_cache_flush (tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int flags)
466 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
467 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
469 /* cache flush is managed by kernel side when using dma-fence. */
470 if (bufmgr_sprd->use_dma_fence)
473 struct drm_sprd_gem_cache_op cache_op = {0, };
476 /* if bo_sprd is null, do cache_flush_all */
479 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
480 cache_op.size = bo_sprd->size;
482 flags = TBM_SPRD_CACHE_FLUSH_ALL;
484 cache_op.usr_addr = 0;
488 if (flags & TBM_SPRD_CACHE_INV) {
489 if (flags & TBM_SPRD_CACHE_ALL)
490 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
492 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
495 if (flags & TBM_SPRD_CACHE_CLN) {
496 if (flags & TBM_SPRD_CACHE_ALL)
497 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
499 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
502 if (flags & TBM_SPRD_CACHE_ALL)
503 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
505 ret = drmCommandWriteRead (bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
508 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
509 "error %s:%d fail to flush the cache.\n",
510 getpid(), __FUNCTION__, __LINE__);
519 _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 tbm_bo_cache_state cache_state;
527 if (bufmgr_sprd->use_dma_fence)
530 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
533 cache_state.data.isDirtied = DEVICE_NONE;
534 cache_state.data.isCached = 0;
535 cache_state.data.cntFlush = 0;
537 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
545 _bo_set_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int device, int opt)
548 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
549 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
552 unsigned short cntFlush = 0;
554 if (bufmgr_sprd->use_dma_fence)
557 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
560 /* get cache state of a bo */
561 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
563 /* get global cache flush count */
564 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
566 if (opt == TBM_DEVICE_CPU) {
567 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
568 bo_sprd->cache_state.data.isCached)
569 need_flush = TBM_SPRD_CACHE_INV;
571 bo_sprd->cache_state.data.isCached = 1;
572 if (opt & TBM_OPTION_WRITE)
573 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
575 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
576 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
579 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
580 bo_sprd->cache_state.data.isCached &&
581 bo_sprd->cache_state.data.cntFlush == cntFlush)
582 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
584 if (opt & TBM_OPTION_WRITE)
585 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
587 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
588 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
593 if (need_flush & TBM_SPRD_CACHE_ALL)
594 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
596 /* call cache flush */
597 _sprd_bo_cache_flush (bufmgr_sprd, bo_sprd, need_flush);
599 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
601 bo_sprd->cache_state.data.isCached,
602 bo_sprd->cache_state.data.isDirtied,
612 _bo_save_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
615 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
616 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
618 if (bufmgr_sprd->use_dma_fence)
621 unsigned short cntFlush = 0;
623 /* get global cache flush count */
624 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
626 /* save global cache flush count */
627 bo_sprd->cache_state.data.cntFlush = cntFlush;
628 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
635 _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);
649 _bufmgr_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
652 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
654 if (bufmgr_sprd->use_dma_fence)
657 /* open tgl fd for saving cache flush data */
658 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
660 if (bufmgr_sprd->tgl_fd < 0) {
661 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
662 if (bufmgr_sprd->tgl_fd < 0) {
663 TBM_SPRD_LOG("[libtbm-sprd:%d] "
664 "error: Fail to open global_lock:%s\n",
665 getpid(), tgl_devfile);
667 close(bufmgr_sprd->tgl_fd);
672 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
673 TBM_SPRD_LOG("[libtbm-sprd:%d] "
674 "error: Fail to initialize the tgl\n",
677 close(bufmgr_sprd->tgl_fd);
686 _bufmgr_deinit_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
689 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
691 if (bufmgr_sprd->use_dma_fence)
694 if (bufmgr_sprd->tgl_fd >= 0)
695 close(bufmgr_sprd->tgl_fd);
699 #ifndef USE_CONTIG_ONLY
701 _get_sprd_flag_from_tbm (unsigned int ftbm)
703 unsigned int flags = 0;
706 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
707 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
708 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
709 * To be updated appropriately once DRM-GEM supports different heap id masks.
712 if (ftbm & TBM_BO_SCANOUT) {
713 flags = SPRD_BO_CONTIG;
715 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
718 if (ftbm & TBM_BO_WC)
720 else if (ftbm & TBM_BO_NONCACHABLE)
721 flags |= SPRD_BO_NONCACHABLE;
727 _get_tbm_flag_from_sprd (unsigned int fsprd)
729 unsigned int flags = 0;
731 if (fsprd & SPRD_BO_NONCONTIG)
732 flags |= TBM_BO_DEFAULT;
734 flags |= TBM_BO_SCANOUT;
736 if (fsprd & SPRD_BO_WC)
738 else if (fsprd & SPRD_BO_CACHABLE)
739 flags |= TBM_BO_DEFAULT;
741 flags |= TBM_BO_NONCACHABLE;
748 _get_name (int fd, unsigned int gem)
750 struct drm_gem_flink arg = {0,};
753 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
754 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
755 "error %s:%d fail to get flink gem=%d\n",
756 getpid(), __FUNCTION__, __LINE__, gem);
760 return (unsigned int)arg.name;
764 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
766 tbm_bo_handle bo_handle;
767 memset (&bo_handle, 0x0, sizeof (uint64_t));
770 case TBM_DEVICE_DEFAULT:
772 bo_handle.u32 = (uint32_t)bo_sprd->gem;
775 if (!bo_sprd->pBase) {
776 struct drm_sprd_gem_mmap arg = {0,};
778 arg.handle = bo_sprd->gem;
779 arg.size = bo_sprd->size;
780 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
781 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
782 "error %s:%d Cannot usrptr gem=%d\n",
783 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
784 return (tbm_bo_handle) NULL;
786 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
789 bo_handle.ptr = (void *)bo_sprd->pBase;
793 if (!bo_sprd->dmabuf) {
794 struct drm_prime_handle arg = {0, };
795 arg.handle = bo_sprd->gem;
796 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
797 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
798 "error %s:%d Cannot dmabuf=%d\n",
799 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
800 return (tbm_bo_handle) NULL;
802 bo_sprd->dmabuf = arg.fd;
805 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
812 //TODO : Add ioctl for GSP MAP once available.
813 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
818 if (!bo_sprd->dmabuf) {
819 struct drm_prime_handle arg = {0, };
821 arg.handle = bo_sprd->gem;
822 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
823 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
824 "error %s:%d Cannot dmabuf=%d\n",
825 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
826 return (tbm_bo_handle) NULL;
828 bo_sprd->dmabuf = arg.fd;
831 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
835 bo_handle.ptr = (void *) NULL;
843 tbm_sprd_bo_size (tbm_bo bo)
845 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
849 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
851 return bo_sprd->size;
855 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
857 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
860 tbm_bufmgr_sprd bufmgr_sprd;
861 unsigned int sprd_flags;
863 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
864 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
866 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
868 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
869 "error %s:%d fail to allocate the bo private\n",
870 getpid(), __FUNCTION__, __LINE__);
874 #ifdef USE_CONTIG_ONLY
875 flags = TBM_BO_SCANOUT;
876 sprd_flags = SPRD_BO_CONTIG;
878 sprd_flags = _get_sprd_flag_from_tbm (flags);
879 if ((flags & TBM_BO_SCANOUT) &&
881 sprd_flags |= SPRD_BO_NONCONTIG;
883 #endif // USE_CONTIG_ONLY
884 struct drm_sprd_gem_create arg = {0, };
885 arg.size = (uint64_t)size;
886 arg.flags = sprd_flags;
887 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
889 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
890 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
891 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
896 bo_sprd->fd = bufmgr_sprd->fd;
897 bo_sprd->gem = arg.handle;
898 bo_sprd->size = size;
899 bo_sprd->flags_tbm = flags;
900 bo_sprd->flags_sprd = sprd_flags;
901 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
903 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 0)) {
904 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
909 pthread_mutex_init(&bo_sprd->mutex, NULL);
911 if (bufmgr_sprd->use_dma_fence
912 && !bo_sprd->dmabuf) {
913 struct drm_prime_handle arg = {0, };
915 arg.handle = bo_sprd->gem;
916 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
917 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
918 "error %s:%d Cannot dmabuf=%d\n",
919 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
923 bo_sprd->dmabuf = arg.fd;
927 PrivGem *privGem = calloc (1, sizeof(PrivGem));
928 privGem->ref_count = 1;
929 privGem->bo_priv = bo_sprd;
930 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
931 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
932 "error %s:%d Cannot insert bo to Hash(%d)\n",
933 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
936 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
937 __FUNCTION__, bo_sprd->size,
938 bo_sprd->gem, bo_sprd->name,
941 return (void *)bo_sprd;
945 tbm_sprd_bo_free(tbm_bo bo)
948 tbm_bufmgr_sprd bufmgr_sprd;
953 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
954 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
956 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
957 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
959 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
960 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
962 if (bo_sprd->pBase) {
963 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
964 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
966 getpid(), __FUNCTION__, __LINE__);
971 if (bo_sprd->dmabuf) {
972 close (bo_sprd->dmabuf);
976 /* delete bo from hash */
977 PrivGem *privGem = NULL;
980 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
982 privGem->ref_count--;
983 if (privGem->ref_count == 0) {
984 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
989 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
990 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
991 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
994 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
996 /* Free gem handle */
997 struct drm_gem_close arg = {0, };
998 memset (&arg, 0, sizeof(arg));
999 arg.handle = bo_sprd->gem;
1000 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
1001 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1003 getpid(), __FUNCTION__, __LINE__);
1011 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
1013 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1015 tbm_bufmgr_sprd bufmgr_sprd;
1016 tbm_bo_sprd bo_sprd;
1017 PrivGem *privGem = NULL;
1020 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1021 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1023 ret = drmHashLookup (bufmgr_sprd->hashBos, key, (void **)&privGem);
1025 return privGem->bo_priv;
1028 struct drm_gem_open arg = {0, };
1029 struct drm_sprd_gem_info info = {0, };
1032 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
1033 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1034 "error %s:%d Cannot open gem name=%d\n",
1035 getpid(), __FUNCTION__, __LINE__, key);
1039 info.handle = arg.handle;
1040 if (drmCommandWriteRead(bufmgr_sprd->fd,
1043 sizeof(struct drm_sprd_gem_info))) {
1044 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1045 "error %s:%d Cannot get gem info=%d\n",
1046 getpid(), __FUNCTION__, __LINE__, key);
1050 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1052 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1053 "error %s:%d fail to allocate the bo private\n",
1054 getpid(), __FUNCTION__, __LINE__);
1058 bo_sprd->fd = bufmgr_sprd->fd;
1059 bo_sprd->gem = arg.handle;
1060 bo_sprd->size = arg.size;
1061 bo_sprd->flags_sprd = info.flags;
1062 bo_sprd->name = key;
1063 #ifdef USE_CONTIG_ONLY
1064 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1065 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1067 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1070 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1071 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
1076 if (!bo_sprd->dmabuf) {
1077 struct drm_prime_handle arg = {0, };
1079 arg.handle = bo_sprd->gem;
1080 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1081 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1082 "error %s:%d Cannot dmabuf=%d\n",
1083 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1087 bo_sprd->dmabuf = arg.fd;
1090 /* add bo to hash */
1091 privGem = calloc (1, sizeof(PrivGem));
1092 privGem->ref_count = 1;
1093 privGem->bo_priv = bo_sprd;
1094 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1095 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1096 "error %s:%d Cannot insert bo to Hash(%d)\n",
1097 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1100 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1101 __FUNCTION__, bo_sprd->size,
1102 bo_sprd->gem, bo_sprd->name,
1103 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1105 return (void *)bo_sprd;
1109 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
1111 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1113 tbm_bufmgr_sprd bufmgr_sprd;
1114 tbm_bo_sprd bo_sprd;
1115 PrivGem *privGem = NULL;
1119 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1120 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1122 //getting handle from fd
1123 unsigned int gem = 0;
1124 struct drm_prime_handle arg = {0, };
1128 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1129 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1130 bo, arg.fd, strerror(errno));
1135 name = _get_name (bufmgr_sprd->fd, gem);
1137 ret = drmHashLookup (bufmgr_sprd->hashBos, name, (void **)&privGem);
1139 if (gem == privGem->bo_priv->gem) {
1140 return privGem->bo_priv;
1144 unsigned int real_size = -1;
1145 struct drm_sprd_gem_info info = {0, };
1147 /* Determine size of bo. The fd-to-handle ioctl really should
1148 * return the size, but it doesn't. If we have kernel 3.12 or
1149 * later, we can lseek on the prime fd to get the size. Older
1150 * kernels will just fail, in which case we fall back to the
1151 * provided (estimated or guess size). */
1152 real_size = lseek(key, 0, SEEK_END);
1155 if (drmCommandWriteRead(bufmgr_sprd->fd,
1158 sizeof(struct drm_sprd_gem_info))) {
1159 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1160 bo, gem, key, strerror(errno));
1164 if (real_size == -1)
1165 real_size = info.size;
1167 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1169 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
1173 bo_sprd->fd = bufmgr_sprd->fd;
1175 bo_sprd->size = real_size;
1176 bo_sprd->flags_sprd = info.flags;
1177 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1179 bo_sprd->name = name;
1180 if (!bo_sprd->name) {
1181 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1182 bo, gem, key, strerror(errno));
1187 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1188 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
1193 /* add bo to hash */
1196 privGem = calloc (1, sizeof(PrivGem));
1198 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1199 "error %s:%d Fail to calloc privGem\n",
1200 getpid(), __FUNCTION__, __LINE__);
1205 privGem->ref_count = 1;
1206 privGem->bo_priv = bo_sprd;
1207 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1208 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1209 bo, bo_sprd->name, gem, key);
1212 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1215 bo_sprd->gem, bo_sprd->name,
1218 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1221 return (void *)bo_sprd;
1225 tbm_sprd_bo_export (tbm_bo bo)
1227 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1229 tbm_bo_sprd bo_sprd;
1231 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1232 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1234 if (!bo_sprd->name) {
1235 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1236 if (!bo_sprd->name) {
1237 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1238 "error %s:%d Cannot get name\n",
1239 getpid(), __FUNCTION__, __LINE__);
1244 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1245 __FUNCTION__, bo_sprd->size,
1246 bo_sprd->gem, bo_sprd->name,
1247 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1249 return (unsigned int)bo_sprd->name;
1253 tbm_sprd_bo_export_fd (tbm_bo bo)
1255 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, -1);
1257 tbm_bo_sprd bo_sprd;
1260 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1261 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, -1);
1263 struct drm_prime_handle arg = {0, };
1265 arg.handle = bo_sprd->gem;
1266 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1268 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
1269 bo, bo_sprd->gem, strerror(errno));
1270 return (tbm_fd) ret;
1273 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1276 bo_sprd->gem, bo_sprd->name,
1279 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1282 return (tbm_fd)arg.fd;
1286 static tbm_bo_handle
1287 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
1289 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1291 tbm_bo_handle bo_handle;
1292 tbm_bo_sprd bo_sprd;
1294 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1295 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1297 if (!bo_sprd->gem) {
1298 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1299 "error %s:%d Cannot map gem=%d\n",
1300 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1301 return (tbm_bo_handle) NULL;
1304 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1305 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1307 /*Get mapped bo_handle*/
1308 bo_handle = _sprd_bo_handle (bo_sprd, device);
1309 if (bo_handle.ptr == NULL) {
1310 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1311 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1312 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1313 return (tbm_bo_handle) NULL;
1319 static tbm_bo_handle
1320 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
1322 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1324 tbm_bo_handle bo_handle;
1325 tbm_bo_sprd bo_sprd;
1326 tbm_bufmgr_sprd bufmgr_sprd;
1328 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1329 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, (tbm_bo_handle) NULL);
1331 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1332 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1334 if (!bo_sprd->gem) {
1335 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1336 "error %s:%d Cannot map gem=%d\n",
1337 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1338 return (tbm_bo_handle) NULL;
1341 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1342 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1344 /*Get mapped bo_handle*/
1345 bo_handle = _sprd_bo_handle (bo_sprd, device);
1346 if (bo_handle.ptr == NULL) {
1347 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1348 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1349 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1350 return (tbm_bo_handle) NULL;
1353 if (bo_sprd->map_cnt == 0)
1354 _bo_set_cache_state (bufmgr_sprd, bo_sprd, device, opt);
1362 tbm_sprd_bo_unmap (tbm_bo bo)
1364 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1366 tbm_bo_sprd bo_sprd;
1367 tbm_bufmgr_sprd bufmgr_sprd;
1369 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1370 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1372 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1373 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1380 if (bo_sprd->map_cnt == 0)
1381 _bo_save_cache_state (bufmgr_sprd, bo_sprd);
1383 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1384 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1390 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1392 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1394 #if USE_BACKEND_LOCK
1395 tbm_bufmgr_sprd bufmgr_sprd;
1396 tbm_bo_sprd bo_sprd;
1399 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1400 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1402 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1403 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1405 if (bufmgr_sprd->use_dma_fence) {
1406 struct dma_buf_fence fence;
1408 memset(&fence, 0, sizeof(struct dma_buf_fence));
1410 /* Check if the given type is valid or not. */
1411 if (opt & TBM_OPTION_WRITE) {
1412 if (device == TBM_DEVICE_CPU)
1413 fence.type = DMA_BUF_ACCESS_WRITE;
1414 else if (device == TBM_DEVICE_3D)
1415 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1417 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1418 getpid(), __FUNCTION__);
1421 } else if (opt & TBM_OPTION_READ) {
1422 if (device == TBM_DEVICE_CPU)
1423 fence.type = DMA_BUF_ACCESS_READ;
1424 else if (device == TBM_DEVICE_3D)
1425 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1427 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1428 getpid(), __FUNCTION__);
1432 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1433 __FUNCTION__, __LINE__);
1437 /* Check if the tbm manager supports dma fence or not. */
1438 if (!bufmgr_sprd->use_dma_fence) {
1439 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1440 "error %s:%d Not support DMA FENCE(%s)\n",
1441 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1446 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1448 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1449 "error %s:%d Can not set GET FENCE(%s)\n",
1450 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1454 pthread_mutex_lock(&bo_sprd->mutex);
1456 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1457 if (bo_sprd->dma_fence[i].ctx == 0) {
1458 bo_sprd->dma_fence[i].type = fence.type;
1459 bo_sprd->dma_fence[i].ctx = fence.ctx;
1463 if (i == DMA_FENCE_LIST_MAX) {
1464 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1465 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1466 "error %s:%d fence list is full\n",
1467 getpid(), __FUNCTION__, __LINE__);
1469 pthread_mutex_unlock(&bo_sprd->mutex);
1471 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1473 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1475 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1477 DBG ("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1478 getpid(), __FUNCTION__, bo_sprd->name);
1488 tbm_sprd_bo_unlock(tbm_bo bo)
1490 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1492 #if USE_BACKEND_LOCK
1493 tbm_bufmgr_sprd bufmgr_sprd;
1494 tbm_bo_sprd bo_sprd;
1497 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1498 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1500 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1501 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1503 if (bufmgr_sprd->use_dma_fence) {
1504 struct dma_buf_fence fence;
1506 if (!bo_sprd->dma_fence[0].ctx) {
1507 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1512 if (!bo_sprd->dma_fence[0].type) {
1513 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1518 pthread_mutex_lock(&bo_sprd->mutex);
1519 fence.type = bo_sprd->dma_fence[0].type;
1520 fence.ctx = bo_sprd->dma_fence[0].ctx;
1522 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1523 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1524 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1526 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1527 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1528 pthread_mutex_unlock(&bo_sprd->mutex);
1530 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1532 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1533 "error %s:%d Can not set PUT FENCE(%s)\n",
1534 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1538 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1540 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1542 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1544 DBG ("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1545 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()) {
1924 bufmgr_sprd->fd = -1;
1925 master_fd = tbm_drm_helper_get_master_fd();
1927 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1929 bufmgr_sprd->fd = master_fd;
1931 if (bufmgr_sprd->fd < 0) {
1932 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1937 tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
1939 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1941 if (!bufmgr_sprd->device_name)
1943 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1944 close(bufmgr_sprd->fd);
1950 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1951 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1958 bufmgr_sprd->hashBos = drmHashCreate ();
1960 //Check if the tbm manager supports dma fence or not.
1961 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1965 length = read(fp, buf, 1);
1967 if (length == 1 && buf[0] == '1')
1968 bufmgr_sprd->use_dma_fence = 1;
1973 if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
1974 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: init bufmgr cache state failed!\n", getpid());
1976 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 tbm_drm_helper_unset_tbm_master_fd();
1990 close(bufmgr_sprd->fd);
1996 bufmgr_backend->priv = (void *)bufmgr_sprd;
1997 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1998 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1999 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
2000 bufmgr_backend->bo_free = tbm_sprd_bo_free;
2001 bufmgr_backend->bo_import = tbm_sprd_bo_import;
2002 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
2003 bufmgr_backend->bo_export = tbm_sprd_bo_export;
2004 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
2005 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
2006 bufmgr_backend->bo_map = tbm_sprd_bo_map;
2007 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
2008 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
2009 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
2010 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
2011 bufmgr_backend->bo_lock = tbm_sprd_bo_lock;
2012 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
2013 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
2015 if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
2016 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
2017 tbm_backend_free (bufmgr_backend);
2019 _bufmgr_deinit_cache_state(bufmgr_sprd);
2021 tbm_drm_helper_unset_tbm_master_fd();
2022 close(bufmgr_sprd->fd);
2031 env = getenv ("TBM_SPRD_DEBUG");
2033 bDebug = atoi (env);
2034 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
2041 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
2042 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2044 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2045 __FUNCTION__, bufmgr_sprd->fd);