1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
39 #include <sys/ioctl.h>
40 #include <sys/types.h>
47 #include <tbm_bufmgr.h>
48 #include <tbm_bufmgr_backend.h>
49 #include <drm/sprd_drm.h>
51 #include <tbm_surface.h>
55 //#define USE_CONTIG_ONLY
58 #define TBM_COLOR_FORMAT_COUNT 8
63 #define LOG_TAG "TBM_BACKEND"
71 static int initialized = 0;
72 static char app_name[128];
77 /* get the application name */
78 f = fopen("/proc/self/cmdline", "r");
85 memset(app_name, 0x00, sizeof(app_name));
87 if ( fgets(app_name, 100, f) == NULL )
95 if ( (slash=strrchr(app_name, '/')) != NULL )
97 memmove(app_name, slash+1, strlen(slash));
104 #define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args)
105 #define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args)
107 #define TBM_SPRD_LOG(...)
111 #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
113 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
114 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128)
115 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
118 /* check condition */
119 #define SPRD_RETURN_IF_FAIL(cond) {\
121 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
125 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
127 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
132 struct dma_buf_info {
134 unsigned int fence_supported;
135 unsigned int padding;
138 #define DMA_BUF_ACCESS_READ 0x1
139 #define DMA_BUF_ACCESS_WRITE 0x2
140 #define DMA_BUF_ACCESS_DMA 0x4
141 #define DMA_BUF_ACCESS_MAX 0x8
143 #define DMA_FENCE_LIST_MAX 5
145 struct dma_buf_fence {
150 #define DMABUF_IOCTL_BASE 'F'
151 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
153 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
154 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
155 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
157 typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd;
158 typedef struct _tbm_bo_sprd *tbm_bo_sprd;
160 typedef struct _sprd_private
165 /* tbm buffor object for sprd */
170 unsigned int name; /* FLINK ID */
172 unsigned int gem; /* GEM Handle */
174 unsigned int dmabuf; /* fd for dmabuf */
176 void *pBase; /* virtual address */
180 unsigned int flags_sprd;
181 unsigned int flags_tbm;
185 pthread_mutex_t mutex;
186 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
191 /* tbm bufmgr private for sprd */
192 struct _tbm_bufmgr_sprd
218 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
228 #ifndef USE_CONTIG_ONLY
230 _get_sprd_flag_from_tbm (unsigned int ftbm)
232 unsigned int flags = 0;
235 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
236 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
237 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
238 * To be updated appropriately once DRM-GEM supports different heap id masks.
241 if (ftbm & TBM_BO_SCANOUT)
243 flags = SPRD_BO_CONTIG;
247 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
250 if (ftbm & TBM_BO_WC)
252 else if (ftbm & TBM_BO_NONCACHABLE)
253 flags |= SPRD_BO_NONCACHABLE;
259 _get_tbm_flag_from_sprd (unsigned int fsprd)
261 unsigned int flags = 0;
263 if (fsprd & SPRD_BO_NONCONTIG)
264 flags |= TBM_BO_DEFAULT;
266 flags |= TBM_BO_SCANOUT;
268 if (fsprd & SPRD_BO_WC)
270 else if (fsprd & SPRD_BO_CACHABLE)
271 flags |= TBM_BO_DEFAULT;
273 flags |= TBM_BO_NONCACHABLE;
280 _get_name (int fd, unsigned int gem)
282 struct drm_gem_flink arg = {0,};
285 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg))
287 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
288 "error %s:%d fail to get flink gem=%d\n",
289 getpid(), __FUNCTION__, __LINE__, gem);
293 return (unsigned int)arg.name;
297 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
299 tbm_bo_handle bo_handle;
300 memset (&bo_handle, 0x0, sizeof (uint64_t));
304 case TBM_DEVICE_DEFAULT:
306 bo_handle.u32 = (uint32_t)bo_sprd->gem;
311 struct drm_sprd_gem_mmap arg = {0,};
313 arg.handle = bo_sprd->gem;
314 arg.size = bo_sprd->size;
315 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg)))
317 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
318 "error %s:%d Cannot usrptr gem=%d\n",
319 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
320 return (tbm_bo_handle) NULL;
322 bo_sprd->pBase = (void*)((uint32_t)arg.mapped);
325 bo_handle.ptr = (void *)bo_sprd->pBase;
329 if (!bo_sprd->dmabuf)
331 struct drm_prime_handle arg = {0, };
332 arg.handle = bo_sprd->gem;
333 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
335 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
336 "error %s:%d Cannot dmabuf=%d\n",
337 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
338 return (tbm_bo_handle) NULL;
340 bo_sprd->dmabuf = arg.fd;
343 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
350 //TODO : Add ioctl for GSP MAP once available.
351 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
355 if (!bo_sprd->dmabuf)
357 struct drm_prime_handle arg = {0, };
359 arg.handle = bo_sprd->gem;
360 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
362 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
363 "error %s:%d Cannot dmabuf=%d\n",
364 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
365 return (tbm_bo_handle) NULL;
367 bo_sprd->dmabuf = arg.fd;
370 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
374 bo_handle.ptr = (void *) NULL;
383 _sprd_cache_flush (int fd, tbm_bo_sprd bo_sprd, int flags)
385 struct drm_sprd_gem_cache_op cache_op = {0, };
388 /* if bo_sprd is null, do cache_flush_all */
392 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
393 cache_op.size = bo_sprd->size;
397 flags = TBM_CACHE_FLUSH_ALL;
399 cache_op.usr_addr = 0;
403 if (flags & TBM_CACHE_INV)
405 if(flags & TBM_CACHE_ALL)
406 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
408 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
411 if (flags & TBM_CACHE_CLN)
413 if(flags & TBM_CACHE_ALL)
414 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
416 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
419 if(flags & TBM_CACHE_ALL)
420 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
422 ret = drmCommandWriteRead (fd, DRM_SPRD_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
425 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
426 "error %s:%d fail to flush the cache.\n",
427 getpid(), __FUNCTION__, __LINE__);
436 tbm_sprd_bo_size (tbm_bo bo)
438 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
442 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
444 return bo_sprd->size;
448 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
450 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
453 tbm_bufmgr_sprd bufmgr_sprd;
454 unsigned int sprd_flags;
456 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
457 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
459 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
462 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
463 "error %s:%d fail to allocate the bo private\n",
464 getpid(), __FUNCTION__, __LINE__);
468 #ifdef USE_CONTIG_ONLY
469 flags = TBM_BO_SCANOUT;
470 sprd_flags = SPRD_BO_CONTIG;
472 sprd_flags = _get_sprd_flag_from_tbm (flags);
473 if((flags & TBM_BO_SCANOUT) &&
476 sprd_flags |= SPRD_BO_NONCONTIG;
478 #endif // USE_CONTIG_ONLY
479 struct drm_sprd_gem_create arg = {0, };
481 arg.flags = sprd_flags;
482 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg, sizeof(arg)))
484 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
485 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
486 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
491 bo_sprd->fd = bufmgr_sprd->fd;
492 bo_sprd->gem = arg.handle;
493 bo_sprd->size = size;
494 bo_sprd->flags_tbm = flags;
495 bo_sprd->flags_sprd = sprd_flags;
496 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
498 pthread_mutex_init(&bo_sprd->mutex, NULL);
500 if (bufmgr_sprd->use_dma_fence
503 struct drm_prime_handle arg = {0, };
505 arg.handle = bo_sprd->gem;
506 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
508 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
509 "error %s:%d Cannot dmabuf=%d\n",
510 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
514 bo_sprd->dmabuf = arg.fd;
518 PrivGem* privGem = calloc (1, sizeof(PrivGem));
519 privGem->ref_count = 1;
520 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
522 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
523 "error %s:%d Cannot insert bo to Hash(%d)\n",
524 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
527 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
528 __FUNCTION__, bo_sprd->size,
529 bo_sprd->gem, bo_sprd->name,
532 return (void *)bo_sprd;
536 tbm_sprd_bo_free(tbm_bo bo)
539 tbm_bufmgr_sprd bufmgr_sprd;
544 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
545 SPRD_RETURN_IF_FAIL (bufmgr_sprd!=NULL);
547 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
548 SPRD_RETURN_IF_FAIL (bo_sprd!=NULL);
550 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
551 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
555 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1)
557 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
559 getpid(), __FUNCTION__, __LINE__);
566 close (bo_sprd->dmabuf);
570 /* delete bo from hash */
571 PrivGem *privGem = NULL;
574 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
577 privGem->ref_count--;
578 if (privGem->ref_count == 0)
580 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
587 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
588 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
589 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
592 /* Free gem handle */
593 struct drm_gem_close arg = {0, };
594 memset (&arg, 0, sizeof(arg));
595 arg.handle = bo_sprd->gem;
596 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg))
598 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
600 getpid(), __FUNCTION__, __LINE__);
608 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
610 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
612 tbm_bufmgr_sprd bufmgr_sprd;
615 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
616 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
618 struct drm_gem_open arg = {0, };
619 struct drm_sprd_gem_info info = {0, };
622 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg))
624 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
625 "error %s:%d Cannot open gem name=%d\n",
626 getpid(), __FUNCTION__, __LINE__, key);
630 info.handle = arg.handle;
631 if (drmCommandWriteRead(bufmgr_sprd->fd,
634 sizeof(struct drm_sprd_gem_info)))
636 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
637 "error %s:%d Cannot get gem info=%d\n",
638 getpid(), __FUNCTION__, __LINE__, key);
642 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
645 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
646 "error %s:%d fail to allocate the bo private\n",
647 getpid(), __FUNCTION__, __LINE__);
651 bo_sprd->fd = bufmgr_sprd->fd;
652 bo_sprd->gem = arg.handle;
653 bo_sprd->size = arg.size;
654 bo_sprd->flags_sprd = info.flags;
656 #ifdef USE_CONTIG_ONLY
657 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
658 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
660 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
664 if (!bo_sprd->dmabuf)
666 struct drm_prime_handle arg = {0, };
668 arg.handle = bo_sprd->gem;
669 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
671 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
672 "error %s:%d Cannot dmabuf=%d\n",
673 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
677 bo_sprd->dmabuf = arg.fd;
681 PrivGem *privGem = NULL;
684 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
687 privGem->ref_count++;
691 privGem = calloc (1, sizeof(PrivGem));
692 privGem->ref_count = 1;
693 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
695 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
696 "error %s:%d Cannot insert bo to Hash(%d)\n",
697 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
702 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
703 "error %s:%d Cannot insert bo to Hash(%d)\n",
704 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
707 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
708 __FUNCTION__, bo_sprd->size,
709 bo_sprd->gem, bo_sprd->name,
710 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
712 return (void *)bo_sprd;
716 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
718 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
720 tbm_bufmgr_sprd bufmgr_sprd;
723 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
724 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
726 unsigned int gem = 0;
727 unsigned int real_size = -1;
728 struct drm_sprd_gem_info info = {0, };
730 //getting handle from fd
731 struct drm_prime_handle arg = {0, };
735 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
737 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
738 bo, arg.fd, strerror(errno));
743 /* Determine size of bo. The fd-to-handle ioctl really should
744 * return the size, but it doesn't. If we have kernel 3.12 or
745 * later, we can lseek on the prime fd to get the size. Older
746 * kernels will just fail, in which case we fall back to the
747 * provided (estimated or guess size). */
748 real_size = lseek(key, 0, SEEK_END);
751 if (drmCommandWriteRead(bufmgr_sprd->fd,
754 sizeof(struct drm_sprd_gem_info)))
756 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
757 bo, gem, key, strerror(errno));
762 real_size = info.size;
764 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
767 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
771 bo_sprd->fd = bufmgr_sprd->fd;
773 bo_sprd->size = real_size;
774 bo_sprd->flags_sprd = info.flags;
775 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
777 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
780 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
781 bo, gem, key, strerror(errno));
787 PrivGem *privGem = NULL;
790 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
793 privGem->ref_count++;
797 privGem = calloc (1, sizeof(PrivGem));
800 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
801 "error %s:%d Fail to calloc privGem\n",
802 getpid(), __FUNCTION__, __LINE__);
807 privGem->ref_count = 1;
808 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
810 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
811 bo, bo_sprd->name, gem, key);
816 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
817 bo, bo_sprd->name, gem, key);
820 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
822 bo_sprd->gem, bo_sprd->name,
825 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
828 return (void *)bo_sprd;
832 tbm_sprd_bo_export (tbm_bo bo)
834 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
838 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
839 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
843 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
846 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
847 "error %s:%d Cannot get name\n",
848 getpid(), __FUNCTION__, __LINE__);
853 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
854 __FUNCTION__, bo_sprd->size,
855 bo_sprd->gem, bo_sprd->name,
856 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
858 return (unsigned int)bo_sprd->name;
862 tbm_sprd_bo_export_fd (tbm_bo bo)
864 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, -1);
869 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
870 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, -1);
872 struct drm_prime_handle arg = {0, };
874 arg.handle = bo_sprd->gem;
875 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
878 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
879 bo, bo_sprd->gem, strerror(errno));
883 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
885 bo_sprd->gem, bo_sprd->name,
888 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
891 return (tbm_fd)arg.fd;
896 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
898 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
900 tbm_bo_handle bo_handle;
903 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
904 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
908 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
909 "error %s:%d Cannot map gem=%d\n",
910 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
911 return (tbm_bo_handle) NULL;
914 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
915 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
917 /*Get mapped bo_handle*/
918 bo_handle = _sprd_bo_handle (bo_sprd, device);
919 if (bo_handle.ptr == NULL)
921 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
922 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
923 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
924 return (tbm_bo_handle) NULL;
931 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
933 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
935 tbm_bo_handle bo_handle;
938 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
939 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
943 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
944 "error %s:%d Cannot map gem=%d\n",
945 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
946 return (tbm_bo_handle) NULL;
949 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
950 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
952 /*Get mapped bo_handle*/
953 bo_handle = _sprd_bo_handle (bo_sprd, device);
954 if (bo_handle.ptr == NULL)
956 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
957 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
958 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
959 return (tbm_bo_handle) NULL;
966 tbm_sprd_bo_unmap (tbm_bo bo)
968 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
972 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
973 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
978 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
979 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
985 tbm_sprd_bo_cache_flush (tbm_bo bo, int flags)
987 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
988 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
990 /* cache flush is managed by kernel side when using dma-fence. */
991 if (bufmgr_sprd->use_dma_fence)
994 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
998 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
999 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1002 if (!_sprd_cache_flush(bo_sprd->fd, bo_sprd, flags))
1010 tbm_sprd_bo_get_global_key (tbm_bo bo)
1012 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1014 tbm_bo_sprd bo_sprd;
1016 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1017 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1024 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1027 return bo_sprd->name;
1031 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1033 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1035 #if USE_BACKEND_LOCK
1036 tbm_bufmgr_sprd bufmgr_sprd;
1037 tbm_bo_sprd bo_sprd;
1038 struct dma_buf_fence fence;
1041 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1042 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1044 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1045 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
1047 memset(&fence, 0, sizeof(struct dma_buf_fence));
1049 /* Check if the given type is valid or not. */
1050 if (opt & TBM_OPTION_WRITE)
1052 if (device == TBM_DEVICE_CPU)
1053 fence.type = DMA_BUF_ACCESS_WRITE;
1054 else if (device == TBM_DEVICE_3D)
1055 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1058 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1062 else if (opt & TBM_OPTION_READ)
1064 if (device == TBM_DEVICE_CPU)
1065 fence.type = DMA_BUF_ACCESS_READ;
1066 else if (device == TBM_DEVICE_3D)
1067 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1070 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1076 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
1080 /* Check if the tbm manager supports dma fence or not. */
1081 if (!bufmgr_sprd->use_dma_fence)
1083 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1084 "error %s:%d Not support DMA FENCE(%s)\n",
1085 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1090 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1093 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1094 "error %s:%d Can not set GET FENCE(%s)\n",
1095 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1099 pthread_mutex_lock(&bo_sprd->mutex);
1101 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1103 if (bo_sprd->dma_fence[i].ctx == 0)
1105 bo_sprd->dma_fence[i].type = fence.type;
1106 bo_sprd->dma_fence[i].ctx = fence.ctx;
1110 if (i == DMA_FENCE_LIST_MAX)
1112 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1113 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1114 "error %s:%d fence list is full\n",
1115 getpid(), __FUNCTION__, __LINE__);
1117 pthread_mutex_unlock(&bo_sprd->mutex);
1119 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1120 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1127 tbm_sprd_bo_unlock(tbm_bo bo)
1129 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1131 #if USE_BACKEND_LOCK
1132 tbm_bo_sprd bo_sprd;
1133 struct dma_buf_fence fence;
1136 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1137 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1139 if (!bo_sprd->dma_fence[0].ctx)
1141 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1145 if (!bo_sprd->dma_fence[0].type)
1147 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1151 pthread_mutex_lock(&bo_sprd->mutex);
1152 fence.type = bo_sprd->dma_fence[0].type;
1153 fence.ctx = bo_sprd->dma_fence[0].ctx;
1155 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1157 bo_sprd->dma_fence[i-1].type = bo_sprd->dma_fence[i].type;
1158 bo_sprd->dma_fence[i-1].ctx = bo_sprd->dma_fence[i].ctx;
1160 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1161 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1162 pthread_mutex_unlock(&bo_sprd->mutex);
1164 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1167 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1168 "error %s:%d Can not set PUT FENCE(%s)\n",
1169 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1173 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1174 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1181 tbm_sprd_bufmgr_deinit (void *priv)
1183 SPRD_RETURN_IF_FAIL (priv!=NULL);
1185 tbm_bufmgr_sprd bufmgr_sprd;
1187 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1189 if (bufmgr_sprd->hashBos)
1194 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0)
1197 drmHashDelete (bufmgr_sprd->hashBos, key);
1200 drmHashDestroy (bufmgr_sprd->hashBos);
1201 bufmgr_sprd->hashBos = NULL;
1208 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1210 uint32_t* color_formats=NULL;
1212 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1214 if( color_formats == NULL )
1218 memcpy( color_formats, tbm_sprd_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1221 *formats = color_formats;
1222 *num = TBM_COLOR_FORMAT_COUNT;
1230 * @brief get the plane data of the surface.
1231 * @param[in] surface : the surface
1232 * @param[in] width : the width of the surface
1233 * @param[in] height : the height of the surface
1234 * @param[in] format : the format of the surface
1235 * @param[in] plane_idx : the format of the surface
1236 * @param[out] size : the size of the plane
1237 * @param[out] offset : the offset of the plane
1238 * @param[out] pitch : the pitch of the plane
1239 * @param[out] padding : the padding of the plane
1240 * @return 1 if this function succeeds, otherwise 0.
1243 tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height, tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
1255 case TBM_FORMAT_XRGB4444:
1256 case TBM_FORMAT_XBGR4444:
1257 case TBM_FORMAT_RGBX4444:
1258 case TBM_FORMAT_BGRX4444:
1259 case TBM_FORMAT_ARGB4444:
1260 case TBM_FORMAT_ABGR4444:
1261 case TBM_FORMAT_RGBA4444:
1262 case TBM_FORMAT_BGRA4444:
1263 case TBM_FORMAT_XRGB1555:
1264 case TBM_FORMAT_XBGR1555:
1265 case TBM_FORMAT_RGBX5551:
1266 case TBM_FORMAT_BGRX5551:
1267 case TBM_FORMAT_ARGB1555:
1268 case TBM_FORMAT_ABGR1555:
1269 case TBM_FORMAT_RGBA5551:
1270 case TBM_FORMAT_BGRA5551:
1271 case TBM_FORMAT_RGB565:
1274 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1275 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1279 case TBM_FORMAT_RGB888:
1280 case TBM_FORMAT_BGR888:
1283 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1284 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1288 case TBM_FORMAT_XRGB8888:
1289 case TBM_FORMAT_XBGR8888:
1290 case TBM_FORMAT_RGBX8888:
1291 case TBM_FORMAT_BGRX8888:
1292 case TBM_FORMAT_ARGB8888:
1293 case TBM_FORMAT_ABGR8888:
1294 case TBM_FORMAT_RGBA8888:
1295 case TBM_FORMAT_BGRA8888:
1298 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1299 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1304 case TBM_FORMAT_YUYV:
1305 case TBM_FORMAT_YVYU:
1306 case TBM_FORMAT_UYVY:
1307 case TBM_FORMAT_VYUY:
1308 case TBM_FORMAT_AYUV:
1311 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1312 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1318 * index 0 = Y plane, [7:0] Y
1319 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1321 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1323 case TBM_FORMAT_NV12:
1324 case TBM_FORMAT_NV21:
1329 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1330 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1333 else if( plane_idx ==1 )
1335 _offset = width*height;
1336 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1337 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1342 case TBM_FORMAT_NV16:
1343 case TBM_FORMAT_NV61:
1345 //if(plane_idx == 0)
1348 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1349 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1354 //else if( plane_idx ==1 )
1357 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1358 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1365 * index 0: Y plane, [7:0] Y
1366 * index 1: Cb plane, [7:0] Cb
1367 * index 2: Cr plane, [7:0] Cr
1369 * index 1: Cr plane, [7:0] Cr
1370 * index 2: Cb plane, [7:0] Cb
1373 NATIVE_BUFFER_FORMAT_YV12
1374 NATIVE_BUFFER_FORMAT_I420
1376 case TBM_FORMAT_YUV410:
1377 case TBM_FORMAT_YVU410:
1380 case TBM_FORMAT_YUV411:
1381 case TBM_FORMAT_YVU411:
1382 case TBM_FORMAT_YUV420:
1383 case TBM_FORMAT_YVU420:
1385 //if(plane_idx == 0)
1388 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1389 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1394 //else if( plane_idx == 1 )
1397 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1398 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1403 //else if (plane_idx == 2 )
1406 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1407 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1411 case TBM_FORMAT_YUV422:
1412 case TBM_FORMAT_YVU422:
1414 //if(plane_idx == 0)
1417 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1418 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1423 //else if( plane_idx == 1 )
1426 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1427 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1432 //else if (plane_idx == 2 )
1435 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1436 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1440 case TBM_FORMAT_YUV444:
1441 case TBM_FORMAT_YVU444:
1443 //if(plane_idx == 0)
1446 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1447 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1452 //else if( plane_idx == 1 )
1455 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1456 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1461 //else if (plane_idx == 2 )
1464 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1465 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1482 * @brief get the size of the surface with a format.
1483 * @param[in] surface : the surface
1484 * @param[in] width : the width of the surface
1485 * @param[in] height : the height of the surface
1486 * @param[in] format : the format of the surface
1487 * @return size of the surface if this function succeeds, otherwise 0.
1491 tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1497 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1503 case TBM_FORMAT_XRGB4444:
1504 case TBM_FORMAT_XBGR4444:
1505 case TBM_FORMAT_RGBX4444:
1506 case TBM_FORMAT_BGRX4444:
1507 case TBM_FORMAT_ARGB4444:
1508 case TBM_FORMAT_ABGR4444:
1509 case TBM_FORMAT_RGBA4444:
1510 case TBM_FORMAT_BGRA4444:
1511 case TBM_FORMAT_XRGB1555:
1512 case TBM_FORMAT_XBGR1555:
1513 case TBM_FORMAT_RGBX5551:
1514 case TBM_FORMAT_BGRX5551:
1515 case TBM_FORMAT_ARGB1555:
1516 case TBM_FORMAT_ABGR1555:
1517 case TBM_FORMAT_RGBA5551:
1518 case TBM_FORMAT_BGRA5551:
1519 case TBM_FORMAT_RGB565:
1521 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1522 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1525 case TBM_FORMAT_RGB888:
1526 case TBM_FORMAT_BGR888:
1528 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1529 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1532 case TBM_FORMAT_XRGB8888:
1533 case TBM_FORMAT_XBGR8888:
1534 case TBM_FORMAT_RGBX8888:
1535 case TBM_FORMAT_BGRX8888:
1536 case TBM_FORMAT_ARGB8888:
1537 case TBM_FORMAT_ABGR8888:
1538 case TBM_FORMAT_RGBA8888:
1539 case TBM_FORMAT_BGRA8888:
1541 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1542 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1545 case TBM_FORMAT_YUYV:
1546 case TBM_FORMAT_YVYU:
1547 case TBM_FORMAT_UYVY:
1548 case TBM_FORMAT_VYUY:
1549 case TBM_FORMAT_AYUV:
1551 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1552 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1556 * index 0 = Y plane, [7:0] Y
1557 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1559 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1561 case TBM_FORMAT_NV12:
1562 case TBM_FORMAT_NV21:
1566 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1567 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1571 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1572 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1575 case TBM_FORMAT_NV16:
1576 case TBM_FORMAT_NV61:
1580 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1581 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1585 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1586 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1592 * index 0: Y plane, [7:0] Y
1593 * index 1: Cb plane, [7:0] Cb
1594 * index 2: Cr plane, [7:0] Cr
1596 * index 1: Cr plane, [7:0] Cr
1597 * index 2: Cb plane, [7:0] Cb
1599 case TBM_FORMAT_YUV410:
1600 case TBM_FORMAT_YVU410:
1602 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1604 case TBM_FORMAT_YUV411:
1605 case TBM_FORMAT_YVU411:
1606 case TBM_FORMAT_YUV420:
1607 case TBM_FORMAT_YVU420:
1611 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1612 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1616 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1617 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1621 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1622 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1626 case TBM_FORMAT_YUV422:
1627 case TBM_FORMAT_YVU422:
1631 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1632 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1636 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1637 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1641 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1642 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1645 case TBM_FORMAT_YUV444:
1646 case TBM_FORMAT_YVU444:
1648 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1659 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1666 tbm_sprd_surface_get_num_bos(tbm_format format)
1673 case TBM_FORMAT_XRGB4444:
1674 case TBM_FORMAT_XBGR4444:
1675 case TBM_FORMAT_RGBX4444:
1676 case TBM_FORMAT_BGRX4444:
1677 case TBM_FORMAT_ARGB4444:
1678 case TBM_FORMAT_ABGR4444:
1679 case TBM_FORMAT_RGBA4444:
1680 case TBM_FORMAT_BGRA4444:
1681 case TBM_FORMAT_XRGB1555:
1682 case TBM_FORMAT_XBGR1555:
1683 case TBM_FORMAT_RGBX5551:
1684 case TBM_FORMAT_BGRX5551:
1685 case TBM_FORMAT_ARGB1555:
1686 case TBM_FORMAT_ABGR1555:
1687 case TBM_FORMAT_RGBA5551:
1688 case TBM_FORMAT_BGRA5551:
1689 case TBM_FORMAT_RGB565:
1691 case TBM_FORMAT_RGB888:
1692 case TBM_FORMAT_BGR888:
1694 case TBM_FORMAT_XRGB8888:
1695 case TBM_FORMAT_XBGR8888:
1696 case TBM_FORMAT_RGBX8888:
1697 case TBM_FORMAT_BGRX8888:
1698 case TBM_FORMAT_ARGB8888:
1699 case TBM_FORMAT_ABGR8888:
1700 case TBM_FORMAT_RGBA8888:
1701 case TBM_FORMAT_BGRA8888:
1703 case TBM_FORMAT_YUYV:
1704 case TBM_FORMAT_YVYU:
1705 case TBM_FORMAT_UYVY:
1706 case TBM_FORMAT_VYUY:
1707 case TBM_FORMAT_AYUV:
1710 * index 0 = Y plane, [7:0] Y
1711 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1713 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1715 case TBM_FORMAT_NV12:
1716 case TBM_FORMAT_NV21:
1717 case TBM_FORMAT_NV16:
1718 case TBM_FORMAT_NV61:
1721 * index 0: Y plane, [7:0] Y
1722 * index 1: Cb plane, [7:0] Cb
1723 * index 2: Cr plane, [7:0] Cr
1725 * index 1: Cr plane, [7:0] Cr
1726 * index 2: Cb plane, [7:0] Cb
1728 case TBM_FORMAT_YUV410:
1729 case TBM_FORMAT_YVU410:
1730 case TBM_FORMAT_YUV411:
1731 case TBM_FORMAT_YVU411:
1732 case TBM_FORMAT_YUV420:
1733 case TBM_FORMAT_YVU420:
1734 case TBM_FORMAT_YUV422:
1735 case TBM_FORMAT_YVU422:
1736 case TBM_FORMAT_YUV444:
1737 case TBM_FORMAT_YVU444:
1750 tbm_sprd_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1752 SPRD_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1753 SPRD_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1755 tbm_bo_handle bo_handle;
1756 memset (&bo_handle, 0x0, sizeof (uint64_t));
1758 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_priv_from_bufmgr(bufmgr);
1762 case TBM_DEVICE_DEFAULT:
1765 //getting handle from fd
1766 struct drm_prime_handle arg = {0, };
1770 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1772 TBM_SPRD_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1773 arg.fd, strerror(errno));
1774 return (tbm_bo_handle) NULL;
1777 bo_handle.u32 = (uint32_t)arg.handle;;
1780 case TBM_DEVICE_CPU:
1781 TBM_SPRD_LOG ("Not supported device:%d\n", device);
1782 bo_handle.ptr = (void *) NULL;
1786 bo_handle.u32 = (uint32_t)fd;
1789 TBM_SPRD_LOG ("error Not supported device:%d\n", device);
1790 bo_handle.ptr = (void *) NULL;
1798 tbm_sprd_bo_get_flags (tbm_bo bo)
1800 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1802 tbm_bo_sprd bo_sprd;
1804 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1805 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1807 return bo_sprd->flags_tbm;
1811 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1813 static TBMModuleVersionInfo SprdVersRec =
1820 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1823 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1825 tbm_bufmgr_sprd bufmgr_sprd;
1826 tbm_bufmgr_backend bufmgr_backend;
1831 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1834 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1838 bufmgr_sprd->fd = fd;
1839 if (bufmgr_sprd->fd < 0)
1841 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1847 bufmgr_sprd->hashBos = drmHashCreate ();
1849 //Check if the tbm manager supports dma fence or not.
1850 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1855 length = read(fp, buf, 1);
1857 if (length == 1 && buf[0] == '1')
1858 bufmgr_sprd->use_dma_fence = 1;
1863 bufmgr_backend = tbm_backend_alloc();
1864 if (!bufmgr_backend)
1866 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1871 bufmgr_backend->priv = (void *)bufmgr_sprd;
1872 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit,
1873 bufmgr_backend->bo_size = tbm_sprd_bo_size,
1874 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc,
1875 bufmgr_backend->bo_free = tbm_sprd_bo_free,
1876 bufmgr_backend->bo_import = tbm_sprd_bo_import,
1877 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd,
1878 bufmgr_backend->bo_export = tbm_sprd_bo_export,
1879 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd,
1880 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle,
1881 bufmgr_backend->bo_map = tbm_sprd_bo_map,
1882 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap,
1883 bufmgr_backend->bo_cache_flush = tbm_sprd_bo_cache_flush,
1884 bufmgr_backend->bo_get_global_key = tbm_sprd_bo_get_global_key;
1885 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1886 bufmgr_backend->surface_get_size = tbm_sprd_surface_get_size;
1887 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1888 bufmgr_backend->fd_to_handle = tbm_sprd_fd_to_handle;
1889 bufmgr_backend->surface_get_num_bos = tbm_sprd_surface_get_num_bos;
1890 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1892 if (bufmgr_sprd->use_dma_fence)
1894 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1895 bufmgr_backend->bo_lock = NULL;
1896 bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1897 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1901 bufmgr_backend->flags = 0;
1902 bufmgr_backend->bo_lock = NULL;
1903 bufmgr_backend->bo_unlock = NULL;
1906 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1908 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1909 tbm_backend_free (bufmgr_backend);
1917 env = getenv ("TBM_SPRD_DEBUG");
1920 bDebug = atoi (env);
1921 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1930 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1931 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1933 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
1934 __FUNCTION__, bufmgr_sprd->fd);