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 "exynos_drm.h"
54 #define TBM_EXYNOS4412_LOG(...) fprintf (stderr, __VA_ARGS__)
57 static int bDebug = 0;
58 #define DBG(...) if(bDebug&0x1) TBM_EXYNOS4412_LOG (__VA_ARGS__)
64 #define EXYNOS4412_RETURN_IF_FAIL(cond) {\
66 TBM_EXYNOS4412_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
70 #define EXYNOS4412_RETURN_VAL_IF_FAIL(cond, val) {\
72 TBM_EXYNOS4412_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
79 unsigned int fence_supported;
83 #define DMA_BUF_ACCESS_READ 0x1
84 #define DMA_BUF_ACCESS_WRITE 0x2
85 #define DMA_BUF_ACCESS_DMA 0x4
86 #define DMA_BUF_ACCESS_MAX 0x8
88 #define DMA_FENCE_LIST_MAX 5
90 struct dma_buf_fence {
95 #define DMABUF_IOCTL_BASE 'F'
96 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
98 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
99 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
100 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
102 typedef struct _tbm_bufmgr_exynos4412 *tbm_bufmgr_exynos4412;
103 typedef struct _tbm_bo_exynos4412 *tbm_bo_exynos4412;
105 typedef struct _exynos4412_private
110 /* tbm buffor object for exynos4412 */
111 struct _tbm_bo_exynos4412
115 unsigned int name; /* FLINK ID */
117 unsigned int gem; /* GEM Handle */
119 unsigned int dmabuf; /* fd for dmabuf */
121 void *pBase; /* virtual address */
125 unsigned int flags_exynos;
126 unsigned int flags_tbm;
130 pthread_mutex_t mutex;
131 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
136 /* tbm bufmgr private for exynos4412 */
137 struct _tbm_bufmgr_exynos4412
164 _get_exynos_flag_from_tbm (unsigned int ftbm)
166 unsigned int flags = 0;
168 if (ftbm & TBM_BO_SCANOUT)
169 flags |= EXYNOS_BO_CONTIG;
171 flags |= EXYNOS_BO_NONCONTIG;
173 if (ftbm & TBM_BO_WC)
174 flags |= EXYNOS_BO_WC;
175 else if (ftbm & TBM_BO_NONCACHABLE)
176 flags |= EXYNOS_BO_NONCACHABLE;
178 flags |= EXYNOS_BO_CACHABLE;
184 _get_tbm_flag_from_exynos (unsigned int fexynos)
186 unsigned int flags = 0;
188 if (fexynos & EXYNOS_BO_NONCONTIG)
189 flags |= TBM_BO_DEFAULT;
191 flags |= TBM_BO_SCANOUT;
193 if (fexynos & EXYNOS_BO_WC)
195 else if (fexynos & EXYNOS_BO_CACHABLE)
196 flags |= TBM_BO_DEFAULT;
198 flags |= TBM_BO_NONCACHABLE;
204 _get_name (int fd, unsigned int gem)
206 struct drm_gem_flink arg = {0,};
209 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg))
211 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
212 "error %s:%d fail to get flink gem=%d\n",
213 getpid(), __FUNCTION__, __LINE__, gem);
217 return (unsigned int)arg.name;
221 _exynos4412_bo_handle (tbm_bo_exynos4412 bo_exynos4412, int device)
223 tbm_bo_handle bo_handle;
224 memset (&bo_handle, 0x0, sizeof (uint64_t));
228 case TBM_DEVICE_DEFAULT:
230 bo_handle.u32 = (uint32_t)bo_exynos4412->gem;
233 if (!bo_exynos4412->pBase)
235 struct drm_exynos_gem_mmap arg = {0,};
237 arg.handle = bo_exynos4412->gem;
238 arg.size = bo_exynos4412->size;
239 if (drmCommandWriteRead (bo_exynos4412->fd, DRM_EXYNOS_GEM_MMAP, &arg, sizeof(arg)))
241 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
242 "error %s:%d Cannot usrptr gem=%d\n",
243 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
244 return (tbm_bo_handle) NULL;
246 bo_exynos4412->pBase = (void*)((uint32_t)arg.mapped);
249 bo_handle.ptr = (void *)bo_exynos4412->pBase;
252 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
253 "warning %s:%d(UMP not supported. Return DMABUF).\n",
254 getpid(), __FUNCTION__, __LINE__);
256 if (!bo_exynos4412->dmabuf)
258 struct drm_prime_handle arg = {0, };
260 arg.handle = bo_exynos4412->gem;
261 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
263 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
264 "error %s:%d Cannot dmabuf=%d\n",
265 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
266 return (tbm_bo_handle) NULL;
268 bo_exynos4412->dmabuf = arg.fd;
271 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
274 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
275 "error %s:%d Not supported device:%d\n",
276 getpid(), __FUNCTION__, __LINE__, device);
277 bo_handle.ptr = (void *) NULL;
285 _exynos4412_cache_flush (int fd, tbm_bo_exynos4412 bo_exynos4412, int flags)
287 struct drm_exynos_gem_cache_op cache_op = {0, };
290 /* if bo_exynos4412 is null, do cache_flush_all */
294 cache_op.usr_addr = (uint64_t)((uint32_t)bo_exynos4412->pBase);
295 cache_op.size = bo_exynos4412->size;
299 flags = TBM_CACHE_FLUSH_ALL;
301 cache_op.usr_addr = 0;
305 if (flags & TBM_CACHE_INV)
307 if(flags & TBM_CACHE_ALL)
308 cache_op.flags |= EXYNOS_DRM_CACHE_INV_ALL;
310 cache_op.flags |= EXYNOS_DRM_CACHE_INV_RANGE;
313 if (flags & TBM_CACHE_CLN)
315 if(flags & TBM_CACHE_ALL)
316 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_ALL;
318 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_RANGE;
321 if(flags & TBM_CACHE_ALL)
322 cache_op.flags |= EXYNOS_DRM_ALL_CACHES_CORES;
324 ret = drmCommandWriteRead (fd, DRM_EXYNOS_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
327 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
328 "error %s:%d fail to flush the cache.\n",
329 getpid(), __FUNCTION__, __LINE__);
337 tbm_exynos4412_bo_size (tbm_bo bo)
339 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
341 tbm_bo_exynos4412 bo_exynos4412;
343 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
345 return bo_exynos4412->size;
349 tbm_exynos4412_bo_alloc (tbm_bo bo, int size, int flags)
351 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
353 tbm_bo_exynos4412 bo_exynos4412;
354 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
355 unsigned int exynos_flags;
357 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
358 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
360 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
363 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
364 "error %s:%d fail to allocate the bo private\n",
365 getpid(), __FUNCTION__, __LINE__);
369 exynos_flags = _get_exynos_flag_from_tbm (flags);
370 if((flags & TBM_BO_SCANOUT) &&
373 exynos_flags |= EXYNOS_BO_NONCONTIG;
376 struct drm_exynos_gem_create arg = {0, };
378 arg.flags = exynos_flags;
379 if (drmCommandWriteRead(bufmgr_exynos4412->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg)))
381 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
382 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
383 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
384 free (bo_exynos4412);
388 bo_exynos4412->fd = bufmgr_exynos4412->fd;
389 bo_exynos4412->gem = arg.handle;
390 bo_exynos4412->size = size;
391 bo_exynos4412->flags_tbm = flags;
392 bo_exynos4412->flags_exynos = exynos_flags;
393 bo_exynos4412->name = _get_name (bo_exynos4412->fd, bo_exynos4412->gem);
395 pthread_mutex_init(&bo_exynos4412->mutex, NULL);
397 if (bufmgr_exynos4412->use_dma_fence
398 && !bo_exynos4412->dmabuf)
400 struct drm_prime_handle arg = {0, };
402 arg.handle = bo_exynos4412->gem;
403 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
405 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
406 "error %s:%d Cannot dmabuf=%d\n",
407 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
408 free (bo_exynos4412);
411 bo_exynos4412->dmabuf = arg.fd;
415 PrivGem* privGem = calloc (1, sizeof(PrivGem));
416 privGem->ref_count = 1;
417 if (drmHashInsert(bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
419 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
420 "error %s:%d Cannot insert bo to Hash(%d)\n",
421 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
424 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
425 __FUNCTION__, bo_exynos4412->size,
426 bo_exynos4412->gem, bo_exynos4412->name,
427 flags, exynos_flags);
429 return (void *)bo_exynos4412;
433 tbm_exynos4412_bo_free(tbm_bo bo)
435 tbm_bo_exynos4412 bo_exynos4412;
436 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
441 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
442 EXYNOS4412_RETURN_IF_FAIL (bufmgr_exynos4412!=NULL);
444 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
445 EXYNOS4412_RETURN_IF_FAIL (bo_exynos4412!=NULL);
447 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d)\n",
448 getpid(), __FUNCTION__, bo_exynos4412->size, bo_exynos4412->gem, bo_exynos4412->name);
450 if (bo_exynos4412->pBase)
452 if (munmap(bo_exynos4412->pBase, bo_exynos4412->size) == -1)
454 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
456 getpid(), __FUNCTION__, __LINE__);
461 if (bo_exynos4412->dmabuf)
463 close (bo_exynos4412->dmabuf);
464 bo_exynos4412->dmabuf = 0;
467 /* delete bo from hash */
468 PrivGem *privGem = NULL;
471 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
474 privGem->ref_count--;
475 if (privGem->ref_count == 0)
477 drmHashDelete (bufmgr_exynos4412->hashBos, bo_exynos4412->name);
484 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
485 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
486 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name, ret);
489 /* Free gem handle */
490 struct drm_gem_close arg = {0, };
491 memset (&arg, 0, sizeof(arg));
492 arg.handle = bo_exynos4412->gem;
493 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_GEM_CLOSE, &arg))
495 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
497 getpid(), __FUNCTION__, __LINE__);
500 free (bo_exynos4412);
505 tbm_exynos4412_bo_import (tbm_bo bo, unsigned int key)
507 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
509 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
510 tbm_bo_exynos4412 bo_exynos4412;
512 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
513 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
515 struct drm_gem_open arg = {0, };
516 struct drm_exynos_gem_info info = {0, };
519 if (drmIoctl(bufmgr_exynos4412->fd, DRM_IOCTL_GEM_OPEN, &arg))
521 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
522 "error %s:%d Cannot open gem name=%d\n",
523 getpid(), __FUNCTION__, __LINE__, key);
527 info.handle = arg.handle;
528 if (drmCommandWriteRead(bufmgr_exynos4412->fd,
531 sizeof(struct drm_exynos_gem_info)))
533 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
534 "error %s:%d Cannot get gem info=%d\n",
535 getpid(), __FUNCTION__, __LINE__, key);
539 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
542 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
543 "error %s:%d fail to allocate the bo private\n",
544 getpid(), __FUNCTION__, __LINE__);
548 bo_exynos4412->fd = bufmgr_exynos4412->fd;
549 bo_exynos4412->gem = arg.handle;
550 bo_exynos4412->size = arg.size;
551 bo_exynos4412->flags_exynos = info.flags;
552 bo_exynos4412->name = key;
553 bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
555 if (!bo_exynos4412->dmabuf)
557 struct drm_prime_handle arg = {0, };
559 arg.handle = bo_exynos4412->gem;
560 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
562 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
563 "error %s:%d Cannot dmabuf=%d\n",
564 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
565 free (bo_exynos4412);
568 bo_exynos4412->dmabuf = arg.fd;
572 PrivGem *privGem = NULL;
575 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
578 privGem->ref_count++;
582 privGem = calloc (1, sizeof(PrivGem));
583 privGem->ref_count = 1;
584 if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
586 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
587 "error %s:%d Cannot insert bo to Hash(%d)\n",
588 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
593 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
594 "error %s:%d Cannot insert bo to Hash(%d)\n",
595 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
598 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
599 __FUNCTION__, bo_exynos4412->size,
600 bo_exynos4412->gem, bo_exynos4412->name,
601 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
603 return (void *)bo_exynos4412;
607 tbm_exynos4412_bo_export (tbm_bo bo)
609 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
611 tbm_bo_exynos4412 bo_exynos4412;
613 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
614 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
616 if (!bo_exynos4412->name)
618 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
619 if (!bo_exynos4412->name)
621 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
622 "error %s:%d Cannot get name\n",
623 getpid(), __FUNCTION__, __LINE__);
628 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
629 __FUNCTION__, bo_exynos4412->size,
630 bo_exynos4412->gem, bo_exynos4412->name,
631 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
633 return (unsigned int)bo_exynos4412->name;
637 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
639 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
641 tbm_bo_handle bo_handle;
642 tbm_bo_exynos4412 bo_exynos4412;
644 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
645 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
647 if (!bo_exynos4412->gem)
649 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
650 "error %s:%d Cannot map gem=%d\n",
651 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
652 return (tbm_bo_handle) NULL;
655 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s\n", getpid(),
656 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device]);
658 /*Get mapped bo_handle*/
659 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
660 if (bo_handle.ptr == NULL)
662 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
663 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
664 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device);
665 return (tbm_bo_handle) NULL;
672 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
674 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
676 tbm_bo_handle bo_handle;
677 tbm_bo_exynos4412 bo_exynos4412;
679 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
680 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
682 if (!bo_exynos4412->gem)
684 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
685 "error %s:%d Cannot map gem=%d\n",
686 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
687 return (tbm_bo_handle) NULL;
690 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s, %s\n", getpid(),
691 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device], STR_OPT[opt]);
693 /*Get mapped bo_handle*/
694 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
695 if (bo_handle.ptr == NULL)
697 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
698 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
699 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device, opt);
700 return (tbm_bo_handle) NULL;
707 tbm_exynos4412_bo_unmap (tbm_bo bo)
709 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
711 tbm_bo_exynos4412 bo_exynos4412;
713 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
714 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
716 if (!bo_exynos4412->gem)
719 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d) \n", getpid(),
720 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name);
726 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
728 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
729 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
731 /* cache flush is managed by kernel side when using dma-fence. */
732 if (bufmgr_exynos4412->use_dma_fence)
735 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
737 tbm_bo_exynos4412 bo_exynos4412;
739 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
740 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
742 if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
749 tbm_exynos4412_bo_get_global_key (tbm_bo bo)
751 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
753 tbm_bo_exynos4412 bo_exynos4412;
755 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
756 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
758 if (!bo_exynos4412->name)
760 if (!bo_exynos4412->gem)
763 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
766 return bo_exynos4412->name;
770 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
772 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
774 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
775 tbm_bo_exynos4412 bo_exynos4412;
776 struct dma_buf_fence fence;
779 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
780 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
782 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
783 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
785 memset(&fence, 0, sizeof(struct dma_buf_fence));
787 /* Check if the given type is valid or not. */
788 if (opt & TBM_OPTION_WRITE)
790 if (device == TBM_DEVICE_CPU)
791 fence.type = DMA_BUF_ACCESS_WRITE;
792 else if (device == TBM_DEVICE_3D)
793 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
796 DBG ("[libtbm-exynos4412:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
800 else if (opt & TBM_OPTION_READ)
802 if (device == TBM_DEVICE_CPU)
803 fence.type = DMA_BUF_ACCESS_READ;
804 else if (device == TBM_DEVICE_3D)
805 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
808 DBG ("[libtbm-exynos4412:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
814 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
818 /* Check if the tbm manager supports dma fence or not. */
819 if (!bufmgr_exynos4412->use_dma_fence)
821 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
822 "error %s:%d Not support DMA FENCE(%s)\n",
823 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
828 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
831 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
832 "error %s:%d Can not set GET FENCE(%s)\n",
833 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
837 pthread_mutex_lock(&bo_exynos4412->mutex);
839 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
841 if (bo_exynos4412->dma_fence[i].ctx == 0)
843 bo_exynos4412->dma_fence[i].type = fence.type;
844 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
848 if (i == DMA_FENCE_LIST_MAX)
850 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
851 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
852 "error %s:%d fence list is full\n",
853 getpid(), __FUNCTION__, __LINE__);
855 pthread_mutex_unlock(&bo_exynos4412->mutex);
857 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
858 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
864 tbm_exynos4412_bo_unlock(tbm_bo bo)
866 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
868 tbm_bo_exynos4412 bo_exynos4412;
869 struct dma_buf_fence fence;
872 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
873 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
875 if (!bo_exynos4412->dma_fence[0].ctx)
877 DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
881 if (!bo_exynos4412->dma_fence[0].type)
883 DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
887 pthread_mutex_lock(&bo_exynos4412->mutex);
888 fence.type = bo_exynos4412->dma_fence[0].type;
889 fence.ctx = bo_exynos4412->dma_fence[0].ctx;
891 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
893 bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
894 bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
896 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
897 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
898 pthread_mutex_unlock(&bo_exynos4412->mutex);
900 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
903 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
904 "error %s:%d Can not set PUT FENCE(%s)\n",
905 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
909 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
910 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
916 tbm_exynos4412_bufmgr_deinit (void *priv)
918 EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
920 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
922 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
924 if (bufmgr_exynos4412->hashBos)
929 while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
932 drmHashDelete (bufmgr_exynos4412->hashBos, key);
935 drmHashDestroy (bufmgr_exynos4412->hashBos);
936 bufmgr_exynos4412->hashBos = NULL;
939 free (bufmgr_exynos4412);
942 MODULEINITPPROTO (init_tbm_bufmgr_priv);
944 static TBMModuleVersionInfo Exynos4412VersRec =
951 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
954 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
956 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
957 tbm_bufmgr_backend bufmgr_backend;
962 bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
963 if (!bufmgr_exynos4412)
965 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to alloc bufmgr_exynos4412!\n", getpid());
969 bufmgr_exynos4412->fd = fd;
970 if (bufmgr_exynos4412->fd < 0)
972 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
973 free (bufmgr_exynos4412);
978 bufmgr_exynos4412->hashBos = drmHashCreate ();
980 //Check if the tbm manager supports dma fence or not.
981 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
986 length = read(fp, buf, 1);
988 if (length == 1 && buf[0] == '1')
989 bufmgr_exynos4412->use_dma_fence = 1;
994 bufmgr_backend = tbm_backend_alloc();
997 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
998 free (bufmgr_exynos4412);
1002 bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1003 bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1004 bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1005 bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1006 bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1007 bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1008 bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1009 bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1010 bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1011 bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1012 bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1013 bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1015 if (bufmgr_exynos4412->use_dma_fence)
1017 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1018 bufmgr_backend->bo_lock = NULL;
1019 bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1020 bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1024 bufmgr_backend->flags = 0;
1025 bufmgr_backend->bo_lock = NULL;
1026 bufmgr_backend->bo_unlock = NULL;
1029 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1031 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to init backend!\n", getpid());
1032 tbm_backend_free (bufmgr_backend);
1033 free (bufmgr_exynos4412);
1040 env = getenv ("TBM_EXYNOS4412_DEBUG");
1043 bDebug = atoi (env);
1044 TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1053 DBG ("[libtbm-exynos4412:%d] %s DMABUF FENCE is %s\n", getpid(),
1054 __FUNCTION__, bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1056 DBG ("[libtbm-exynos4412:%d] %s fd:%d\n", getpid(),
1057 __FUNCTION__, bufmgr_exynos4412->fd);