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 //#define USE_CONTIG_ONLY
64 #include "tbm_bufmgr_tgl.h"
67 #define TBM_COLOR_FORMAT_COUNT 4
70 #define LOG_TAG "TBM_BACKEND"
72 static int bDebug = 0;
74 #define SPRD_DRM_NAME "sprd"
79 static char app_name[128] = {0, };
80 static int initialized = 0;
87 /* get the application name */
88 f = fopen("/proc/self/cmdline", "r");
92 if (fgets(app_name, 100, f) == NULL) {
99 slash = strrchr(app_name, '/');
101 memmove(app_name, slash + 1, strlen(slash));
108 #define TBM_SPRD_ERROR(fmt, args...) LOGE("\033[31m" "[%s] " fmt "\033[0m", _target_name(), ##args)
109 #define TBM_SPRD_DEBUG(fmt, args...) if (bDebug&01) LOGD("[%s] " fmt, _target_name(), ##args)
111 #define TBM_SPRD_ERROR(...)
112 #define TBM_SPRD_DEBUG(...)
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_ERROR("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
129 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
131 TBM_SPRD_ERROR("[%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 {
236 char *STR_DEVICE[] = {
252 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = {
261 _tgl_get_version(int fd)
263 struct tgl_ver_data data;
266 err = ioctl(fd, TGL_IOCTL_GET_VERSION, &data);
268 TBM_SPRD_ERROR("error(%s) %s:%d\n", strerror(errno));
272 TBM_SPRD_DEBUG("tgl version is (%u, %u).\n", data.major, data.minor);
278 _tgl_init(int fd, unsigned int key)
280 struct tgl_reg_data data;
284 data.timeout_ms = 1000;
286 err = ioctl(fd, TGL_IOCTL_REGISTER, &data);
288 TBM_SPRD_ERROR("error(%s) key:%d\n", strerror(errno), key);
296 _tgl_destroy(int fd, unsigned int key)
298 struct tgl_reg_data data;
302 err = ioctl(fd, TGL_IOCTL_UNREGISTER, &data);
304 TBM_SPRD_ERROR("error(%s) key:%d\n", strerror(errno), key);
312 _tgl_lock(int fd, unsigned int key, int opt)
314 struct tgl_lock_data data;
315 enum tgl_type_data tgl_type;
319 case TBM_OPTION_READ:
320 tgl_type = TGL_TYPE_READ;
322 case TBM_OPTION_WRITE:
323 tgl_type = TGL_TYPE_WRITE;
326 tgl_type = TGL_TYPE_NONE;
331 data.type = tgl_type;
333 err = ioctl(fd, TGL_IOCTL_LOCK, &data);
335 TBM_SPRD_ERROR("error(%s) key:%d opt:%d\n",
336 strerror(errno), key, opt);
344 _tgl_unlock(int fd, unsigned int key)
346 struct tgl_lock_data data;
350 data.type = TGL_TYPE_NONE;
352 err = ioctl(fd, TGL_IOCTL_UNLOCK, &data);
354 TBM_SPRD_ERROR("error(%s) key:%d\n",
355 strerror(errno), key);
363 _tgl_set_data(int fd, unsigned int key, unsigned int val)
365 struct tgl_usr_data data;
371 err = ioctl(fd, TGL_IOCTL_SET_DATA, &data);
373 TBM_SPRD_ERROR("error(%s) key:%d\n",
374 strerror(errno), key);
381 static inline unsigned int
382 _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
384 struct tgl_usr_data data = { 0, };
389 err = ioctl(fd, TGL_IOCTL_GET_DATA, &data);
391 TBM_SPRD_ERROR("error(%s) key:%d\n",
392 strerror(errno), key);
397 *locked = (unsigned int)data.status;
404 _tbm_sprd_open_drm(void)
407 struct udev_device *drm_device = NULL;
408 struct udev_list_entry *entry = NULL;
409 struct udev_enumerate *e;
410 const char *filepath;
416 fd = drmOpen(SPRD_DRM_NAME, NULL);
421 TBM_SPRD_DEBUG("warning fail to open drm. search drm-device by udev\n");
425 TBM_SPRD_ERROR("udev_new() failed.\n");
429 e = udev_enumerate_new(udev);
430 udev_enumerate_add_match_subsystem(e, "drm");
431 udev_enumerate_add_match_sysname(e, "card[0-9]*");
432 udev_enumerate_scan_devices(e);
434 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
435 struct udev_device *device, *device_parent;
437 device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
438 udev_list_entry_get_name(entry));
439 device_parent = udev_device_get_parent(device);
440 /* Not need unref device_parent. device_parent and device have same refcnt */
442 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
444 TBM_SPRD_DEBUG("Found render device: '%s' (%s)\n",
445 udev_device_get_syspath(drm_device),
446 udev_device_get_sysname(device_parent));
450 udev_device_unref(device);
453 udev_enumerate_unref(e);
455 /* Get device file path. */
456 filepath = udev_device_get_devnode(drm_device);
458 TBM_SPRD_ERROR("udev_device_get_devnode() failed.\n");
459 udev_device_unref(drm_device);
464 udev_device_unref(drm_device);
467 /* Open DRM device file and check validity. */
468 fd = open(filepath, O_RDWR | O_CLOEXEC);
470 TBM_SPRD_ERROR("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
475 TBM_SPRD_ERROR("fstat() failed %s.\n");
480 TBM_SPRD_ERROR("warning fail to open drm\n");
488 _sprd_bo_cache_flush(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int flags)
490 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
492 /* cache flush is managed by kernel side when using dma-fence. */
493 if (bufmgr_sprd->use_dma_fence)
495 // TODO: The tm1 kernel does not support ioctl for cache flush right now.
496 // The drm in tm1 kernel has to support cache_flush to turn on this feature(TBM_SRPD_CACHE_FLUSH).
497 #if TBM_SRPD_CACHE_FLUSH
498 struct drm_sprd_gem_cache_op cache_op = {0, };
501 /* if bo_sprd is null, do cache_flush_all */
504 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
505 cache_op.size = bo_sprd->size;
507 flags = TBM_SPRD_CACHE_FLUSH_ALL;
509 cache_op.usr_addr = 0;
513 if (flags & TBM_SPRD_CACHE_INV) {
514 if (flags & TBM_SPRD_CACHE_ALL)
515 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
517 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
520 if (flags & TBM_SPRD_CACHE_CLN) {
521 if (flags & TBM_SPRD_CACHE_ALL)
522 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
524 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
527 if (flags & TBM_SPRD_CACHE_ALL)
528 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
530 ret = drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
533 TBM_SPRD_ERROR("error fail to flush the cache.\n");
543 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int import)
546 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
547 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
549 if (bufmgr_sprd->use_dma_fence)
552 _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
554 tbm_bo_cache_state cache_state;
557 cache_state.data.isDirtied = DEVICE_NONE;
558 cache_state.data.isCached = 0;
559 cache_state.data.cntFlush = 0;
561 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
569 _bo_set_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd, int device, int opt)
572 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
573 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
576 unsigned short cntFlush = 0;
578 if (bufmgr_sprd->use_dma_fence)
581 if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
584 /* get cache state of a bo */
585 bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
587 /* get global cache flush count */
588 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
590 if (opt == TBM_DEVICE_CPU) {
591 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
592 bo_sprd->cache_state.data.isCached)
593 need_flush = TBM_SPRD_CACHE_INV;
595 bo_sprd->cache_state.data.isCached = 1;
596 if (opt & TBM_OPTION_WRITE)
597 bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
599 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
600 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
603 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
604 bo_sprd->cache_state.data.isCached &&
605 bo_sprd->cache_state.data.cntFlush == cntFlush)
606 need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
608 if (opt & TBM_OPTION_WRITE)
609 bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
611 if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
612 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
617 if (need_flush & TBM_SPRD_CACHE_ALL)
618 _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
620 /* call cache flush */
621 _sprd_bo_cache_flush(bufmgr_sprd, bo_sprd, need_flush);
623 TBM_SPRD_DEBUG("\tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
624 bo_sprd->cache_state.data.isCached,
625 bo_sprd->cache_state.data.isDirtied,
635 _bo_save_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
638 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
639 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
641 if (bufmgr_sprd->use_dma_fence)
644 unsigned short cntFlush = 0;
646 /* get global cache flush count */
647 cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
649 /* save global cache flush count */
650 bo_sprd->cache_state.data.cntFlush = cntFlush;
651 _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
658 _bo_destroy_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
661 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
662 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
664 if (bufmgr_sprd->use_dma_fence)
667 _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
672 _bufmgr_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
675 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
677 if (bufmgr_sprd->use_dma_fence)
680 /* open tgl fd for saving cache flush data */
681 bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
683 if (bufmgr_sprd->tgl_fd < 0) {
684 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
685 if (bufmgr_sprd->tgl_fd < 0) {
686 TBM_SPRD_ERROR("fail to open global_lock:%s\n",
692 if (!_tgl_get_version(bufmgr_sprd->tgl_fd)) {
693 TBM_SPRD_ERROR("fail to get tgl_version. tgl init failed.\n");
694 close(bufmgr_sprd->tgl_fd);
698 if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
699 TBM_SPRD_ERROR("fail to initialize the tgl\n");
700 close(bufmgr_sprd->tgl_fd);
709 _bufmgr_deinit_cache_state(tbm_bufmgr_sprd bufmgr_sprd)
712 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
714 if (bufmgr_sprd->use_dma_fence)
717 if (bufmgr_sprd->tgl_fd >= 0)
718 close(bufmgr_sprd->tgl_fd);
722 #ifndef USE_CONTIG_ONLY
724 _get_sprd_flag_from_tbm(unsigned int ftbm)
726 unsigned int flags = 0;
729 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
730 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
731 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
732 * To be updated appropriately once DRM-GEM supports different heap id masks.
735 if (ftbm & TBM_BO_SCANOUT)
736 flags = SPRD_BO_CONTIG;
738 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
740 if (ftbm & TBM_BO_WC)
742 else if (ftbm & TBM_BO_NONCACHABLE)
743 flags |= SPRD_BO_NONCACHABLE;
749 _get_tbm_flag_from_sprd(unsigned int fsprd)
751 unsigned int flags = 0;
753 if (fsprd & SPRD_BO_NONCONTIG)
754 flags |= TBM_BO_DEFAULT;
756 flags |= TBM_BO_SCANOUT;
758 if (fsprd & SPRD_BO_WC)
760 else if (fsprd & SPRD_BO_CACHABLE)
761 flags |= TBM_BO_DEFAULT;
763 flags |= TBM_BO_NONCACHABLE;
770 _get_name(int fd, unsigned int gem)
772 struct drm_gem_flink arg = {0,};
775 if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
776 TBM_SPRD_ERROR("error fail to get flink gem=%d\n", gem);
780 return (unsigned int)arg.name;
784 _sprd_bo_handle(tbm_bo_sprd bo_sprd, int device)
786 tbm_bo_handle bo_handle;
787 memset(&bo_handle, 0x0, sizeof(uint64_t));
790 case TBM_DEVICE_DEFAULT:
792 bo_handle.u32 = (uint32_t)bo_sprd->gem;
795 if (!bo_sprd->pBase) {
796 struct drm_sprd_gem_mmap arg = {0,};
798 arg.handle = bo_sprd->gem;
799 arg.size = bo_sprd->size;
800 if (drmCommandWriteRead(bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
801 TBM_SPRD_ERROR("error Cannot usrptr gem=%d\n", bo_sprd->gem);
802 return (tbm_bo_handle) NULL;
804 bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
807 bo_handle.ptr = (void *)bo_sprd->pBase;
811 if (!bo_sprd->dmabuf) {
812 struct drm_prime_handle arg = {0, };
813 arg.handle = bo_sprd->gem;
814 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
815 TBM_SPRD_ERROR("error Cannot dmabuf=%d\n", bo_sprd->gem);
816 return (tbm_bo_handle) NULL;
818 bo_sprd->dmabuf = arg.fd;
821 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
828 //TODO : Add ioctl for GSP MAP once available.
829 TBM_SPRD_DEBUG("%s In case TBM_DEVICE_MM: \n", __FUNCTION_);
831 if (!bo_sprd->dmabuf) {
832 struct drm_prime_handle arg = {0, };
834 arg.handle = bo_sprd->gem;
835 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
836 TBM_SPRD_ERROR("error Cannot dmabuf=%d\n", bo_sprd->gem);
837 return (tbm_bo_handle) NULL;
839 bo_sprd->dmabuf = arg.fd;
842 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
846 bo_handle.ptr = (void *) NULL;
854 tbm_sprd_bo_size(tbm_bo bo)
856 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
860 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
861 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
863 return bo_sprd->size;
867 tbm_sprd_bo_alloc(tbm_bo bo, int size, int flags)
869 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
871 tbm_bufmgr_sprd bufmgr_sprd;
872 unsigned int sprd_flags;
875 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
876 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
878 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
880 TBM_SPRD_ERROR("error fail to allocate the bo private\n");
884 #ifdef USE_CONTIG_ONLY
885 flags = TBM_BO_SCANOUT;
886 sprd_flags = SPRD_BO_CONTIG;
888 sprd_flags = _get_sprd_flag_from_tbm(flags);
889 if ((flags & TBM_BO_SCANOUT) && (size <= 4 * 1024))
890 sprd_flags |= SPRD_BO_NONCONTIG;
891 #endif // USE_CONTIG_ONLY
893 struct drm_sprd_gem_create arg = {0, };
894 arg.size = (uint64_t)size;
895 arg.flags = sprd_flags;
896 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
898 TBM_SPRD_ERROR("error Cannot create bo(flag:%x, size:%d)\n",
899 arg.flags, (unsigned int)arg.size);
904 bo_sprd->fd = bufmgr_sprd->fd;
905 bo_sprd->gem = arg.handle;
906 bo_sprd->size = size;
907 bo_sprd->flags_tbm = flags;
908 bo_sprd->flags_sprd = sprd_flags;
909 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
911 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 0)) {
912 TBM_SPRD_ERROR("error fail init cache state(%d)\n", bo_sprd->name);
917 pthread_mutex_init(&bo_sprd->mutex, NULL);
919 if (bufmgr_sprd->use_dma_fence
920 && !bo_sprd->dmabuf) {
921 struct drm_prime_handle arg = {0, };
923 arg.handle = bo_sprd->gem;
924 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
925 TBM_SPRD_ERROR("error Cannot dmabuf=%d\n", bo_sprd->gem);
929 bo_sprd->dmabuf = arg.fd;
933 PrivGem *privGem = calloc(1, sizeof(PrivGem));
935 TBM_SPRD_ERROR("error Fail to calloc PrivGem\n");
940 privGem->ref_count = 1;
941 privGem->bo_priv = bo_sprd;
942 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
943 TBM_SPRD_ERROR("error Cannot insert bo to Hash(%d)\n", bo_sprd->name);
945 TBM_SPRD_DEBUG("%s size:%d, gem:%d(%d), flags:%d(%d)\n",
946 __FUNCTION__, bo_sprd->size,
947 bo_sprd->gem, bo_sprd->name,
950 return (void *)bo_sprd;
954 tbm_sprd_bo_free(tbm_bo bo)
957 tbm_bufmgr_sprd bufmgr_sprd;
962 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
963 SPRD_RETURN_IF_FAIL(bufmgr_sprd != NULL);
965 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
966 SPRD_RETURN_IF_FAIL(bo_sprd != NULL);
968 TBM_SPRD_DEBUG("size:%d, gem:%d(%d)\n",
969 bo_sprd->size, bo_sprd->gem, bo_sprd->name);
971 if (bo_sprd->pBase) {
972 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1)
973 TBM_SPRD_ERROR("error fail to munmap.\n");
977 if (bo_sprd->dmabuf) {
978 close(bo_sprd->dmabuf);
982 /* delete bo from hash */
983 PrivGem *privGem = NULL;
986 ret = drmHashLookup(bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
988 privGem->ref_count--;
989 if (privGem->ref_count == 0) {
990 drmHashDelete(bufmgr_sprd->hashBos, bo_sprd->name);
995 TBM_SPRD_DEBUG("warning Cannot find bo to Hash(%d), ret=%d\n", bo_sprd->name, ret);
998 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
1000 /* Free gem handle */
1001 struct drm_gem_close arg = {0, };
1002 memset(&arg, 0, sizeof(arg));
1003 arg.handle = bo_sprd->gem;
1004 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg))
1005 TBM_SPRD_ERROR("error fail to DRM_IOCTL_GEM_CLOSE\n");
1012 tbm_sprd_bo_import(tbm_bo bo, unsigned int key)
1014 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, NULL);
1016 tbm_bufmgr_sprd bufmgr_sprd;
1017 tbm_bo_sprd bo_sprd;
1018 PrivGem *privGem = NULL;
1021 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1022 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, NULL);
1024 ret = drmHashLookup(bufmgr_sprd->hashBos, key, (void **)&privGem);
1026 return privGem->bo_priv;
1028 struct drm_sprd_gem_info info = {0, };
1029 struct drm_gem_open arg = {0, };
1032 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
1033 TBM_SPRD_ERROR("error Cannot open gem name=%d\n", key);
1037 info.handle = arg.handle;
1038 if (drmCommandWriteRead(bufmgr_sprd->fd,
1041 sizeof(struct drm_sprd_gem_info))) {
1042 TBM_SPRD_ERROR("error Cannot get gem info=%d\n", key);
1046 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1048 TBM_SPRD_ERROR("error fail to allocate the bo private\n");
1052 bo_sprd->fd = bufmgr_sprd->fd;
1053 bo_sprd->gem = arg.handle;
1054 bo_sprd->size = arg.size;
1055 bo_sprd->flags_sprd = info.flags;
1056 bo_sprd->name = key;
1057 #ifdef USE_CONTIG_ONLY
1058 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1059 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1061 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1064 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1065 TBM_SPRD_ERROR("error fail init cache state(%d)\n", bo_sprd->name);
1066 goto fail_init_cache;
1069 if (!bo_sprd->dmabuf) {
1070 struct drm_prime_handle arg = {0, };
1072 arg.handle = bo_sprd->gem;
1073 if (drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1074 TBM_SPRD_ERROR("error Cannot dmabuf=%d\n", bo_sprd->gem);
1075 goto fail_prime_handle_to_fd;
1077 bo_sprd->dmabuf = arg.fd;
1080 /* add bo to hash */
1081 privGem = calloc(1, sizeof(PrivGem));
1083 TBM_SPRD_ERROR("error Fail to alloc\n");
1084 goto fail_alloc_gem_priv;
1087 privGem->ref_count = 1;
1088 privGem->bo_priv = bo_sprd;
1089 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
1090 TBM_SPRD_ERROR("error Cannot insert bo to Hash(%d)\n", bo_sprd->name);
1092 TBM_SPRD_DEBUG("size:%d, gem:%d(%d), flags:%d(%d)\n",
1093 bo_sprd->size, bo_sprd->gem, bo_sprd->name,
1094 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1096 return (void *)bo_sprd;
1098 fail_alloc_gem_priv:
1099 if (bo_sprd->dmabuf)
1100 close(bo_sprd->dmabuf);
1101 fail_prime_handle_to_fd:
1102 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
1108 struct drm_gem_close gem_close_arg = {arg.handle, 0};
1109 drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_CLOSE, &gem_close_arg);
1115 tbm_sprd_bo_import_fd(tbm_bo bo, tbm_fd key)
1117 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, NULL);
1119 tbm_bufmgr_sprd bufmgr_sprd;
1120 tbm_bo_sprd bo_sprd;
1124 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1125 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, NULL);
1127 //getting handle from fd
1128 struct drm_prime_handle arg = {0, };
1132 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1133 TBM_SPRD_ERROR("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1134 bo, arg.fd, strerror(errno));
1139 name = _get_name(bufmgr_sprd->fd, gem);
1141 TBM_SPRD_ERROR("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1142 bo, gem, key, strerror(errno));
1146 if (!drmHashLookup(bufmgr_sprd->hashBos, name, (void **)&privGem)) {
1147 if (gem == privGem->bo_priv->gem)
1148 return privGem->bo_priv;
1151 unsigned int real_size;
1152 struct drm_sprd_gem_info info = {0, };
1154 /* Determine size of bo. The fd-to-handle ioctl really should
1155 * return the size, but it doesn't. If we have kernel 3.12 or
1156 * later, we can lseek on the prime fd to get the size. Older
1157 * kernels will just fail, in which case we fall back to the
1158 * provided (estimated or guess size). */
1159 real_size = lseek(key, 0, SEEK_END);
1162 if (drmCommandWriteRead(bufmgr_sprd->fd,
1165 sizeof(struct drm_sprd_gem_info))) {
1166 TBM_SPRD_ERROR("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1167 bo, gem, key, strerror(errno));
1171 if (real_size == -1)
1172 real_size = info.size;
1174 bo_sprd = calloc(1, sizeof(struct _tbm_bo_sprd));
1176 TBM_SPRD_ERROR("error bo:%p fail to allocate the bo private\n", bo);
1180 bo_sprd->fd = bufmgr_sprd->fd;
1182 bo_sprd->size = real_size;
1183 bo_sprd->flags_sprd = info.flags;
1184 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd(bo_sprd->flags_sprd);
1186 bo_sprd->name = name;
1187 if (!bo_sprd->name) {
1188 TBM_SPRD_ERROR("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1189 bo, gem, key, strerror(errno));
1190 goto fail_check_name;
1193 if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd, 1)) {
1194 TBM_SPRD_ERROR("error fail init cache state(%d)\n", bo_sprd->name);
1195 goto fail_init_cache;
1198 /* add bo to hash */
1199 privGem = calloc(1, sizeof(PrivGem));
1201 TBM_SPRD_ERROR("error Fail to callocprivGem\n");
1202 goto fail_alloc_gem_priv;
1205 privGem->ref_count = 1;
1206 privGem->bo_priv = bo_sprd;
1207 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1208 TBM_SPRD_ERROR("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1209 bo, bo_sprd->name, gem, key);
1212 TBM_SPRD_DEBUG("bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1214 bo_sprd->gem, bo_sprd->name,
1217 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1220 return (void *)bo_sprd;
1222 fail_alloc_gem_priv:
1223 _bo_destroy_cache_state(bufmgr_sprd, bo_sprd);
1231 tbm_sprd_bo_export(tbm_bo bo)
1233 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1235 tbm_bo_sprd bo_sprd;
1237 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1238 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1240 if (!bo_sprd->name) {
1241 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1242 if (!bo_sprd->name) {
1243 TBM_SPRD_ERROR("error Cannot get name\n");
1248 TBM_SPRD_DEBUG("size:%d, gem:%d(%d), flags:%d(%d)\n",
1249 bo_sprd->size, bo_sprd->gem, bo_sprd->name,
1250 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1252 return (unsigned int)bo_sprd->name;
1256 tbm_sprd_bo_export_fd(tbm_bo bo)
1258 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, -1);
1260 tbm_bo_sprd bo_sprd;
1263 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1264 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, -1);
1266 struct drm_prime_handle arg = {0, };
1268 arg.handle = bo_sprd->gem;
1269 ret = drmIoctl(bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1271 TBM_SPRD_ERROR("error bo:%p Cannot dmabuf=%d (%s)\n",
1272 bo, bo_sprd->gem, strerror(errno));
1273 return (tbm_fd) ret;
1276 TBM_SPRD_DEBUG("bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1278 bo_sprd->gem, bo_sprd->name,
1281 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1284 return (tbm_fd)arg.fd;
1288 static tbm_bo_handle
1289 tbm_sprd_bo_get_handle(tbm_bo bo, int device)
1291 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1293 tbm_bo_handle bo_handle;
1294 tbm_bo_sprd bo_sprd;
1296 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1297 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1299 if (!bo_sprd->gem) {
1300 TBM_SPRD_ERROR("error Cannot map gem=%d\n", bo_sprd->gem);
1301 return (tbm_bo_handle) NULL;
1304 TBM_SPRD_DEBUG("gem:%d(%d), %s\n",
1305 bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1307 /*Get mapped bo_handle*/
1308 bo_handle = _sprd_bo_handle(bo_sprd, device);
1309 if (bo_handle.ptr == NULL) {
1310 TBM_SPRD_ERROR("error Cannot get handle: gem:%d, device:%d\n",
1311 bo_sprd->gem, device);
1312 return (tbm_bo_handle) NULL;
1318 static tbm_bo_handle
1319 tbm_sprd_bo_map(tbm_bo bo, int device, int opt)
1321 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL);
1323 tbm_bo_handle bo_handle;
1324 tbm_bo_sprd bo_sprd;
1325 tbm_bufmgr_sprd bufmgr_sprd;
1327 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1328 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, (tbm_bo_handle) NULL);
1330 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1331 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, (tbm_bo_handle) NULL);
1333 if (!bo_sprd->gem) {
1334 TBM_SPRD_ERROR("error Cannot map gem=%d\n", bo_sprd->gem);
1335 return (tbm_bo_handle) NULL;
1338 TBM_SPRD_DEBUG("%s gem:%d(%d), %s, %s\n",
1339 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1341 /*Get mapped bo_handle*/
1342 bo_handle = _sprd_bo_handle(bo_sprd, device);
1343 if (bo_handle.ptr == NULL) {
1344 TBM_SPRD_ERROR("error Cannot get handle: gem:%d, device:%d, opt:%d\n",
1345 bo_sprd->gem, device, opt);
1346 return (tbm_bo_handle) NULL;
1349 if (bo_sprd->map_cnt == 0)
1350 _bo_set_cache_state(bufmgr_sprd, bo_sprd, device, opt);
1358 tbm_sprd_bo_unmap(tbm_bo bo)
1360 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1362 tbm_bufmgr_sprd bufmgr_sprd;
1363 tbm_bo_sprd bo_sprd;
1365 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1366 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1368 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1369 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1376 if (bo_sprd->map_cnt == 0)
1377 _bo_save_cache_state(bufmgr_sprd, bo_sprd);
1379 TBM_SPRD_DEBUG("gem:%d(%d) \n", bo_sprd->gem, bo_sprd->name);
1385 tbm_sprd_bufmgr_deinit(void *priv)
1387 SPRD_RETURN_IF_FAIL(priv != NULL);
1389 tbm_bufmgr_sprd bufmgr_sprd;
1391 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1393 if (bufmgr_sprd->hashBos) {
1397 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1399 drmHashDelete(bufmgr_sprd->hashBos, key);
1402 drmHashDestroy(bufmgr_sprd->hashBos);
1403 bufmgr_sprd->hashBos = NULL;
1406 if (bufmgr_sprd->bind_display)
1407 tbm_drm_helper_wl_auth_server_deinit();
1409 if (tbm_backend_is_display_server())
1410 tbm_drm_helper_unset_tbm_master_fd();
1412 if (bufmgr_sprd->device_name)
1413 free(bufmgr_sprd->device_name);
1415 _bufmgr_deinit_cache_state(bufmgr_sprd);
1417 close(bufmgr_sprd->fd);
1423 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1425 uint32_t *color_formats;
1427 color_formats = (uint32_t *)calloc(1,
1428 sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1429 if (color_formats == NULL)
1432 memcpy(color_formats, tbm_sprd_color_format_list,
1433 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1435 *formats = color_formats;
1436 *num = TBM_COLOR_FORMAT_COUNT;
1443 * @brief get the plane data of the surface.
1444 * @param[in] width : the width of the surface
1445 * @param[in] height : the height of the surface
1446 * @param[in] format : the format of the surface
1447 * @param[in] plane_idx : the format of the surface
1448 * @param[out] size : the size of the plane
1449 * @param[out] offset : the offset of the plane
1450 * @param[out] pitch : the pitch of the plane
1451 * @param[out] padding : the padding of the plane
1452 * @return 1 if this function succeeds, otherwise 0.
1455 tbm_sprd_surface_get_plane_data(int width, int height,
1456 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1457 uint32_t *pitch, int *bo_idx)
1465 int _align_height = 0;
1469 case TBM_FORMAT_XRGB4444:
1470 case TBM_FORMAT_XBGR4444:
1471 case TBM_FORMAT_RGBX4444:
1472 case TBM_FORMAT_BGRX4444:
1473 case TBM_FORMAT_ARGB4444:
1474 case TBM_FORMAT_ABGR4444:
1475 case TBM_FORMAT_RGBA4444:
1476 case TBM_FORMAT_BGRA4444:
1477 case TBM_FORMAT_XRGB1555:
1478 case TBM_FORMAT_XBGR1555:
1479 case TBM_FORMAT_RGBX5551:
1480 case TBM_FORMAT_BGRX5551:
1481 case TBM_FORMAT_ARGB1555:
1482 case TBM_FORMAT_ABGR1555:
1483 case TBM_FORMAT_RGBA5551:
1484 case TBM_FORMAT_BGRA5551:
1485 case TBM_FORMAT_RGB565:
1488 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1489 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1493 case TBM_FORMAT_RGB888:
1494 case TBM_FORMAT_BGR888:
1497 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1498 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1502 case TBM_FORMAT_XRGB8888:
1503 case TBM_FORMAT_XBGR8888:
1504 case TBM_FORMAT_RGBX8888:
1505 case TBM_FORMAT_BGRX8888:
1506 case TBM_FORMAT_ARGB8888:
1507 case TBM_FORMAT_ABGR8888:
1508 case TBM_FORMAT_RGBA8888:
1509 case TBM_FORMAT_BGRA8888:
1512 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1513 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1518 case TBM_FORMAT_YUYV:
1519 case TBM_FORMAT_YVYU:
1520 case TBM_FORMAT_UYVY:
1521 case TBM_FORMAT_VYUY:
1522 case TBM_FORMAT_AYUV:
1525 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1526 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1532 * index 0 = Y plane, [7:0] Y
1533 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1535 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1537 case TBM_FORMAT_NV12:
1538 case TBM_FORMAT_NV21:
1540 if (plane_idx == 0) {
1542 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1543 _align_height = SIZE_ALIGN(height, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1544 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1546 } else if (plane_idx == 1) {
1547 _offset = width * height;
1548 _pitch = SIZE_ALIGN(width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1549 _align_height = SIZE_ALIGN(height / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1550 _size = SIZE_ALIGN(_pitch * _align_height, TBM_SURFACE_ALIGNMENT_PLANE);
1555 case TBM_FORMAT_NV16:
1556 case TBM_FORMAT_NV61:
1558 //if(plane_idx == 0)
1561 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1562 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1567 //else if( plane_idx ==1 )
1570 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1571 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1578 * index 0: Y plane, [7:0] Y
1579 * index 1: Cb plane, [7:0] Cb
1580 * index 2: Cr plane, [7:0] Cr
1582 * index 1: Cr plane, [7:0] Cr
1583 * index 2: Cb plane, [7:0] Cb
1586 NATIVE_BUFFER_FORMAT_YV12
1587 NATIVE_BUFFER_FORMAT_I420
1589 case TBM_FORMAT_YUV410:
1590 case TBM_FORMAT_YVU410:
1593 case TBM_FORMAT_YUV411:
1594 case TBM_FORMAT_YVU411:
1595 case TBM_FORMAT_YUV420:
1596 case TBM_FORMAT_YVU420:
1598 //if(plane_idx == 0)
1601 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1602 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1607 //else if( plane_idx == 1 )
1610 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1611 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1616 //else if (plane_idx == 2 )
1619 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1620 _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1624 case TBM_FORMAT_YUV422:
1625 case TBM_FORMAT_YVU422:
1627 //if(plane_idx == 0)
1630 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1631 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1636 //else if( plane_idx == 1 )
1639 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1640 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1645 //else if (plane_idx == 2 )
1648 _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1649 _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1653 case TBM_FORMAT_YUV444:
1654 case TBM_FORMAT_YVU444:
1656 //if(plane_idx == 0)
1659 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1660 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1665 //else if( plane_idx == 1 )
1668 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1669 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1674 //else if (plane_idx == 2 )
1677 _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1678 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1696 tbm_sprd_bo_get_flags(tbm_bo bo)
1698 SPRD_RETURN_VAL_IF_FAIL(bo != NULL, 0);
1700 tbm_bo_sprd bo_sprd;
1702 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1703 SPRD_RETURN_VAL_IF_FAIL(bo_sprd != NULL, 0);
1705 return bo_sprd->flags_tbm;
1709 tbm_sprd_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1711 tbm_bufmgr_sprd bufmgr_sprd;
1713 bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1714 SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1716 if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1717 bufmgr_sprd->device_name, 0)) {
1718 TBM_SPRD_ERROR("fail to tbm_drm_helper_wl_server_init\n");
1722 bufmgr_sprd->bind_display = NativeDisplay;
1727 MODULEINITPPROTO(init_tbm_bufmgr_priv);
1729 static TBMModuleVersionInfo SprdVersRec = {
1735 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1738 init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd)
1740 tbm_bufmgr_backend bufmgr_backend;
1741 tbm_bufmgr_sprd bufmgr_sprd;
1747 bufmgr_sprd = calloc(1, sizeof(struct _tbm_bufmgr_sprd));
1749 TBM_SPRD_ERROR("fail to alloc bufmgr_sprd!\n");
1753 if (tbm_backend_is_display_server()) {
1754 bufmgr_sprd->fd = tbm_drm_helper_get_master_fd();
1755 if (bufmgr_sprd->fd < 0) {
1756 bufmgr_sprd->fd = _tbm_sprd_open_drm();
1757 if (bufmgr_sprd->fd < 0) {
1758 TBM_SPRD_ERROR("fail to open drm!\n");
1763 tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
1765 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1766 if (!bufmgr_sprd->device_name) {
1767 TBM_SPRD_ERROR("fail to get device name!\n");
1768 tbm_drm_helper_unset_tbm_master_fd();
1769 goto fail_get_device_name;
1772 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1773 TBM_SPRD_ERROR("fail to get auth drm info!\n");
1774 goto fail_get_auth_info;
1779 bufmgr_sprd->hashBos = drmHashCreate();
1781 //Check if the tbm manager supports dma fence or not.
1782 fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1785 int length = read(fp, buf, 1);
1787 if (length == 1 && buf[0] == '1')
1788 bufmgr_sprd->use_dma_fence = 1;
1793 if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
1794 TBM_SPRD_ERROR("fail to init bufmgr cache state\n");
1795 goto fail_init_cache_state;
1798 bufmgr_backend = tbm_backend_alloc();
1799 if (!bufmgr_backend) {
1800 TBM_SPRD_ERROR("fail to alloc backend!\n");
1801 goto fail_alloc_backend;
1804 bufmgr_backend->priv = (void *)bufmgr_sprd;
1805 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1806 bufmgr_backend->bo_size = tbm_sprd_bo_size;
1807 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1808 bufmgr_backend->bo_free = tbm_sprd_bo_free;
1809 bufmgr_backend->bo_import = tbm_sprd_bo_import;
1810 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1811 bufmgr_backend->bo_export = tbm_sprd_bo_export;
1812 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1813 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1814 bufmgr_backend->bo_map = tbm_sprd_bo_map;
1815 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1816 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1817 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1818 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1819 bufmgr_backend->bo_lock = NULL;
1820 bufmgr_backend->bo_unlock = NULL;
1821 bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1823 if (!tbm_backend_init(bufmgr, bufmgr_backend)) {
1824 TBM_SPRD_ERROR("fail to init backend!\n");
1825 goto fail_init_backend;
1832 env = getenv("TBM_SPRD_DEBUG");
1835 TBM_SPRD_ERROR("TBM_SPRD_DEBUG=%s\n", env);
1841 TBM_SPRD_DEBUG("DMABUF FENCE is %s\n",
1842 bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1843 TBM_SPRD_DEBUG("fd:%d\n", bufmgr_sprd->fd);
1848 tbm_backend_free(bufmgr_backend);
1850 _bufmgr_deinit_cache_state(bufmgr_sprd);
1851 fail_init_cache_state:
1852 if (bufmgr_sprd->hashBos)
1853 drmHashDestroy(bufmgr_sprd->hashBos);
1854 if (tbm_backend_is_display_server())
1855 tbm_drm_helper_unset_tbm_master_fd();
1856 if (bufmgr_sprd->device_name)
1857 free(bufmgr_sprd->device_name);
1858 fail_get_device_name:
1859 close(bufmgr_sprd->fd);