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 if (bufmgr_sprd->bind_display)
1520 tbm_drm_helper_wl_auth_server_deinit();
1522 if (bufmgr_sprd->device_name)
1523 free(bufmgr_sprd->device_name);
1525 close (bufmgr_sprd->tgl_fd);
1526 close (bufmgr_sprd->fd);
1532 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1534 uint32_t *color_formats = NULL;
1536 color_formats = (uint32_t *)calloc (1,
1537 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1539 if ( color_formats == NULL ) {
1542 memcpy( color_formats, tbm_sprd_color_format_list ,
1543 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1546 *formats = color_formats;
1547 *num = TBM_COLOR_FORMAT_COUNT;
1555 * @brief get the plane data of the surface.
1556 * @param[in] surface : the surface
1557 * @param[in] width : the width of the surface
1558 * @param[in] height : the height of the surface
1559 * @param[in] format : the format of the surface
1560 * @param[in] plane_idx : the format of the surface
1561 * @param[out] size : the size of the plane
1562 * @param[out] offset : the offset of the plane
1563 * @param[out] pitch : the pitch of the plane
1564 * @param[out] padding : the padding of the plane
1565 * @return 1 if this function succeeds, otherwise 0.
1568 tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height,
1569 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1570 uint32_t *pitch, int *bo_idx)
1581 case TBM_FORMAT_XRGB4444:
1582 case TBM_FORMAT_XBGR4444:
1583 case TBM_FORMAT_RGBX4444:
1584 case TBM_FORMAT_BGRX4444:
1585 case TBM_FORMAT_ARGB4444:
1586 case TBM_FORMAT_ABGR4444:
1587 case TBM_FORMAT_RGBA4444:
1588 case TBM_FORMAT_BGRA4444:
1589 case TBM_FORMAT_XRGB1555:
1590 case TBM_FORMAT_XBGR1555:
1591 case TBM_FORMAT_RGBX5551:
1592 case TBM_FORMAT_BGRX5551:
1593 case TBM_FORMAT_ARGB1555:
1594 case TBM_FORMAT_ABGR1555:
1595 case TBM_FORMAT_RGBA5551:
1596 case TBM_FORMAT_BGRA5551:
1597 case TBM_FORMAT_RGB565:
1600 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1601 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1605 case TBM_FORMAT_RGB888:
1606 case TBM_FORMAT_BGR888:
1609 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1610 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1614 case TBM_FORMAT_XRGB8888:
1615 case TBM_FORMAT_XBGR8888:
1616 case TBM_FORMAT_RGBX8888:
1617 case TBM_FORMAT_BGRX8888:
1618 case TBM_FORMAT_ARGB8888:
1619 case TBM_FORMAT_ABGR8888:
1620 case TBM_FORMAT_RGBA8888:
1621 case TBM_FORMAT_BGRA8888:
1624 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1625 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1630 case TBM_FORMAT_YUYV:
1631 case TBM_FORMAT_YVYU:
1632 case TBM_FORMAT_UYVY:
1633 case TBM_FORMAT_VYUY:
1634 case TBM_FORMAT_AYUV:
1637 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1638 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1644 * index 0 = Y plane, [7:0] Y
1645 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1647 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1649 case TBM_FORMAT_NV12:
1650 case TBM_FORMAT_NV21:
1652 if (plane_idx == 0) {
1654 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1655 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1657 } else if ( plane_idx == 1 ) {
1658 _offset = width * height;
1659 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1660 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1665 case TBM_FORMAT_NV16:
1666 case TBM_FORMAT_NV61:
1668 //if(plane_idx == 0)
1671 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1672 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1677 //else if( plane_idx ==1 )
1680 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1681 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1688 * index 0: Y plane, [7:0] Y
1689 * index 1: Cb plane, [7:0] Cb
1690 * index 2: Cr plane, [7:0] Cr
1692 * index 1: Cr plane, [7:0] Cr
1693 * index 2: Cb plane, [7:0] Cb
1696 NATIVE_BUFFER_FORMAT_YV12
1697 NATIVE_BUFFER_FORMAT_I420
1699 case TBM_FORMAT_YUV410:
1700 case TBM_FORMAT_YVU410:
1703 case TBM_FORMAT_YUV411:
1704 case TBM_FORMAT_YVU411:
1705 case TBM_FORMAT_YUV420:
1706 case TBM_FORMAT_YVU420:
1708 //if(plane_idx == 0)
1711 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1712 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1717 //else if( plane_idx == 1 )
1720 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1721 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1726 //else if (plane_idx == 2 )
1729 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1730 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1734 case TBM_FORMAT_YUV422:
1735 case TBM_FORMAT_YVU422:
1737 //if(plane_idx == 0)
1740 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1741 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1746 //else if( plane_idx == 1 )
1749 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1750 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1755 //else if (plane_idx == 2 )
1758 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1759 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1763 case TBM_FORMAT_YUV444:
1764 case TBM_FORMAT_YVU444:
1766 //if(plane_idx == 0)
1769 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1770 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1775 //else if( plane_idx == 1 )
1778 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1779 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1784 //else if (plane_idx == 2 )
1787 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1788 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1806 tbm_sprd_bo_get_flags (tbm_bo bo)
1808 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1810 tbm_bo_sprd bo_sprd;
1812 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1813 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1815 return bo_sprd->flags_tbm;
1819 tbm_sprd_bufmgr_bind_native_display (tbm_bufmgr bufmgr, void *NativeDisplay)
1821 tbm_bufmgr_sprd bufmgr_sprd;
1823 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1824 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1826 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1827 bufmgr_sprd->device_name, 0)) {
1828 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1832 bufmgr_sprd->bind_display = NativeDisplay;
1837 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1839 static TBMModuleVersionInfo SprdVersRec = {
1845 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1848 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1850 tbm_bufmgr_sprd bufmgr_sprd;
1851 tbm_bufmgr_backend bufmgr_backend;
1856 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1858 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1862 if (tbm_backend_is_display_server()) {
1865 bufmgr_sprd->fd = -1;
1866 master_fd = tbm_drm_helper_get_master_fd();
1867 if (master_fd < 0) {
1868 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1869 tbm_drm_helper_set_master_fd(bufmgr_sprd->fd);
1871 bufmgr_sprd->fd = dup(master_fd);
1874 if (bufmgr_sprd->fd < 0) {
1875 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1880 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1882 if (!bufmgr_sprd->device_name)
1884 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1890 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1891 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1897 /* open tgl fd for saving cache flush data */
1898 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
1900 if (bufmgr_sprd->tgl_fd < 0) {
1901 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
1902 if (bufmgr_sprd->tgl_fd < 0) {
1903 TBM_SPRD_LOG("[libtbm:%d] "
1904 "error: Fail to open global_lock:%s\n",
1905 getpid(), tgl_devfile);
1907 close(bufmgr_sprd->fd);
1913 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
1914 TBM_SPRD_LOG("[libtbm:%d] "
1915 "error: Fail to initialize the tgl\n",
1918 close(bufmgr_sprd->fd);
1919 close(bufmgr_sprd->tgl_fd);
1926 bufmgr_sprd->hashBos = drmHashCreate ();
1928 //Check if the tbm manager supports dma fence or not.
1929 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1933 length = read(fp, buf, 1);
1935 if (length == 1 && buf[0] == '1')
1936 bufmgr_sprd->use_dma_fence = 1;
1941 bufmgr_backend = tbm_backend_alloc();
1942 if (!bufmgr_backend) {
1943 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1945 close(bufmgr_sprd->fd);
1946 close(bufmgr_sprd->tgl_fd);
1952 bufmgr_backend->priv = (void *)bufmgr_sprd;
1953 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1954 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1955 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1956 bufmgr_backend->bo_free = tbm_sprd_bo_free;
1957 bufmgr_backend->bo_import = tbm_sprd_bo_import;
1958 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1959 bufmgr_backend->bo_export = tbm_sprd_bo_export;
1960 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1961 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1962 bufmgr_backend->bo_map = tbm_sprd_bo_map;
1963 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1964 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1965 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1966 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1967 bufmgr_backend->bo_lock = NULL;
1968 bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1969 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1970 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1972 bufmgr_backend->flags |= TBM_LOCK_CTRL_BACKEND;
1973 bufmgr_backend->flags |= TBM_USE_2_0_BACKEND;
1975 if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
1976 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1977 tbm_backend_free (bufmgr_backend);
1979 close(bufmgr_sprd->tgl_fd);
1980 close(bufmgr_sprd->fd);
1989 env = getenv ("TBM_SPRD_DEBUG");
1991 bDebug = atoi (env);
1992 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1999 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
2000 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2002 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2003 __FUNCTION__, bufmgr_sprd->fd);