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 {
237 char *STR_DEVICE[] = {
253 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
264 _tgl_init(int fd, unsigned int key)
266 struct tgl_attribute attr;
270 attr.timeout_ms = 1000;
272 err = ioctl(fd, TGL_IOC_INIT_LOCK, &attr);
274 TBM_SPRD_LOG("[libtbm-sprd:%d] error(%s) %s:%d key:%d\n",
275 getpid(), strerror(errno), __func__, __LINE__, key);
283 _tgl_destroy(int fd, unsigned int key)
287 err = ioctl(fd, TGL_IOC_DESTROY_LOCK, key);
289 TBM_SPRD_LOG("[libtbm-sprd:%d] "
290 "error(%s) %s:%d key:%d\n",
291 getpid(), strerror(errno), __func__, __LINE__, key);
299 _tgl_lock(int fd, unsigned int key)
303 err = ioctl(fd, TGL_IOC_LOCK_LOCK, key);
305 TBM_SPRD_LOG("[libtbm-sprd:%d] "
306 "error(%s) %s:%d key:%d\n",
307 getpid(), strerror(errno), __func__, __LINE__, key);
315 _tgl_unlock(int fd, unsigned int key)
319 err = ioctl(fd, TGL_IOC_UNLOCK_LOCK, key);
321 TBM_SPRD_LOG("[libtbm-sprd:%d] "
322 "error(%s) %s:%d key:%d\n",
323 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;
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_bo bo, int flags)
465 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
466 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
468 /* cache flush is managed by kernel side when using dma-fence. */
469 if (bufmgr_sprd->use_dma_fence)
472 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
476 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
477 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
480 struct drm_sprd_gem_cache_op cache_op = {0, };
483 /* if bo_sprd is null, do cache_flush_all */
486 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
487 cache_op.size = bo_sprd->size;
489 flags = TBM_SPRD_CACHE_FLUSH_ALL;
491 cache_op.usr_addr = 0;
495 if (flags & TBM_SPRD_CACHE_INV) {
496 if (flags & TBM_SPRD_CACHE_ALL)
497 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
499 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
502 if (flags & TBM_SPRD_CACHE_CLN) {
503 if (flags & TBM_SPRD_CACHE_ALL)
504 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
506 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
509 if (flags & TBM_SPRD_CACHE_ALL)
510 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
512 ret = drmCommandWriteRead (bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
515 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
516 "error %s:%d fail to flush the cache.\n",
517 getpid(), __FUNCTION__, __LINE__);
526 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
528 tbm_bo_cache_state cache_state;
530 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
531 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
533 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
535 cache_state.data.isDirtied = DEVICE_NONE;
536 cache_state.data.isCached = 0;
537 cache_state.data.cntFlush = 0;
539 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
545 _bo_set_cache_state(tbm_bo bo, int device, int opt)
548 tbm_bufmgr_sprd bufmgr_sprd;
550 unsigned short cntFlush = 0;
552 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
553 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
555 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
556 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
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 (bo, 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,
612 _bo_save_cache_state(tbm_bo bo)
614 unsigned short cntFlush = 0;
616 tbm_bufmgr_sprd bufmgr_sprd;
618 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
619 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
621 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
622 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 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);
635 _bo_destroy_cache_state(tbm_bo bo)
638 tbm_bufmgr_sprd bufmgr_sprd;
640 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
641 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
643 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
644 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
646 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
649 #ifndef USE_CONTIG_ONLY
651 _get_sprd_flag_from_tbm (unsigned int ftbm)
653 unsigned int flags = 0;
656 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
657 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
658 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
659 * To be updated appropriately once DRM-GEM supports different heap id masks.
662 if (ftbm & TBM_BO_SCANOUT) {
663 flags = SPRD_BO_CONTIG;
665 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
668 if (ftbm & TBM_BO_WC)
670 else if (ftbm & TBM_BO_NONCACHABLE)
671 flags |= SPRD_BO_NONCACHABLE;
677 _get_tbm_flag_from_sprd (unsigned int fsprd)
679 unsigned int flags = 0;
681 if (fsprd & SPRD_BO_NONCONTIG)
682 flags |= TBM_BO_DEFAULT;
684 flags |= TBM_BO_SCANOUT;
686 if (fsprd & SPRD_BO_WC)
688 else if (fsprd & SPRD_BO_CACHABLE)
689 flags |= TBM_BO_DEFAULT;
691 flags |= TBM_BO_NONCACHABLE;
698 _get_name (int fd, unsigned int gem)
700 struct drm_gem_flink arg = {0,};
703 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
704 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
705 "error %s:%d fail to get flink gem=%d\n",
706 getpid(), __FUNCTION__, __LINE__, gem);
710 return (unsigned int)arg.name;
714 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
716 tbm_bo_handle bo_handle;
717 memset (&bo_handle, 0x0, sizeof (uint64_t));
720 case TBM_DEVICE_DEFAULT:
722 bo_handle.u32 = (uint32_t)bo_sprd->gem;
725 if (!bo_sprd->pBase) {
726 struct drm_sprd_gem_mmap arg = {0,};
728 arg.handle = bo_sprd->gem;
729 arg.size = bo_sprd->size;
730 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
731 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
732 "error %s:%d Cannot usrptr gem=%d\n",
733 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
734 return (tbm_bo_handle) NULL;
736 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
739 bo_handle.ptr = (void *)bo_sprd->pBase;
743 if (!bo_sprd->dmabuf) {
744 struct drm_prime_handle arg = {0, };
745 arg.handle = bo_sprd->gem;
746 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
747 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
748 "error %s:%d Cannot dmabuf=%d\n",
749 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
750 return (tbm_bo_handle) NULL;
752 bo_sprd->dmabuf = arg.fd;
755 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
762 //TODO : Add ioctl for GSP MAP once available.
763 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
768 if (!bo_sprd->dmabuf) {
769 struct drm_prime_handle arg = {0, };
771 arg.handle = bo_sprd->gem;
772 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
773 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
774 "error %s:%d Cannot dmabuf=%d\n",
775 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
776 return (tbm_bo_handle) NULL;
778 bo_sprd->dmabuf = arg.fd;
781 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
785 bo_handle.ptr = (void *) NULL;
793 tbm_sprd_bo_size (tbm_bo bo)
795 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
799 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
801 return bo_sprd->size;
805 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
807 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
810 tbm_bufmgr_sprd bufmgr_sprd;
811 unsigned int sprd_flags;
813 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
814 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
816 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
818 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
819 "error %s:%d fail to allocate the bo private\n",
820 getpid(), __FUNCTION__, __LINE__);
824 #ifdef USE_CONTIG_ONLY
825 flags = TBM_BO_SCANOUT;
826 sprd_flags = SPRD_BO_CONTIG;
828 sprd_flags = _get_sprd_flag_from_tbm (flags);
829 if ((flags & TBM_BO_SCANOUT) &&
831 sprd_flags |= SPRD_BO_NONCONTIG;
833 #endif // USE_CONTIG_ONLY
834 struct drm_sprd_gem_create arg = {0, };
836 arg.flags = sprd_flags;
837 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
839 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
840 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
841 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
846 bo_sprd->fd = bufmgr_sprd->fd;
847 bo_sprd->gem = arg.handle;
848 bo_sprd->size = size;
849 bo_sprd->flags_tbm = flags;
850 bo_sprd->flags_sprd = sprd_flags;
851 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
853 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd)) {
854 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
859 pthread_mutex_init(&bo_sprd->mutex, NULL);
861 if (bufmgr_sprd->use_dma_fence
862 && !bo_sprd->dmabuf) {
863 struct drm_prime_handle arg = {0, };
865 arg.handle = bo_sprd->gem;
866 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
867 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
868 "error %s:%d Cannot dmabuf=%d\n",
869 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
873 bo_sprd->dmabuf = arg.fd;
877 PrivGem *privGem = calloc (1, sizeof(PrivGem));
878 privGem->ref_count = 1;
879 privGem->bo_priv = bo_sprd;
880 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
881 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
882 "error %s:%d Cannot insert bo to Hash(%d)\n",
883 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
886 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
887 __FUNCTION__, bo_sprd->size,
888 bo_sprd->gem, bo_sprd->name,
891 return (void *)bo_sprd;
895 tbm_sprd_bo_free(tbm_bo bo)
898 tbm_bufmgr_sprd bufmgr_sprd;
903 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
904 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
906 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
907 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
909 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
910 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
912 if (bo_sprd->pBase) {
913 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
914 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
916 getpid(), __FUNCTION__, __LINE__);
921 if (bo_sprd->dmabuf) {
922 close (bo_sprd->dmabuf);
926 /* delete bo from hash */
927 PrivGem *privGem = NULL;
930 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
932 privGem->ref_count--;
933 if (privGem->ref_count == 0) {
934 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
939 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
940 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
941 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
944 _bo_destroy_cache_state(bo);
946 /* Free gem handle */
947 struct drm_gem_close arg = {0, };
948 memset (&arg, 0, sizeof(arg));
949 arg.handle = bo_sprd->gem;
950 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
951 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
953 getpid(), __FUNCTION__, __LINE__);
961 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
963 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
965 tbm_bufmgr_sprd bufmgr_sprd;
967 PrivGem *privGem = NULL;
970 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
971 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
973 ret = drmHashLookup (bufmgr_sprd->hashBos, key, (void **)&privGem);
975 privGem->ref_count++;
976 return privGem->bo_priv;
979 struct drm_gem_open arg = {0, };
980 struct drm_sprd_gem_info info = {0, };
983 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
984 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
985 "error %s:%d Cannot open gem name=%d\n",
986 getpid(), __FUNCTION__, __LINE__, key);
990 info.handle = arg.handle;
991 if (drmCommandWriteRead(bufmgr_sprd->fd,
994 sizeof(struct drm_sprd_gem_info))) {
995 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
996 "error %s:%d Cannot get gem info=%d\n",
997 getpid(), __FUNCTION__, __LINE__, key);
1001 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1003 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1004 "error %s:%d fail to allocate the bo private\n",
1005 getpid(), __FUNCTION__, __LINE__);
1009 bo_sprd->fd = bufmgr_sprd->fd;
1010 bo_sprd->gem = arg.handle;
1011 bo_sprd->size = arg.size;
1012 bo_sprd->flags_sprd = info.flags;
1013 bo_sprd->name = key;
1014 #ifdef USE_CONTIG_ONLY
1015 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1016 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1018 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1021 if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
1022 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
1027 if (!bo_sprd->dmabuf) {
1028 struct drm_prime_handle arg = {0, };
1030 arg.handle = bo_sprd->gem;
1031 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1032 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1033 "error %s:%d Cannot dmabuf=%d\n",
1034 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1038 bo_sprd->dmabuf = arg.fd;
1041 /* add bo to hash */
1042 privGem = calloc (1, sizeof(PrivGem));
1043 privGem->ref_count = 1;
1044 privGem->bo_priv = bo_sprd;
1045 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1046 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1047 "error %s:%d Cannot insert bo to Hash(%d)\n",
1048 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1051 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1052 __FUNCTION__, bo_sprd->size,
1053 bo_sprd->gem, bo_sprd->name,
1054 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1056 return (void *)bo_sprd;
1060 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
1062 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1064 tbm_bufmgr_sprd bufmgr_sprd;
1065 tbm_bo_sprd bo_sprd;
1066 PrivGem *privGem = NULL;
1070 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1071 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1073 //getting handle from fd
1074 unsigned int gem = 0;
1075 struct drm_prime_handle arg = {0, };
1079 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1080 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1081 bo, arg.fd, strerror(errno));
1086 name = _get_name (bufmgr_sprd->fd, gem);
1088 ret = drmHashLookup (bufmgr_sprd->hashBos, name, (void **)&privGem);
1090 if (gem == privGem->bo_priv->gem) {
1091 privGem->ref_count++;
1092 return privGem->bo_priv;
1096 unsigned int real_size = -1;
1097 struct drm_sprd_gem_info info = {0, };
1099 /* Determine size of bo. The fd-to-handle ioctl really should
1100 * return the size, but it doesn't. If we have kernel 3.12 or
1101 * later, we can lseek on the prime fd to get the size. Older
1102 * kernels will just fail, in which case we fall back to the
1103 * provided (estimated or guess size). */
1104 real_size = lseek(key, 0, SEEK_END);
1107 if (drmCommandWriteRead(bufmgr_sprd->fd,
1110 sizeof(struct drm_sprd_gem_info))) {
1111 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1112 bo, gem, key, strerror(errno));
1116 if (real_size == -1)
1117 real_size = info.size;
1119 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1121 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
1125 bo_sprd->fd = bufmgr_sprd->fd;
1127 bo_sprd->size = real_size;
1128 bo_sprd->flags_sprd = info.flags;
1129 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1131 bo_sprd->name = name;
1132 if (!bo_sprd->name) {
1133 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1134 bo, gem, key, strerror(errno));
1139 if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
1140 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
1145 /* add bo to hash */
1148 privGem = calloc (1, sizeof(PrivGem));
1150 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1151 "error %s:%d Fail to calloc privGem\n",
1152 getpid(), __FUNCTION__, __LINE__);
1157 privGem->ref_count = 1;
1158 privGem->bo_priv = bo_sprd;
1159 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1160 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1161 bo, bo_sprd->name, gem, key);
1164 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1167 bo_sprd->gem, bo_sprd->name,
1170 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1173 return (void *)bo_sprd;
1177 tbm_sprd_bo_export (tbm_bo bo)
1179 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1181 tbm_bo_sprd bo_sprd;
1183 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1184 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1186 if (!bo_sprd->name) {
1187 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1188 if (!bo_sprd->name) {
1189 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1190 "error %s:%d Cannot get name\n",
1191 getpid(), __FUNCTION__, __LINE__);
1196 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1197 __FUNCTION__, bo_sprd->size,
1198 bo_sprd->gem, bo_sprd->name,
1199 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1201 return (unsigned int)bo_sprd->name;
1205 tbm_sprd_bo_export_fd (tbm_bo bo)
1207 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, -1);
1209 tbm_bo_sprd bo_sprd;
1212 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1213 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, -1);
1215 struct drm_prime_handle arg = {0, };
1217 arg.handle = bo_sprd->gem;
1218 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1220 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
1221 bo, bo_sprd->gem, strerror(errno));
1222 return (tbm_fd) ret;
1225 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1228 bo_sprd->gem, bo_sprd->name,
1231 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1234 return (tbm_fd)arg.fd;
1238 static tbm_bo_handle
1239 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
1241 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1243 tbm_bo_handle bo_handle;
1244 tbm_bo_sprd bo_sprd;
1246 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1247 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1249 if (!bo_sprd->gem) {
1250 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1251 "error %s:%d Cannot map gem=%d\n",
1252 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1253 return (tbm_bo_handle) NULL;
1256 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1257 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1259 /*Get mapped bo_handle*/
1260 bo_handle = _sprd_bo_handle (bo_sprd, device);
1261 if (bo_handle.ptr == NULL) {
1262 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1263 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1264 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1265 return (tbm_bo_handle) NULL;
1271 static tbm_bo_handle
1272 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
1274 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1276 tbm_bo_handle bo_handle;
1277 tbm_bo_sprd bo_sprd;
1279 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1280 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1282 if (!bo_sprd->gem) {
1283 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1284 "error %s:%d Cannot map gem=%d\n",
1285 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1286 return (tbm_bo_handle) NULL;
1289 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1290 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1292 /*Get mapped bo_handle*/
1293 bo_handle = _sprd_bo_handle (bo_sprd, device);
1294 if (bo_handle.ptr == NULL) {
1295 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1296 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1297 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1298 return (tbm_bo_handle) NULL;
1301 if (bo_sprd->map_cnt == 0)
1302 _bo_set_cache_state (bo, device, opt);
1310 tbm_sprd_bo_unmap (tbm_bo bo)
1312 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1314 tbm_bo_sprd bo_sprd;
1316 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1317 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1324 if (bo_sprd->map_cnt == 0)
1325 _bo_save_cache_state (bo);
1327 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1328 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1334 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1336 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1338 #if USE_BACKEND_LOCK
1339 tbm_bufmgr_sprd bufmgr_sprd;
1340 tbm_bo_sprd bo_sprd;
1343 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1344 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1346 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1347 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1349 if (bufmgr_sprd->use_dma_fence) {
1350 struct dma_buf_fence fence;
1352 memset(&fence, 0, sizeof(struct dma_buf_fence));
1354 /* Check if the given type is valid or not. */
1355 if (opt & TBM_OPTION_WRITE) {
1356 if (device == TBM_DEVICE_CPU)
1357 fence.type = DMA_BUF_ACCESS_WRITE;
1358 else if (device == TBM_DEVICE_3D)
1359 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1361 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1362 getpid(), __FUNCTION__);
1365 } else if (opt & TBM_OPTION_READ) {
1366 if (device == TBM_DEVICE_CPU)
1367 fence.type = DMA_BUF_ACCESS_READ;
1368 else if (device == TBM_DEVICE_3D)
1369 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1371 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1372 getpid(), __FUNCTION__);
1376 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1377 __FUNCTION__, __LINE__);
1381 /* Check if the tbm manager supports dma fence or not. */
1382 if (!bufmgr_sprd->use_dma_fence) {
1383 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1384 "error %s:%d Not support DMA FENCE(%s)\n",
1385 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1390 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1392 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1393 "error %s:%d Can not set GET FENCE(%s)\n",
1394 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1398 pthread_mutex_lock(&bo_sprd->mutex);
1400 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1401 if (bo_sprd->dma_fence[i].ctx == 0) {
1402 bo_sprd->dma_fence[i].type = fence.type;
1403 bo_sprd->dma_fence[i].ctx = fence.ctx;
1407 if (i == DMA_FENCE_LIST_MAX) {
1408 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1409 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1410 "error %s:%d fence list is full\n",
1411 getpid(), __FUNCTION__, __LINE__);
1413 pthread_mutex_unlock(&bo_sprd->mutex);
1415 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1417 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1419 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1421 DBG ("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1422 getpid(), __FUNCTION__, bo_sprd->name);
1432 tbm_sprd_bo_unlock(tbm_bo bo)
1434 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1436 #if USE_BACKEND_LOCK
1437 tbm_bufmgr_sprd bufmgr_sprd;
1438 tbm_bo_sprd bo_sprd;
1441 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1442 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1444 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1445 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1447 if (bufmgr_sprd->use_dma_fence) {
1448 struct dma_buf_fence fence;
1450 if (!bo_sprd->dma_fence[0].ctx) {
1451 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1456 if (!bo_sprd->dma_fence[0].type) {
1457 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1462 pthread_mutex_lock(&bo_sprd->mutex);
1463 fence.type = bo_sprd->dma_fence[0].type;
1464 fence.ctx = bo_sprd->dma_fence[0].ctx;
1466 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1467 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1468 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1470 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1471 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1472 pthread_mutex_unlock(&bo_sprd->mutex);
1474 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1476 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1477 "error %s:%d Can not set PUT FENCE(%s)\n",
1478 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1482 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1484 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1486 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1488 DBG ("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1489 getpid(), __FUNCTION__, bo_sprd->name);
1498 tbm_sprd_bufmgr_deinit (void *priv)
1500 SPRD_RETURN_IF_FAIL (priv != NULL);
1502 tbm_bufmgr_sprd bufmgr_sprd;
1504 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1506 if (bufmgr_sprd->hashBos) {
1510 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1512 drmHashDelete (bufmgr_sprd->hashBos, key);
1515 drmHashDestroy (bufmgr_sprd->hashBos);
1516 bufmgr_sprd->hashBos = NULL;
1519 close (bufmgr_sprd->tgl_fd);
1521 if (bufmgr_sprd->bind_display)
1522 tbm_drm_helper_wl_auth_server_deinit();
1524 if (bufmgr_sprd->device_name)
1525 free(bufmgr_sprd->device_name);
1527 close (bufmgr_sprd->fd);
1533 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1535 uint32_t *color_formats = NULL;
1537 color_formats = (uint32_t *)calloc (1,
1538 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1540 if ( color_formats == NULL ) {
1543 memcpy( color_formats, tbm_sprd_color_format_list ,
1544 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1547 *formats = color_formats;
1548 *num = TBM_COLOR_FORMAT_COUNT;
1556 * @brief get the plane data of the surface.
1557 * @param[in] surface : the surface
1558 * @param[in] width : the width of the surface
1559 * @param[in] height : the height of the surface
1560 * @param[in] format : the format of the surface
1561 * @param[in] plane_idx : the format of the surface
1562 * @param[out] size : the size of the plane
1563 * @param[out] offset : the offset of the plane
1564 * @param[out] pitch : the pitch of the plane
1565 * @param[out] padding : the padding of the plane
1566 * @return 1 if this function succeeds, otherwise 0.
1569 tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height,
1570 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1571 uint32_t *pitch, int *bo_idx)
1582 case TBM_FORMAT_XRGB4444:
1583 case TBM_FORMAT_XBGR4444:
1584 case TBM_FORMAT_RGBX4444:
1585 case TBM_FORMAT_BGRX4444:
1586 case TBM_FORMAT_ARGB4444:
1587 case TBM_FORMAT_ABGR4444:
1588 case TBM_FORMAT_RGBA4444:
1589 case TBM_FORMAT_BGRA4444:
1590 case TBM_FORMAT_XRGB1555:
1591 case TBM_FORMAT_XBGR1555:
1592 case TBM_FORMAT_RGBX5551:
1593 case TBM_FORMAT_BGRX5551:
1594 case TBM_FORMAT_ARGB1555:
1595 case TBM_FORMAT_ABGR1555:
1596 case TBM_FORMAT_RGBA5551:
1597 case TBM_FORMAT_BGRA5551:
1598 case TBM_FORMAT_RGB565:
1601 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1602 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1606 case TBM_FORMAT_RGB888:
1607 case TBM_FORMAT_BGR888:
1610 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1611 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1615 case TBM_FORMAT_XRGB8888:
1616 case TBM_FORMAT_XBGR8888:
1617 case TBM_FORMAT_RGBX8888:
1618 case TBM_FORMAT_BGRX8888:
1619 case TBM_FORMAT_ARGB8888:
1620 case TBM_FORMAT_ABGR8888:
1621 case TBM_FORMAT_RGBA8888:
1622 case TBM_FORMAT_BGRA8888:
1625 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1626 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1631 case TBM_FORMAT_YUYV:
1632 case TBM_FORMAT_YVYU:
1633 case TBM_FORMAT_UYVY:
1634 case TBM_FORMAT_VYUY:
1635 case TBM_FORMAT_AYUV:
1638 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1639 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1645 * index 0 = Y plane, [7:0] Y
1646 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1648 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1650 case TBM_FORMAT_NV12:
1651 case TBM_FORMAT_NV21:
1653 if (plane_idx == 0) {
1655 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1656 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1658 } else if ( plane_idx == 1 ) {
1659 _offset = width * height;
1660 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1661 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1666 case TBM_FORMAT_NV16:
1667 case TBM_FORMAT_NV61:
1669 //if(plane_idx == 0)
1672 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1673 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1678 //else if( plane_idx ==1 )
1681 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1682 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1689 * index 0: Y plane, [7:0] Y
1690 * index 1: Cb plane, [7:0] Cb
1691 * index 2: Cr plane, [7:0] Cr
1693 * index 1: Cr plane, [7:0] Cr
1694 * index 2: Cb plane, [7:0] Cb
1697 NATIVE_BUFFER_FORMAT_YV12
1698 NATIVE_BUFFER_FORMAT_I420
1700 case TBM_FORMAT_YUV410:
1701 case TBM_FORMAT_YVU410:
1704 case TBM_FORMAT_YUV411:
1705 case TBM_FORMAT_YVU411:
1706 case TBM_FORMAT_YUV420:
1707 case TBM_FORMAT_YVU420:
1709 //if(plane_idx == 0)
1712 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1713 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1718 //else if( plane_idx == 1 )
1721 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1722 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1727 //else if (plane_idx == 2 )
1730 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1731 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1735 case TBM_FORMAT_YUV422:
1736 case TBM_FORMAT_YVU422:
1738 //if(plane_idx == 0)
1741 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1742 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1747 //else if( plane_idx == 1 )
1750 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1751 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1756 //else if (plane_idx == 2 )
1759 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1760 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1764 case TBM_FORMAT_YUV444:
1765 case TBM_FORMAT_YVU444:
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, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1780 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1785 //else if (plane_idx == 2 )
1788 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1789 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1807 tbm_sprd_bo_get_flags (tbm_bo bo)
1809 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1811 tbm_bo_sprd bo_sprd;
1813 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1814 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1816 return bo_sprd->flags_tbm;
1820 tbm_sprd_bufmgr_bind_native_display (tbm_bufmgr bufmgr, void *NativeDisplay)
1822 tbm_bufmgr_sprd bufmgr_sprd;
1824 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1825 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1827 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1828 bufmgr_sprd->device_name, 0)) {
1829 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1833 bufmgr_sprd->bind_display = NativeDisplay;
1838 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1840 static TBMModuleVersionInfo SprdVersRec = {
1846 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1849 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1851 tbm_bufmgr_sprd bufmgr_sprd;
1852 tbm_bufmgr_backend bufmgr_backend;
1857 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1859 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1863 if (tbm_backend_is_display_server()) {
1866 bufmgr_sprd->fd = -1;
1867 master_fd = tbm_drm_helper_get_master_fd();
1868 if (master_fd < 0) {
1869 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1870 tbm_drm_helper_set_master_fd(bufmgr_sprd->fd);
1872 bufmgr_sprd->fd = dup(master_fd);
1875 if (bufmgr_sprd->fd < 0) {
1876 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1881 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1883 if (!bufmgr_sprd->device_name)
1885 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1891 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1892 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1898 /* open tgl fd for saving cache flush data */
1899 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
1901 if (bufmgr_sprd->tgl_fd < 0) {
1902 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
1903 if (bufmgr_sprd->tgl_fd < 0) {
1904 TBM_SPRD_LOG("[libtbm:%d] "
1905 "error: Fail to open global_lock:%s\n",
1906 getpid(), tgl_devfile);
1913 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
1914 TBM_SPRD_LOG("[libtbm:%d] "
1915 "error: Fail to initialize the tgl\n",
1923 bufmgr_sprd->hashBos = drmHashCreate ();
1925 //Check if the tbm manager supports dma fence or not.
1926 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1930 length = read(fp, buf, 1);
1932 if (length == 1 && buf[0] == '1')
1933 bufmgr_sprd->use_dma_fence = 1;
1938 bufmgr_backend = tbm_backend_alloc();
1939 if (!bufmgr_backend) {
1940 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1946 bufmgr_backend->priv = (void *)bufmgr_sprd;
1947 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1948 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1949 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1950 bufmgr_backend->bo_free = tbm_sprd_bo_free;
1951 bufmgr_backend->bo_import = tbm_sprd_bo_import;
1952 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1953 bufmgr_backend->bo_export = tbm_sprd_bo_export;
1954 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1955 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1956 bufmgr_backend->bo_map = tbm_sprd_bo_map;
1957 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1958 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1959 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1960 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1961 bufmgr_backend->bo_lock = NULL;
1962 bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1963 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1964 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1966 bufmgr_backend->flags |= TBM_LOCK_CTRL_BACKEND;
1967 bufmgr_backend->flags |= TBM_USE_2_0_BACKEND;
1969 if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
1970 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1971 tbm_backend_free (bufmgr_backend);
1980 env = getenv ("TBM_SPRD_DEBUG");
1982 bDebug = atoi (env);
1983 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1990 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1991 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1993 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
1994 __FUNCTION__, bufmgr_sprd->fd);