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;
376 fd = drmOpen(SPRD_DRM_NAME, NULL);
378 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
379 "warning %s:%d fail to open drm\n",
380 getpid(), __FUNCTION__, __LINE__);
385 struct udev *udev = NULL;
386 struct udev_enumerate *e = NULL;
387 struct udev_list_entry *entry = NULL;
388 struct udev_device *device = NULL, *drm_device = NULL, *device_parent = NULL;
389 const char *filepath;
394 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
395 "%s:%d search drm-device by udev\n",
396 getpid(), __FUNCTION__, __LINE__);
400 TBM_SPRD_LOG("udev_new() failed.\n");
404 e = udev_enumerate_new(udev);
405 udev_enumerate_add_match_subsystem(e, "drm");
406 udev_enumerate_add_match_sysname(e, "card[0-9]*");
407 udev_enumerate_scan_devices(e);
409 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
410 device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
411 udev_list_entry_get_name(entry));
412 device_parent = udev_device_get_parent(device);
413 /* Not need unref device_parent. device_parent and device have same refcnt */
415 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
417 DBG("[%s] Found render device: '%s' (%s)\n",
419 udev_device_get_syspath(drm_device),
420 udev_device_get_sysname(device_parent));
424 udev_device_unref(device);
427 udev_enumerate_unref(e);
429 /* Get device file path. */
430 filepath = udev_device_get_devnode(drm_device);
432 TBM_SPRD_LOG("udev_device_get_devnode() failed.\n");
433 udev_device_unref(drm_device);
438 /* Open DRM device file and check validity. */
439 fd = open(filepath, O_RDWR | O_CLOEXEC);
441 TBM_SPRD_LOG("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
442 udev_device_unref(drm_device);
449 TBM_SPRD_LOG("fstat() failed %s.\n");
450 udev_device_unref(drm_device);
455 udev_device_unref(drm_device);
465 _sprd_bo_cache_flush (tbm_bo bo, int flags)
467 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
468 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
470 /* cache flush is managed by kernel side when using dma-fence. */
471 if (bufmgr_sprd->use_dma_fence)
474 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
478 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
479 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
482 struct drm_sprd_gem_cache_op cache_op = {0, };
485 /* if bo_sprd is null, do cache_flush_all */
488 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
489 cache_op.size = bo_sprd->size;
491 flags = TBM_SPRD_CACHE_FLUSH_ALL;
493 cache_op.usr_addr = 0;
497 if (flags & TBM_SPRD_CACHE_INV) {
498 if (flags & TBM_SPRD_CACHE_ALL)
499 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
501 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
504 if (flags & TBM_SPRD_CACHE_CLN) {
505 if (flags & TBM_SPRD_CACHE_ALL)
506 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
508 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
511 if (flags & TBM_SPRD_CACHE_ALL)
512 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
514 ret = drmCommandWriteRead (bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
517 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
518 "error %s:%d fail to flush the cache.\n",
519 getpid(), __FUNCTION__, __LINE__);
528 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
530 tbm_bo_cache_state cache_state;
532 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
533 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
535 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
537 cache_state.data.isDirtied = DEVICE_NONE;
538 cache_state.data.isCached = 0;
539 cache_state.data.cntFlush = 0;
541 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
547 _bo_set_cache_state(tbm_bo bo, int device, int opt)
550 tbm_bufmgr_sprd bufmgr_sprd;
552 unsigned short cntFlush = 0;
554 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
555 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
557 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
558 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
560 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
563 /* get cache state of a bo */
564 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
566 /* get global cache flush count */
567 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
569 if (opt == TBM_DEVICE_CPU) {
570 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
571 bo_sprd->cache_state.data.isCached)
572 need_flush = TBM_SPRD_CACHE_INV;
574 bo_sprd->cache_state.data.isCached = 1;
575 if (opt & TBM_OPTION_WRITE)
576 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
578 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
579 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
582 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
583 bo_sprd->cache_state.data.isCached &&
584 bo_sprd->cache_state.data.cntFlush == cntFlush)
585 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
587 if (opt & TBM_OPTION_WRITE)
588 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
590 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
591 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
596 if (need_flush & TBM_SPRD_CACHE_ALL)
597 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
599 /* call cache flush */
600 _sprd_bo_cache_flush (bo, need_flush);
602 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
604 bo_sprd->cache_state.data.isCached,
605 bo_sprd->cache_state.data.isDirtied,
614 _bo_save_cache_state(tbm_bo bo)
616 unsigned short cntFlush = 0;
618 tbm_bufmgr_sprd bufmgr_sprd;
620 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
621 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
623 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
624 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
626 /* get global cache flush count */
627 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
629 /* save global cache flush count */
630 bo_sprd->cache_state.data.cntFlush = cntFlush;
631 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
637 _bo_destroy_cache_state(tbm_bo bo)
640 tbm_bufmgr_sprd bufmgr_sprd;
642 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
643 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
645 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
646 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
648 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
651 #ifndef USE_CONTIG_ONLY
653 _get_sprd_flag_from_tbm (unsigned int ftbm)
655 unsigned int flags = 0;
658 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
659 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
660 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
661 * To be updated appropriately once DRM-GEM supports different heap id masks.
664 if (ftbm & TBM_BO_SCANOUT) {
665 flags = SPRD_BO_CONTIG;
667 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
670 if (ftbm & TBM_BO_WC)
672 else if (ftbm & TBM_BO_NONCACHABLE)
673 flags |= SPRD_BO_NONCACHABLE;
679 _get_tbm_flag_from_sprd (unsigned int fsprd)
681 unsigned int flags = 0;
683 if (fsprd & SPRD_BO_NONCONTIG)
684 flags |= TBM_BO_DEFAULT;
686 flags |= TBM_BO_SCANOUT;
688 if (fsprd & SPRD_BO_WC)
690 else if (fsprd & SPRD_BO_CACHABLE)
691 flags |= TBM_BO_DEFAULT;
693 flags |= TBM_BO_NONCACHABLE;
700 _get_name (int fd, unsigned int gem)
702 struct drm_gem_flink arg = {0,};
705 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
706 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
707 "error %s:%d fail to get flink gem=%d\n",
708 getpid(), __FUNCTION__, __LINE__, gem);
712 return (unsigned int)arg.name;
716 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
718 tbm_bo_handle bo_handle;
719 memset (&bo_handle, 0x0, sizeof (uint64_t));
722 case TBM_DEVICE_DEFAULT:
724 bo_handle.u32 = (uint32_t)bo_sprd->gem;
727 if (!bo_sprd->pBase) {
728 struct drm_sprd_gem_mmap arg = {0,};
730 arg.handle = bo_sprd->gem;
731 arg.size = bo_sprd->size;
732 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
733 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
734 "error %s:%d Cannot usrptr gem=%d\n",
735 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
736 return (tbm_bo_handle) NULL;
738 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
741 bo_handle.ptr = (void *)bo_sprd->pBase;
745 if (!bo_sprd->dmabuf) {
746 struct drm_prime_handle arg = {0, };
747 arg.handle = bo_sprd->gem;
748 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
749 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
750 "error %s:%d Cannot dmabuf=%d\n",
751 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
752 return (tbm_bo_handle) NULL;
754 bo_sprd->dmabuf = arg.fd;
757 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
764 //TODO : Add ioctl for GSP MAP once available.
765 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
770 if (!bo_sprd->dmabuf) {
771 struct drm_prime_handle arg = {0, };
773 arg.handle = bo_sprd->gem;
774 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
775 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
776 "error %s:%d Cannot dmabuf=%d\n",
777 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
778 return (tbm_bo_handle) NULL;
780 bo_sprd->dmabuf = arg.fd;
783 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
787 bo_handle.ptr = (void *) NULL;
795 tbm_sprd_bo_size (tbm_bo bo)
797 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
801 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
803 return bo_sprd->size;
807 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
809 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
812 tbm_bufmgr_sprd bufmgr_sprd;
813 unsigned int sprd_flags;
815 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
816 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
818 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
820 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
821 "error %s:%d fail to allocate the bo private\n",
822 getpid(), __FUNCTION__, __LINE__);
826 #ifdef USE_CONTIG_ONLY
827 flags = TBM_BO_SCANOUT;
828 sprd_flags = SPRD_BO_CONTIG;
830 sprd_flags = _get_sprd_flag_from_tbm (flags);
831 if ((flags & TBM_BO_SCANOUT) &&
833 sprd_flags |= SPRD_BO_NONCONTIG;
835 #endif // USE_CONTIG_ONLY
836 struct drm_sprd_gem_create arg = {0, };
838 arg.flags = sprd_flags;
839 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
841 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
842 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
843 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
848 bo_sprd->fd = bufmgr_sprd->fd;
849 bo_sprd->gem = arg.handle;
850 bo_sprd->size = size;
851 bo_sprd->flags_tbm = flags;
852 bo_sprd->flags_sprd = sprd_flags;
853 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
855 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd)) {
856 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
861 pthread_mutex_init(&bo_sprd->mutex, NULL);
863 if (bufmgr_sprd->use_dma_fence
864 && !bo_sprd->dmabuf) {
865 struct drm_prime_handle arg = {0, };
867 arg.handle = bo_sprd->gem;
868 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
869 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
870 "error %s:%d Cannot dmabuf=%d\n",
871 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
875 bo_sprd->dmabuf = arg.fd;
879 PrivGem *privGem = calloc (1, sizeof(PrivGem));
880 privGem->ref_count = 1;
881 privGem->bo_priv = bo_sprd;
882 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
883 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
884 "error %s:%d Cannot insert bo to Hash(%d)\n",
885 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
888 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
889 __FUNCTION__, bo_sprd->size,
890 bo_sprd->gem, bo_sprd->name,
893 return (void *)bo_sprd;
897 tbm_sprd_bo_free(tbm_bo bo)
900 tbm_bufmgr_sprd bufmgr_sprd;
905 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
906 SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
908 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
909 SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
911 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
912 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
914 if (bo_sprd->pBase) {
915 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
916 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
918 getpid(), __FUNCTION__, __LINE__);
923 if (bo_sprd->dmabuf) {
924 close (bo_sprd->dmabuf);
928 /* delete bo from hash */
929 PrivGem *privGem = NULL;
932 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
934 privGem->ref_count--;
935 if (privGem->ref_count == 0) {
936 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
941 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
942 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
943 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
946 _bo_destroy_cache_state(bo);
948 /* Free gem handle */
949 struct drm_gem_close arg = {0, };
950 memset (&arg, 0, sizeof(arg));
951 arg.handle = bo_sprd->gem;
952 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
953 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
955 getpid(), __FUNCTION__, __LINE__);
963 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
965 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
967 tbm_bufmgr_sprd bufmgr_sprd;
969 PrivGem *privGem = NULL;
972 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
973 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
975 ret = drmHashLookup (bufmgr_sprd->hashBos, key, (void **)&privGem);
977 privGem->ref_count++;
978 return privGem->bo_priv;
981 struct drm_gem_open arg = {0, };
982 struct drm_sprd_gem_info info = {0, };
985 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
986 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
987 "error %s:%d Cannot open gem name=%d\n",
988 getpid(), __FUNCTION__, __LINE__, key);
992 info.handle = arg.handle;
993 if (drmCommandWriteRead(bufmgr_sprd->fd,
996 sizeof(struct drm_sprd_gem_info))) {
997 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
998 "error %s:%d Cannot get gem info=%d\n",
999 getpid(), __FUNCTION__, __LINE__, key);
1003 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1005 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1006 "error %s:%d fail to allocate the bo private\n",
1007 getpid(), __FUNCTION__, __LINE__);
1011 bo_sprd->fd = bufmgr_sprd->fd;
1012 bo_sprd->gem = arg.handle;
1013 bo_sprd->size = arg.size;
1014 bo_sprd->flags_sprd = info.flags;
1015 bo_sprd->name = key;
1016 #ifdef USE_CONTIG_ONLY
1017 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1018 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1020 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1023 if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
1024 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
1029 if (!bo_sprd->dmabuf) {
1030 struct drm_prime_handle arg = {0, };
1032 arg.handle = bo_sprd->gem;
1033 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1034 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1035 "error %s:%d Cannot dmabuf=%d\n",
1036 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1040 bo_sprd->dmabuf = arg.fd;
1043 /* add bo to hash */
1044 privGem = calloc (1, sizeof(PrivGem));
1045 privGem->ref_count = 1;
1046 privGem->bo_priv = bo_sprd;
1047 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1048 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1049 "error %s:%d Cannot insert bo to Hash(%d)\n",
1050 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1053 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1054 __FUNCTION__, bo_sprd->size,
1055 bo_sprd->gem, bo_sprd->name,
1056 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1058 return (void *)bo_sprd;
1062 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
1064 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1066 tbm_bufmgr_sprd bufmgr_sprd;
1067 tbm_bo_sprd bo_sprd;
1068 PrivGem *privGem = NULL;
1072 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1073 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1075 //getting handle from fd
1076 unsigned int gem = 0;
1077 struct drm_prime_handle arg = {0, };
1081 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1082 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1083 bo, arg.fd, strerror(errno));
1088 name = _get_name (bufmgr_sprd->fd, gem);
1090 ret = drmHashLookup (bufmgr_sprd->hashBos, name, (void **)&privGem);
1092 if (gem == privGem->bo_priv->gem) {
1093 privGem->ref_count++;
1094 return privGem->bo_priv;
1098 unsigned int real_size = -1;
1099 struct drm_sprd_gem_info info = {0, };
1101 /* Determine size of bo. The fd-to-handle ioctl really should
1102 * return the size, but it doesn't. If we have kernel 3.12 or
1103 * later, we can lseek on the prime fd to get the size. Older
1104 * kernels will just fail, in which case we fall back to the
1105 * provided (estimated or guess size). */
1106 real_size = lseek(key, 0, SEEK_END);
1109 if (drmCommandWriteRead(bufmgr_sprd->fd,
1112 sizeof(struct drm_sprd_gem_info))) {
1113 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1114 bo, gem, key, strerror(errno));
1118 if (real_size == -1)
1119 real_size = info.size;
1121 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1123 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
1127 bo_sprd->fd = bufmgr_sprd->fd;
1129 bo_sprd->size = real_size;
1130 bo_sprd->flags_sprd = info.flags;
1131 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1133 bo_sprd->name = name;
1134 if (!bo_sprd->name) {
1135 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1136 bo, gem, key, strerror(errno));
1141 if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
1142 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
1147 /* add bo to hash */
1150 privGem = calloc (1, sizeof(PrivGem));
1152 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1153 "error %s:%d Fail to calloc privGem\n",
1154 getpid(), __FUNCTION__, __LINE__);
1159 privGem->ref_count = 1;
1160 privGem->bo_priv = bo_sprd;
1161 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1162 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1163 bo, bo_sprd->name, gem, key);
1166 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1169 bo_sprd->gem, bo_sprd->name,
1172 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1175 return (void *)bo_sprd;
1179 tbm_sprd_bo_export (tbm_bo bo)
1181 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1183 tbm_bo_sprd bo_sprd;
1185 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1186 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1188 if (!bo_sprd->name) {
1189 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1190 if (!bo_sprd->name) {
1191 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1192 "error %s:%d Cannot get name\n",
1193 getpid(), __FUNCTION__, __LINE__);
1198 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1199 __FUNCTION__, bo_sprd->size,
1200 bo_sprd->gem, bo_sprd->name,
1201 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1203 return (unsigned int)bo_sprd->name;
1207 tbm_sprd_bo_export_fd (tbm_bo bo)
1209 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, -1);
1211 tbm_bo_sprd bo_sprd;
1214 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1215 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, -1);
1217 struct drm_prime_handle arg = {0, };
1219 arg.handle = bo_sprd->gem;
1220 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1222 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
1223 bo, bo_sprd->gem, strerror(errno));
1224 return (tbm_fd) ret;
1227 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1230 bo_sprd->gem, bo_sprd->name,
1233 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1236 return (tbm_fd)arg.fd;
1240 static tbm_bo_handle
1241 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
1243 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1245 tbm_bo_handle bo_handle;
1246 tbm_bo_sprd bo_sprd;
1248 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1249 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1251 if (!bo_sprd->gem) {
1252 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1253 "error %s:%d Cannot map gem=%d\n",
1254 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1255 return (tbm_bo_handle) NULL;
1258 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1259 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1261 /*Get mapped bo_handle*/
1262 bo_handle = _sprd_bo_handle (bo_sprd, device);
1263 if (bo_handle.ptr == NULL) {
1264 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1265 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1266 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1267 return (tbm_bo_handle) NULL;
1273 static tbm_bo_handle
1274 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
1276 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1278 tbm_bo_handle bo_handle;
1279 tbm_bo_sprd bo_sprd;
1281 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1282 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1284 if (!bo_sprd->gem) {
1285 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1286 "error %s:%d Cannot map gem=%d\n",
1287 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1288 return (tbm_bo_handle) NULL;
1291 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1292 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1294 /*Get mapped bo_handle*/
1295 bo_handle = _sprd_bo_handle (bo_sprd, device);
1296 if (bo_handle.ptr == NULL) {
1297 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1298 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1299 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1300 return (tbm_bo_handle) NULL;
1303 if (bo_sprd->map_cnt == 0)
1304 _bo_set_cache_state (bo, device, opt);
1312 tbm_sprd_bo_unmap (tbm_bo bo)
1314 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1316 tbm_bo_sprd bo_sprd;
1318 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1319 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1326 if (bo_sprd->map_cnt == 0)
1327 _bo_save_cache_state (bo);
1329 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1330 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1336 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1338 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1340 #if USE_BACKEND_LOCK
1341 tbm_bufmgr_sprd bufmgr_sprd;
1342 tbm_bo_sprd bo_sprd;
1345 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1346 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1348 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1349 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1351 if (bufmgr_sprd->use_dma_fence) {
1352 struct dma_buf_fence fence;
1354 memset(&fence, 0, sizeof(struct dma_buf_fence));
1356 /* Check if the given type is valid or not. */
1357 if (opt & TBM_OPTION_WRITE) {
1358 if (device == TBM_DEVICE_CPU)
1359 fence.type = DMA_BUF_ACCESS_WRITE;
1360 else if (device == TBM_DEVICE_3D)
1361 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1363 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1364 getpid(), __FUNCTION__);
1367 } else if (opt & TBM_OPTION_READ) {
1368 if (device == TBM_DEVICE_CPU)
1369 fence.type = DMA_BUF_ACCESS_READ;
1370 else if (device == TBM_DEVICE_3D)
1371 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1373 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1374 getpid(), __FUNCTION__);
1378 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1379 __FUNCTION__, __LINE__);
1383 /* Check if the tbm manager supports dma fence or not. */
1384 if (!bufmgr_sprd->use_dma_fence) {
1385 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1386 "error %s:%d Not support DMA FENCE(%s)\n",
1387 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1392 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1394 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1395 "error %s:%d Can not set GET FENCE(%s)\n",
1396 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1400 pthread_mutex_lock(&bo_sprd->mutex);
1402 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1403 if (bo_sprd->dma_fence[i].ctx == 0) {
1404 bo_sprd->dma_fence[i].type = fence.type;
1405 bo_sprd->dma_fence[i].ctx = fence.ctx;
1409 if (i == DMA_FENCE_LIST_MAX) {
1410 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1411 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1412 "error %s:%d fence list is full\n",
1413 getpid(), __FUNCTION__, __LINE__);
1415 pthread_mutex_unlock(&bo_sprd->mutex);
1417 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1419 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1421 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1423 DBG ("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1424 getpid(), __FUNCTION__, bo_sprd->name);
1434 tbm_sprd_bo_unlock(tbm_bo bo)
1436 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1438 #if USE_BACKEND_LOCK
1439 tbm_bufmgr_sprd bufmgr_sprd;
1440 tbm_bo_sprd bo_sprd;
1443 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1444 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1446 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1447 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1449 if (bufmgr_sprd->use_dma_fence) {
1450 struct dma_buf_fence fence;
1452 if (!bo_sprd->dma_fence[0].ctx) {
1453 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1458 if (!bo_sprd->dma_fence[0].type) {
1459 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1464 pthread_mutex_lock(&bo_sprd->mutex);
1465 fence.type = bo_sprd->dma_fence[0].type;
1466 fence.ctx = bo_sprd->dma_fence[0].ctx;
1468 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1469 bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1470 bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1472 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1473 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1474 pthread_mutex_unlock(&bo_sprd->mutex);
1476 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1478 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1479 "error %s:%d Can not set PUT FENCE(%s)\n",
1480 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1484 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1486 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1488 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1490 DBG ("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1491 getpid(), __FUNCTION__, bo_sprd->name);
1500 tbm_sprd_bufmgr_deinit (void *priv)
1502 SPRD_RETURN_IF_FAIL (priv != NULL);
1504 tbm_bufmgr_sprd bufmgr_sprd;
1506 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1508 if (bufmgr_sprd->hashBos) {
1512 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1514 drmHashDelete (bufmgr_sprd->hashBos, key);
1517 drmHashDestroy (bufmgr_sprd->hashBos);
1518 bufmgr_sprd->hashBos = NULL;
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->tgl_fd);
1528 close (bufmgr_sprd->fd);
1534 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1536 uint32_t *color_formats = NULL;
1538 color_formats = (uint32_t *)calloc (1,
1539 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1541 if ( color_formats == NULL ) {
1544 memcpy( color_formats, tbm_sprd_color_format_list ,
1545 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1548 *formats = color_formats;
1549 *num = TBM_COLOR_FORMAT_COUNT;
1557 * @brief get the plane data of the surface.
1558 * @param[in] surface : the surface
1559 * @param[in] width : the width of the surface
1560 * @param[in] height : the height of the surface
1561 * @param[in] format : the format of the surface
1562 * @param[in] plane_idx : the format of the surface
1563 * @param[out] size : the size of the plane
1564 * @param[out] offset : the offset of the plane
1565 * @param[out] pitch : the pitch of the plane
1566 * @param[out] padding : the padding of the plane
1567 * @return 1 if this function succeeds, otherwise 0.
1570 tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height,
1571 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1572 uint32_t *pitch, int *bo_idx)
1583 case TBM_FORMAT_XRGB4444:
1584 case TBM_FORMAT_XBGR4444:
1585 case TBM_FORMAT_RGBX4444:
1586 case TBM_FORMAT_BGRX4444:
1587 case TBM_FORMAT_ARGB4444:
1588 case TBM_FORMAT_ABGR4444:
1589 case TBM_FORMAT_RGBA4444:
1590 case TBM_FORMAT_BGRA4444:
1591 case TBM_FORMAT_XRGB1555:
1592 case TBM_FORMAT_XBGR1555:
1593 case TBM_FORMAT_RGBX5551:
1594 case TBM_FORMAT_BGRX5551:
1595 case TBM_FORMAT_ARGB1555:
1596 case TBM_FORMAT_ABGR1555:
1597 case TBM_FORMAT_RGBA5551:
1598 case TBM_FORMAT_BGRA5551:
1599 case TBM_FORMAT_RGB565:
1602 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1603 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1607 case TBM_FORMAT_RGB888:
1608 case TBM_FORMAT_BGR888:
1611 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1612 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1616 case TBM_FORMAT_XRGB8888:
1617 case TBM_FORMAT_XBGR8888:
1618 case TBM_FORMAT_RGBX8888:
1619 case TBM_FORMAT_BGRX8888:
1620 case TBM_FORMAT_ARGB8888:
1621 case TBM_FORMAT_ABGR8888:
1622 case TBM_FORMAT_RGBA8888:
1623 case TBM_FORMAT_BGRA8888:
1626 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1627 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1632 case TBM_FORMAT_YUYV:
1633 case TBM_FORMAT_YVYU:
1634 case TBM_FORMAT_UYVY:
1635 case TBM_FORMAT_VYUY:
1636 case TBM_FORMAT_AYUV:
1639 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1640 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1646 * index 0 = Y plane, [7:0] Y
1647 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1649 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1651 case TBM_FORMAT_NV12:
1652 case TBM_FORMAT_NV21:
1654 if (plane_idx == 0) {
1656 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1657 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1659 } else if ( plane_idx == 1 ) {
1660 _offset = width * height;
1661 _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1662 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1667 case TBM_FORMAT_NV16:
1668 case TBM_FORMAT_NV61:
1670 //if(plane_idx == 0)
1673 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1674 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1679 //else if( plane_idx ==1 )
1682 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1683 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1690 * index 0: Y plane, [7:0] Y
1691 * index 1: Cb plane, [7:0] Cb
1692 * index 2: Cr plane, [7:0] Cr
1694 * index 1: Cr plane, [7:0] Cr
1695 * index 2: Cb plane, [7:0] Cb
1698 NATIVE_BUFFER_FORMAT_YV12
1699 NATIVE_BUFFER_FORMAT_I420
1701 case TBM_FORMAT_YUV410:
1702 case TBM_FORMAT_YVU410:
1705 case TBM_FORMAT_YUV411:
1706 case TBM_FORMAT_YVU411:
1707 case TBM_FORMAT_YUV420:
1708 case TBM_FORMAT_YVU420:
1710 //if(plane_idx == 0)
1713 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1714 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1719 //else if( plane_idx == 1 )
1722 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1723 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1728 //else if (plane_idx == 2 )
1731 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1732 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1736 case TBM_FORMAT_YUV422:
1737 case TBM_FORMAT_YVU422:
1739 //if(plane_idx == 0)
1742 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1743 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1748 //else if( plane_idx == 1 )
1751 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1752 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1757 //else if (plane_idx == 2 )
1760 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1761 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1765 case TBM_FORMAT_YUV444:
1766 case TBM_FORMAT_YVU444:
1768 //if(plane_idx == 0)
1771 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1772 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1777 //else if( plane_idx == 1 )
1780 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1781 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1786 //else if (plane_idx == 2 )
1789 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1790 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1808 tbm_sprd_bo_get_flags (tbm_bo bo)
1810 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1812 tbm_bo_sprd bo_sprd;
1814 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1815 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1817 return bo_sprd->flags_tbm;
1821 tbm_sprd_bufmgr_bind_native_display (tbm_bufmgr bufmgr, void *NativeDisplay)
1823 tbm_bufmgr_sprd bufmgr_sprd;
1825 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1826 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1828 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1829 bufmgr_sprd->device_name, 0)) {
1830 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1834 bufmgr_sprd->bind_display = NativeDisplay;
1839 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1841 static TBMModuleVersionInfo SprdVersRec = {
1847 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1850 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1852 tbm_bufmgr_sprd bufmgr_sprd;
1853 tbm_bufmgr_backend bufmgr_backend;
1858 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1860 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1864 if (tbm_backend_is_display_server()) {
1866 /* this code is applied with libtdm-sprd */
1869 bufmgr_sprd->fd = -1;
1870 master_fd = tbm_drm_helper_get_master_fd();
1871 if (master_fd < 0) {
1872 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1873 tbm_drm_helper_set_master_fd(bufmgr_sprd->fd);
1875 bufmgr_sprd->fd = dup(master_fd);
1878 bufmgr_sprd->fd = dup(fd);
1881 if (bufmgr_sprd->fd < 0) {
1882 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1887 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1889 if (!bufmgr_sprd->device_name)
1891 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1897 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1898 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1904 /* open tgl fd for saving cache flush data */
1905 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
1907 if (bufmgr_sprd->tgl_fd < 0) {
1908 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
1909 if (bufmgr_sprd->tgl_fd < 0) {
1910 TBM_SPRD_LOG("[libtbm:%d] "
1911 "error: Fail to open global_lock:%s\n",
1912 getpid(), tgl_devfile);
1914 close(bufmgr_sprd->fd);
1920 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
1921 TBM_SPRD_LOG("[libtbm:%d] "
1922 "error: Fail to initialize the tgl\n",
1925 close(bufmgr_sprd->fd);
1926 close(bufmgr_sprd->tgl_fd);
1933 bufmgr_sprd->hashBos = drmHashCreate ();
1935 //Check if the tbm manager supports dma fence or not.
1936 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1940 length = read(fp, buf, 1);
1942 if (length == 1 && buf[0] == '1')
1943 bufmgr_sprd->use_dma_fence = 1;
1948 bufmgr_backend = tbm_backend_alloc();
1949 if (!bufmgr_backend) {
1950 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1952 close(bufmgr_sprd->fd);
1953 close(bufmgr_sprd->tgl_fd);
1959 bufmgr_backend->priv = (void *)bufmgr_sprd;
1960 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1961 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1962 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1963 bufmgr_backend->bo_free = tbm_sprd_bo_free;
1964 bufmgr_backend->bo_import = tbm_sprd_bo_import;
1965 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1966 bufmgr_backend->bo_export = tbm_sprd_bo_export;
1967 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1968 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1969 bufmgr_backend->bo_map = tbm_sprd_bo_map;
1970 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1971 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1972 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1973 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1974 bufmgr_backend->bo_lock = NULL;
1975 bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1976 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1977 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1979 bufmgr_backend->flags |= TBM_LOCK_CTRL_BACKEND;
1980 bufmgr_backend->flags |= TBM_USE_2_0_BACKEND;
1982 if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
1983 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1984 tbm_backend_free (bufmgr_backend);
1986 close(bufmgr_sprd->tgl_fd);
1987 close(bufmgr_sprd->fd);
1996 env = getenv ("TBM_SPRD_DEBUG");
1998 bDebug = atoi (env);
1999 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
2006 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
2007 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2009 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2010 __FUNCTION__, bufmgr_sprd->fd);