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 **************************************************************************/
39 #include <sys/ioctl.h>
40 #include <sys/types.h>
47 #include <tbm_bufmgr.h>
48 #include <tbm_bufmgr_backend.h>
49 #include <drm/sprd_drm.h>
51 #include <tbm_surface.h>
52 #include <tbm_drm_helper.h>
55 #include "tbm_bufmgr_tgl.h"
57 //#define USE_CONTIG_ONLY
60 #define TBM_COLOR_FORMAT_COUNT 8
63 #define LOG_TAG "TBM_BACKEND"
65 static int bDebug = 0;
72 static int initialized = 0;
73 static char app_name[128];
78 /* get the application name */
79 f = fopen("/proc/self/cmdline", "r");
85 memset(app_name, 0x00, sizeof(app_name));
87 if ( fgets(app_name, 100, f) == NULL ) {
94 if ( (slash = strrchr(app_name, '/')) != NULL ) {
95 memmove(app_name, slash + 1, strlen(slash));
102 #define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args)
103 #define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args)
105 #define TBM_SPRD_LOG(...)
109 #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
111 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
112 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128)
113 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
116 /* check condition */
117 #define SPRD_RETURN_IF_FAIL(cond) {\
119 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
123 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
125 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
130 struct dma_buf_info {
132 unsigned int fence_supported;
133 unsigned int padding;
136 #define DMA_BUF_ACCESS_READ 0x1
137 #define DMA_BUF_ACCESS_WRITE 0x2
138 #define DMA_BUF_ACCESS_DMA 0x4
139 #define DMA_BUF_ACCESS_MAX 0x8
141 #define DMA_FENCE_LIST_MAX 5
143 struct dma_buf_fence {
148 #define DMABUF_IOCTL_BASE 'F'
149 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
151 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
152 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
153 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
156 #define GLOBAL_KEY ((unsigned int)(-1))
158 #define TBM_SPRD_CACHE_INV 0x01 /**< cache invalidate */
159 #define TBM_SPRD_CACHE_CLN 0x02 /**< cache clean */
160 #define TBM_SPRD_CACHE_ALL 0x10 /**< cache all */
161 #define TBM_SPRD_CACHE_FLUSH (TBM_SPRD_CACHE_INV|TBM_SPRD_CACHE_CLN) /**< cache flush */
162 #define TBM_SPRD_CACHE_FLUSH_ALL (TBM_SPRD_CACHE_FLUSH|TBM_SPRD_CACHE_ALL) /**< cache flush all */
166 DEVICE_CA, /* cache aware device */
167 DEVICE_CO /* cache oblivious device */
170 typedef union _tbm_bo_cache_state tbm_bo_cache_state;
172 union _tbm_bo_cache_state {
175 unsigned int cntFlush: 16; /*Flush all index for sync */
176 unsigned int isCached: 1;
177 unsigned int isDirtied: 2;
181 typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd;
182 typedef struct _tbm_bo_sprd *tbm_bo_sprd;
184 typedef struct _sprd_private {
186 struct _tbm_bo_sprd *bo_priv;
189 /* tbm buffor object for sprd */
190 struct _tbm_bo_sprd {
193 unsigned int name; /* FLINK ID */
195 unsigned int gem; /* GEM Handle */
197 unsigned int dmabuf; /* fd for dmabuf */
199 void *pBase; /* virtual address */
203 unsigned int flags_sprd;
204 unsigned int flags_tbm;
208 pthread_mutex_t mutex;
209 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
213 tbm_bo_cache_state cache_state;
214 unsigned int map_cnt;
217 /* tbm bufmgr private for sprd */
218 struct _tbm_bufmgr_sprd {
229 char *STR_DEVICE[] = {
245 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
256 _tgl_init(int fd, unsigned int key)
258 struct tgl_attribute attr;
262 attr.timeout_ms = 1000;
264 err = ioctl(fd, TGL_IOC_INIT_LOCK, &attr);
266 TBM_SPRD_LOG("[libtbm-sprd:%d] error(%s) %s:%d key:%d\n",
267 getpid(), strerror(errno), __func__, __LINE__, key);
275 _tgl_destroy(int fd, unsigned int key)
279 err = ioctl(fd, TGL_IOC_DESTROY_LOCK, key);
281 TBM_SPRD_LOG("[libtbm-sprd:%d] "
282 "error(%s) %s:%d key:%d\n",
283 getpid(), strerror(errno), __func__, __LINE__, key);
291 _tgl_lock(int fd, unsigned int key)
295 err = ioctl(fd, TGL_IOC_LOCK_LOCK, key);
297 TBM_SPRD_LOG("[libtbm-sprd:%d] "
298 "error(%s) %s:%d key:%d\n",
299 getpid(), strerror(errno), __func__, __LINE__, key);
307 _tgl_unlock(int fd, unsigned int key)
311 err = ioctl(fd, TGL_IOC_UNLOCK_LOCK, key);
313 TBM_SPRD_LOG("[libtbm-sprd:%d] "
314 "error(%s) %s:%d key:%d\n",
315 getpid(), strerror(errno), __func__, __LINE__, key);
323 _tgl_set_data(int fd, unsigned int key, unsigned int val)
326 struct tgl_user_data arg;
330 err = ioctl(fd, TGL_IOC_SET_DATA, &arg);
332 TBM_SPRD_LOG("[libtbm-sprd:%d] "
333 "error(%s) %s:%d key:%d\n",
334 getpid(), strerror(errno), __func__, __LINE__, key);
341 static inline unsigned int
342 _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
345 struct tgl_user_data arg = { 0, };
348 err = ioctl(fd, TGL_IOC_GET_DATA, &arg);
350 TBM_SPRD_LOG("[libtbm-sprd:%d] "
351 "error(%s) %s:%d key:%d\n",
352 getpid(), strerror(errno), __func__, __LINE__, key);
357 *locked = arg.locked;
363 _sprd_bo_cache_flush (tbm_bo bo, int flags)
365 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
366 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
368 /* cache flush is managed by kernel side when using dma-fence. */
369 if (bufmgr_sprd->use_dma_fence)
372 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
376 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
377 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
380 struct drm_sprd_gem_cache_op cache_op = {0, };
383 /* if bo_sprd is null, do cache_flush_all */
386 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
387 cache_op.size = bo_sprd->size;
389 flags = TBM_SPRD_CACHE_FLUSH_ALL;
391 cache_op.usr_addr = 0;
395 if (flags & TBM_SPRD_CACHE_INV) {
396 if (flags & TBM_SPRD_CACHE_ALL)
397 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
399 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
402 if (flags & TBM_SPRD_CACHE_CLN) {
403 if (flags & TBM_SPRD_CACHE_ALL)
404 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
406 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
409 if (flags & TBM_SPRD_CACHE_ALL)
410 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
412 ret = drmCommandWriteRead (bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
415 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
416 "error %s:%d fail to flush the cache.\n",
417 getpid(), __FUNCTION__, __LINE__);
426 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
428 tbm_bo_cache_state cache_state;
430 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
431 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
433 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
435 cache_state.data.isDirtied = DEVICE_NONE;
436 cache_state.data.isCached = 0;
437 cache_state.data.cntFlush = 0;
439 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
445 _bo_set_cache_state(tbm_bo bo, int device, int opt)
448 tbm_bufmgr_sprd bufmgr_sprd;
450 unsigned short cntFlush = 0;
452 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
453 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
455 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
456 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
458 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
461 /* get cache state of a bo */
462 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
464 /* get global cache flush count */
465 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
467 if (opt == TBM_DEVICE_CPU) {
468 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
469 bo_sprd->cache_state.data.isCached)
470 need_flush = TBM_SPRD_CACHE_INV;
472 bo_sprd->cache_state.data.isCached = 1;
473 if (opt & TBM_OPTION_WRITE)
474 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
476 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
477 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
480 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
481 bo_sprd->cache_state.data.isCached &&
482 bo_sprd->cache_state.data.cntFlush == cntFlush)
483 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
485 if (opt & TBM_OPTION_WRITE)
486 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
488 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
489 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
494 if (need_flush & TBM_SPRD_CACHE_ALL)
495 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
497 /* call cache flush */
498 _sprd_bo_cache_flush (bo, need_flush);
500 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
502 bo_sprd->cache_state.data.isCached,
503 bo_sprd->cache_state.data.isDirtied,
512 _bo_save_cache_state(tbm_bo bo)
514 unsigned short cntFlush = 0;
516 tbm_bufmgr_sprd bufmgr_sprd;
518 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
519 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
521 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
522 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
524 /* get global cache flush count */
525 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
527 /* save global cache flush count */
528 bo_sprd->cache_state.data.cntFlush = cntFlush;
529 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
535 _bo_destroy_cache_state(tbm_bo bo)
538 tbm_bufmgr_sprd bufmgr_sprd;
540 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
541 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
543 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
544 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
546 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
550 _is_drm_master(int drm_fd)
554 return drmGetMagic(drm_fd, &magic) == 0 &&
555 drmAuthMagic(drm_fd, magic) == 0;
559 #ifndef USE_CONTIG_ONLY
561 _get_sprd_flag_from_tbm (unsigned int ftbm)
563 unsigned int flags = 0;
566 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
567 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
568 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
569 * To be updated appropriately once DRM-GEM supports different heap id masks.
572 if (ftbm & TBM_BO_SCANOUT) {
573 flags = SPRD_BO_CONTIG;
575 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
578 if (ftbm & TBM_BO_WC)
580 else if (ftbm & TBM_BO_NONCACHABLE)
581 flags |= SPRD_BO_NONCACHABLE;
587 _get_tbm_flag_from_sprd (unsigned int fsprd)
589 unsigned int flags = 0;
591 if (fsprd & SPRD_BO_NONCONTIG)
592 flags |= TBM_BO_DEFAULT;
594 flags |= TBM_BO_SCANOUT;
596 if (fsprd & SPRD_BO_WC)
598 else if (fsprd & SPRD_BO_CACHABLE)
599 flags |= TBM_BO_DEFAULT;
601 flags |= TBM_BO_NONCACHABLE;
608 _get_name (int fd, unsigned int gem)
610 struct drm_gem_flink arg = {0,};
613 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
614 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
615 "error %s:%d fail to get flink gem=%d\n",
616 getpid(), __FUNCTION__, __LINE__, gem);
620 return (unsigned int)arg.name;
624 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
626 tbm_bo_handle bo_handle;
627 memset (&bo_handle, 0x0, sizeof (uint64_t));
630 case TBM_DEVICE_DEFAULT:
632 bo_handle.u32 = (uint32_t)bo_sprd->gem;
635 if (!bo_sprd->pBase) {
636 struct drm_sprd_gem_mmap arg = {0,};
638 arg.handle = bo_sprd->gem;
639 arg.size = bo_sprd->size;
640 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
641 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
642 "error %s:%d Cannot usrptr gem=%d\n",
643 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
644 return (tbm_bo_handle) NULL;
646 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
649 bo_handle.ptr = (void *)bo_sprd->pBase;
653 if (!bo_sprd->dmabuf) {
654 struct drm_prime_handle arg = {0, };
655 arg.handle = bo_sprd->gem;
656 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
657 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
658 "error %s:%d Cannot dmabuf=%d\n",
659 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
660 return (tbm_bo_handle) NULL;
662 bo_sprd->dmabuf = arg.fd;
665 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
672 //TODO : Add ioctl for GSP MAP once available.
673 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
678 if (!bo_sprd->dmabuf) {
679 struct drm_prime_handle arg = {0, };
681 arg.handle = bo_sprd->gem;
682 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
683 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
684 "error %s:%d Cannot dmabuf=%d\n",
685 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
686 return (tbm_bo_handle) NULL;
688 bo_sprd->dmabuf = arg.fd;
691 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
695 bo_handle.ptr = (void *) NULL;
703 tbm_sprd_bo_size (tbm_bo bo)
705 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
709 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
711 return bo_sprd->size;
715 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
717 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
720 tbm_bufmgr_sprd bufmgr_sprd;
721 unsigned int sprd_flags;
723 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
724 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
726 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
728 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
729 "error %s:%d fail to allocate the bo private\n",
730 getpid(), __FUNCTION__, __LINE__);
734 #ifdef USE_CONTIG_ONLY
735 flags = TBM_BO_SCANOUT;
736 sprd_flags = SPRD_BO_CONTIG;
738 sprd_flags = _get_sprd_flag_from_tbm (flags);
739 if ((flags & TBM_BO_SCANOUT) &&
741 sprd_flags |= SPRD_BO_NONCONTIG;
743 #endif // USE_CONTIG_ONLY
744 struct drm_sprd_gem_create arg = {0, };
746 arg.flags = sprd_flags;
747 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
749 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
750 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
751 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
756 bo_sprd->fd = bufmgr_sprd->fd;
757 bo_sprd->gem = arg.handle;
758 bo_sprd->size = size;
759 bo_sprd->flags_tbm = flags;
760 bo_sprd->flags_sprd = sprd_flags;
761 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
763 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd)) {
764 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
769 pthread_mutex_init(&bo_sprd->mutex, NULL);
771 if (bufmgr_sprd->use_dma_fence
772 && !bo_sprd->dmabuf) {
773 struct drm_prime_handle arg = {0, };
775 arg.handle = bo_sprd->gem;
776 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
777 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
778 "error %s:%d Cannot dmabuf=%d\n",
779 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
783 bo_sprd->dmabuf = arg.fd;
787 PrivGem *privGem = calloc (1, sizeof(PrivGem));
788 privGem->ref_count = 1;
789 privGem->bo_priv = bo_sprd;
790 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
791 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
792 "error %s:%d Cannot insert bo to Hash(%d)\n",
793 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
796 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
797 __FUNCTION__, bo_sprd->size,
798 bo_sprd->gem, bo_sprd->name,
801 return (void *)bo_sprd;
805 tbm_sprd_bo_free(tbm_bo bo)
808 tbm_bufmgr_sprd bufmgr_sprd;
813 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
814 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
816 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
817 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
819 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
820 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
822 if (bo_sprd->pBase) {
823 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
824 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
826 getpid(), __FUNCTION__, __LINE__);
831 if (bo_sprd->dmabuf) {
832 close (bo_sprd->dmabuf);
836 /* delete bo from hash */
837 PrivGem *privGem = NULL;
840 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
842 privGem->ref_count--;
843 if (privGem->ref_count == 0) {
844 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
849 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
850 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
851 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
854 _bo_destroy_cache_state(bo);
856 /* Free gem handle */
857 struct drm_gem_close arg = {0, };
858 memset (&arg, 0, sizeof(arg));
859 arg.handle = bo_sprd->gem;
860 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
861 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
863 getpid(), __FUNCTION__, __LINE__);
871 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
873 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
875 tbm_bufmgr_sprd bufmgr_sprd;
877 PrivGem *privGem = NULL;
880 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
881 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
883 ret = drmHashLookup (bufmgr_sprd->hashBos, key, (void **)&privGem);
885 privGem->ref_count++;
886 return privGem->bo_priv;
889 struct drm_gem_open arg = {0, };
890 struct drm_sprd_gem_info info = {0, };
893 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
894 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
895 "error %s:%d Cannot open gem name=%d\n",
896 getpid(), __FUNCTION__, __LINE__, key);
900 info.handle = arg.handle;
901 if (drmCommandWriteRead(bufmgr_sprd->fd,
904 sizeof(struct drm_sprd_gem_info))) {
905 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
906 "error %s:%d Cannot get gem info=%d\n",
907 getpid(), __FUNCTION__, __LINE__, key);
911 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
913 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
914 "error %s:%d fail to allocate the bo private\n",
915 getpid(), __FUNCTION__, __LINE__);
919 bo_sprd->fd = bufmgr_sprd->fd;
920 bo_sprd->gem = arg.handle;
921 bo_sprd->size = arg.size;
922 bo_sprd->flags_sprd = info.flags;
924 #ifdef USE_CONTIG_ONLY
925 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
926 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
928 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
931 if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
932 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
937 if (!bo_sprd->dmabuf) {
938 struct drm_prime_handle arg = {0, };
940 arg.handle = bo_sprd->gem;
941 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
942 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
943 "error %s:%d Cannot dmabuf=%d\n",
944 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
948 bo_sprd->dmabuf = arg.fd;
952 privGem = calloc (1, sizeof(PrivGem));
953 privGem->ref_count = 1;
954 privGem->bo_priv = bo_sprd;
955 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
956 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
957 "error %s:%d Cannot insert bo to Hash(%d)\n",
958 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
961 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
962 __FUNCTION__, bo_sprd->size,
963 bo_sprd->gem, bo_sprd->name,
964 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
966 return (void *)bo_sprd;
970 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
972 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
974 tbm_bufmgr_sprd bufmgr_sprd;
976 PrivGem *privGem = NULL;
980 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
981 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
983 //getting handle from fd
984 unsigned int gem = 0;
985 struct drm_prime_handle arg = {0, };
989 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
990 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
991 bo, arg.fd, strerror(errno));
996 name = _get_name (bufmgr_sprd->fd, gem);
998 ret = drmHashLookup (bufmgr_sprd->hashBos, name, (void **)&privGem);
1000 if (gem == privGem->bo_priv->gem) {
1001 privGem->ref_count++;
1002 return privGem->bo_priv;
1006 unsigned int real_size = -1;
1007 struct drm_sprd_gem_info info = {0, };
1009 /* Determine size of bo. The fd-to-handle ioctl really should
1010 * return the size, but it doesn't. If we have kernel 3.12 or
1011 * later, we can lseek on the prime fd to get the size. Older
1012 * kernels will just fail, in which case we fall back to the
1013 * provided (estimated or guess size). */
1014 real_size = lseek(key, 0, SEEK_END);
1017 if (drmCommandWriteRead(bufmgr_sprd->fd,
1020 sizeof(struct drm_sprd_gem_info))) {
1021 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1022 bo, gem, key, strerror(errno));
1026 if (real_size == -1)
1027 real_size = info.size;
1029 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1031 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
1035 bo_sprd->fd = bufmgr_sprd->fd;
1037 bo_sprd->size = real_size;
1038 bo_sprd->flags_sprd = info.flags;
1039 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1041 bo_sprd->name = name;
1042 if (!bo_sprd->name) {
1043 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1044 bo, gem, key, strerror(errno));
1049 if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
1050 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
1055 /* add bo to hash */
1058 privGem = calloc (1, sizeof(PrivGem));
1060 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1061 "error %s:%d Fail to calloc privGem\n",
1062 getpid(), __FUNCTION__, __LINE__);
1067 privGem->ref_count = 1;
1068 privGem->bo_priv = bo_sprd;
1069 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1070 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1071 bo, bo_sprd->name, gem, key);
1074 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1077 bo_sprd->gem, bo_sprd->name,
1080 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1083 return (void *)bo_sprd;
1087 tbm_sprd_bo_export (tbm_bo bo)
1089 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1091 tbm_bo_sprd bo_sprd;
1093 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1094 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1096 if (!bo_sprd->name) {
1097 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1098 if (!bo_sprd->name) {
1099 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1100 "error %s:%d Cannot get name\n",
1101 getpid(), __FUNCTION__, __LINE__);
1106 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1107 __FUNCTION__, bo_sprd->size,
1108 bo_sprd->gem, bo_sprd->name,
1109 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1111 return (unsigned int)bo_sprd->name;
1115 tbm_sprd_bo_export_fd (tbm_bo bo)
1117 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, -1);
1119 tbm_bo_sprd bo_sprd;
1122 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1123 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, -1);
1125 struct drm_prime_handle arg = {0, };
1127 arg.handle = bo_sprd->gem;
1128 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1130 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
1131 bo, bo_sprd->gem, strerror(errno));
1132 return (tbm_fd) ret;
1135 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1138 bo_sprd->gem, bo_sprd->name,
1141 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1144 return (tbm_fd)arg.fd;
1148 static tbm_bo_handle
1149 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
1151 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1153 tbm_bo_handle bo_handle;
1154 tbm_bo_sprd bo_sprd;
1156 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1157 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1159 if (!bo_sprd->gem) {
1160 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1161 "error %s:%d Cannot map gem=%d\n",
1162 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1163 return (tbm_bo_handle) NULL;
1166 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1167 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1169 /*Get mapped bo_handle*/
1170 bo_handle = _sprd_bo_handle (bo_sprd, device);
1171 if (bo_handle.ptr == NULL) {
1172 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1173 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1174 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1175 return (tbm_bo_handle) NULL;
1181 static tbm_bo_handle
1182 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
1184 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1186 tbm_bo_handle bo_handle;
1187 tbm_bo_sprd bo_sprd;
1189 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1190 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1192 if (!bo_sprd->gem) {
1193 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1194 "error %s:%d Cannot map gem=%d\n",
1195 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1196 return (tbm_bo_handle) NULL;
1199 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1200 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1202 /*Get mapped bo_handle*/
1203 bo_handle = _sprd_bo_handle (bo_sprd, device);
1204 if (bo_handle.ptr == NULL) {
1205 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1206 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1207 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1208 return (tbm_bo_handle) NULL;
1211 if (bo_sprd->map_cnt == 0)
1212 _bo_set_cache_state (bo, device, opt);
1220 tbm_sprd_bo_unmap (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);
1234 if (bo_sprd->map_cnt == 0)
1235 _bo_save_cache_state (bo);
1237 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1238 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1244 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1246 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1248 #if USE_BACKEND_LOCK
1249 tbm_bufmgr_sprd bufmgr_sprd;
1250 tbm_bo_sprd bo_sprd;
1253 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1254 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1256 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1257 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1259 if (bufmgr_sprd->use_dma_fence) {
1260 struct dma_buf_fence fence;
1262 memset(&fence, 0, sizeof(struct dma_buf_fence));
1264 /* Check if the given type is valid or not. */
1265 if (opt & TBM_OPTION_WRITE) {
1266 if (device == TBM_DEVICE_CPU)
1267 fence.type = DMA_BUF_ACCESS_WRITE;
1268 else if (device == TBM_DEVICE_3D)
1269 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1271 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1272 getpid(), __FUNCTION__);
1275 } else if (opt & TBM_OPTION_READ) {
1276 if (device == TBM_DEVICE_CPU)
1277 fence.type = DMA_BUF_ACCESS_READ;
1278 else if (device == TBM_DEVICE_3D)
1279 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1281 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1282 getpid(), __FUNCTION__);
1286 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1287 __FUNCTION__, __LINE__);
1291 /* Check if the tbm manager supports dma fence or not. */
1292 if (!bufmgr_sprd->use_dma_fence) {
1293 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1294 "error %s:%d Not support DMA FENCE(%s)\n",
1295 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1300 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1302 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1303 "error %s:%d Can not set GET FENCE(%s)\n",
1304 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1308 pthread_mutex_lock(&bo_sprd->mutex);
1310 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1311 if (bo_sprd->dma_fence[i].ctx == 0) {
1312 bo_sprd->dma_fence[i].type = fence.type;
1313 bo_sprd->dma_fence[i].ctx = fence.ctx;
1317 if (i == DMA_FENCE_LIST_MAX) {
1318 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1319 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1320 "error %s:%d fence list is full\n",
1321 getpid(), __FUNCTION__, __LINE__);
1323 pthread_mutex_unlock(&bo_sprd->mutex);
1325 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1327 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1329 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1331 DBG ("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1332 getpid(), __FUNCTION__, bo_sprd->name);
1342 tbm_sprd_bo_unlock(tbm_bo bo)
1344 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1346 #if USE_BACKEND_LOCK
1347 tbm_bufmgr_sprd bufmgr_sprd;
1348 tbm_bo_sprd bo_sprd;
1351 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1352 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1354 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1355 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1357 if (bufmgr_sprd->use_dma_fence) {
1358 struct dma_buf_fence fence;
1360 if (!bo_sprd->dma_fence[0].ctx) {
1361 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1366 if (!bo_sprd->dma_fence[0].type) {
1367 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1372 pthread_mutex_lock(&bo_sprd->mutex);
1373 fence.type = bo_sprd->dma_fence[0].type;
1374 fence.ctx = bo_sprd->dma_fence[0].ctx;
1376 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1377 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1378 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1380 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1381 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1382 pthread_mutex_unlock(&bo_sprd->mutex);
1384 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1386 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1387 "error %s:%d Can not set PUT FENCE(%s)\n",
1388 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1392 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1394 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1396 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1398 DBG ("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1399 getpid(), __FUNCTION__, bo_sprd->name);
1408 tbm_sprd_bufmgr_deinit (void *priv)
1410 SPRD_RETURN_IF_FAIL (priv != NULL);
1412 tbm_bufmgr_sprd bufmgr_sprd;
1414 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1416 if (bufmgr_sprd->hashBos) {
1420 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1422 drmHashDelete (bufmgr_sprd->hashBos, key);
1425 drmHashDestroy (bufmgr_sprd->hashBos);
1426 bufmgr_sprd->hashBos = NULL;
1429 close (bufmgr_sprd->tgl_fd);
1431 if (bufmgr_sprd->bind_display)
1432 tbm_drm_helper_wl_server_deinit();
1438 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1440 uint32_t *color_formats = NULL;
1442 color_formats = (uint32_t *)calloc (1,
1443 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1445 if ( color_formats == NULL ) {
1448 memcpy( color_formats, tbm_sprd_color_format_list ,
1449 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1452 *formats = color_formats;
1453 *num = TBM_COLOR_FORMAT_COUNT;
1461 * @brief get the plane data of the surface.
1462 * @param[in] surface : the surface
1463 * @param[in] width : the width of the surface
1464 * @param[in] height : the height of the surface
1465 * @param[in] format : the format of the surface
1466 * @param[in] plane_idx : the format of the surface
1467 * @param[out] size : the size of the plane
1468 * @param[out] offset : the offset of the plane
1469 * @param[out] pitch : the pitch of the plane
1470 * @param[out] padding : the padding of the plane
1471 * @return 1 if this function succeeds, otherwise 0.
1474 tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height,
1475 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1476 uint32_t *pitch, int *bo_idx)
1487 case TBM_FORMAT_XRGB4444:
1488 case TBM_FORMAT_XBGR4444:
1489 case TBM_FORMAT_RGBX4444:
1490 case TBM_FORMAT_BGRX4444:
1491 case TBM_FORMAT_ARGB4444:
1492 case TBM_FORMAT_ABGR4444:
1493 case TBM_FORMAT_RGBA4444:
1494 case TBM_FORMAT_BGRA4444:
1495 case TBM_FORMAT_XRGB1555:
1496 case TBM_FORMAT_XBGR1555:
1497 case TBM_FORMAT_RGBX5551:
1498 case TBM_FORMAT_BGRX5551:
1499 case TBM_FORMAT_ARGB1555:
1500 case TBM_FORMAT_ABGR1555:
1501 case TBM_FORMAT_RGBA5551:
1502 case TBM_FORMAT_BGRA5551:
1503 case TBM_FORMAT_RGB565:
1506 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1507 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1511 case TBM_FORMAT_RGB888:
1512 case TBM_FORMAT_BGR888:
1515 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1516 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1520 case TBM_FORMAT_XRGB8888:
1521 case TBM_FORMAT_XBGR8888:
1522 case TBM_FORMAT_RGBX8888:
1523 case TBM_FORMAT_BGRX8888:
1524 case TBM_FORMAT_ARGB8888:
1525 case TBM_FORMAT_ABGR8888:
1526 case TBM_FORMAT_RGBA8888:
1527 case TBM_FORMAT_BGRA8888:
1530 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1531 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1536 case TBM_FORMAT_YUYV:
1537 case TBM_FORMAT_YVYU:
1538 case TBM_FORMAT_UYVY:
1539 case TBM_FORMAT_VYUY:
1540 case TBM_FORMAT_AYUV:
1543 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1544 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1550 * index 0 = Y plane, [7:0] Y
1551 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1553 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1555 case TBM_FORMAT_NV12:
1556 case TBM_FORMAT_NV21:
1558 if (plane_idx == 0) {
1560 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1561 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1563 } else if ( plane_idx == 1 ) {
1564 _offset = width * height;
1565 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1566 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1571 case TBM_FORMAT_NV16:
1572 case TBM_FORMAT_NV61:
1574 //if(plane_idx == 0)
1577 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1578 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1583 //else if( plane_idx ==1 )
1586 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1587 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1594 * index 0: Y plane, [7:0] Y
1595 * index 1: Cb plane, [7:0] Cb
1596 * index 2: Cr plane, [7:0] Cr
1598 * index 1: Cr plane, [7:0] Cr
1599 * index 2: Cb plane, [7:0] Cb
1602 NATIVE_BUFFER_FORMAT_YV12
1603 NATIVE_BUFFER_FORMAT_I420
1605 case TBM_FORMAT_YUV410:
1606 case TBM_FORMAT_YVU410:
1609 case TBM_FORMAT_YUV411:
1610 case TBM_FORMAT_YVU411:
1611 case TBM_FORMAT_YUV420:
1612 case TBM_FORMAT_YVU420:
1614 //if(plane_idx == 0)
1617 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1618 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1623 //else if( plane_idx == 1 )
1626 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1627 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1632 //else if (plane_idx == 2 )
1635 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1636 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1640 case TBM_FORMAT_YUV422:
1641 case TBM_FORMAT_YVU422:
1643 //if(plane_idx == 0)
1646 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1647 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1652 //else if( plane_idx == 1 )
1655 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1656 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1661 //else if (plane_idx == 2 )
1664 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1665 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1669 case TBM_FORMAT_YUV444:
1670 case TBM_FORMAT_YVU444:
1672 //if(plane_idx == 0)
1675 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1676 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1681 //else if( plane_idx == 1 )
1684 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1685 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1690 //else if (plane_idx == 2 )
1693 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1694 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1712 tbm_sprd_bo_get_flags (tbm_bo bo)
1714 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1716 tbm_bo_sprd bo_sprd;
1718 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1719 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1721 return bo_sprd->flags_tbm;
1725 tbm_sprd_bufmgr_bind_native_display (tbm_bufmgr bufmgr, void *NativeDisplay)
1727 tbm_bufmgr_sprd bufmgr_sprd;
1729 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1730 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1732 if (!tbm_drm_helper_wl_server_init(NativeDisplay, bufmgr_sprd->fd,
1733 "/dev/dri/card0", 0)) {
1734 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1738 bufmgr_sprd->bind_display = NativeDisplay;
1743 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1745 static TBMModuleVersionInfo SprdVersRec = {
1751 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1754 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1756 tbm_bufmgr_sprd bufmgr_sprd;
1757 tbm_bufmgr_backend bufmgr_backend;
1762 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1764 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1768 if (tbm_backend_is_display_server()) {
1769 bufmgr_sprd->fd = -1;
1770 bufmgr_sprd->fd = tbm_drm_helper_get_master_fd();
1771 if (bufmgr_sprd->fd < 0) {
1772 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1773 tbm_drm_helper_set_master_fd(bufmgr_sprd->fd);
1775 if (bufmgr_sprd->fd < 0) {
1776 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1781 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), NULL, NULL)) {
1782 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1788 /* open tgl fd for saving cache flush data */
1789 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
1791 if (bufmgr_sprd->tgl_fd < 0) {
1792 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
1793 if (bufmgr_sprd->tgl_fd < 0) {
1794 TBM_SPRD_LOG("[libtbm:%d] "
1795 "error: Fail to open global_lock:%s\n",
1796 getpid(), tgl_devfile);
1803 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
1804 TBM_SPRD_LOG("[libtbm:%d] "
1805 "error: Fail to initialize the tgl\n",
1813 bufmgr_sprd->hashBos = drmHashCreate ();
1815 //Check if the tbm manager supports dma fence or not.
1816 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1820 length = read(fp, buf, 1);
1822 if (length == 1 && buf[0] == '1')
1823 bufmgr_sprd->use_dma_fence = 1;
1828 bufmgr_backend = tbm_backend_alloc();
1829 if (!bufmgr_backend) {
1830 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1836 bufmgr_backend->priv = (void *)bufmgr_sprd;
1837 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1838 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1839 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1840 bufmgr_backend->bo_free = tbm_sprd_bo_free;
1841 bufmgr_backend->bo_import = tbm_sprd_bo_import;
1842 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1843 bufmgr_backend->bo_export = tbm_sprd_bo_export;
1844 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1845 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1846 bufmgr_backend->bo_map = tbm_sprd_bo_map;
1847 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1848 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1849 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1850 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1851 bufmgr_backend->bo_lock = NULL;
1852 bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1853 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1854 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1856 bufmgr_backend->flags |= TBM_LOCK_CTRL_BACKEND;
1857 bufmgr_backend->flags |= TBM_USE_2_0_BACKEND;
1859 if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
1860 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1861 tbm_backend_free (bufmgr_backend);
1870 env = getenv ("TBM_SPRD_DEBUG");
1872 bDebug = atoi (env);
1873 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1880 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1881 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1883 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
1884 __FUNCTION__, bufmgr_sprd->fd);