If drm fd is negative value, get fd with wayland protocol
[platform/adaptation/spreadtrum/libtbm-sprd.git] / src / tbm_bufmgr_sprd.c
1 /**************************************************************************
2
3 libtbm_sprd
4
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8
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:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20
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.
28
29 **************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <sys/ioctl.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #include <sys/mman.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <errno.h>
46 #include <xf86drm.h>
47 #include <tbm_bufmgr.h>
48 #include <tbm_bufmgr_backend.h>
49 #include <drm/sprd_drm.h>
50 #include <pthread.h>
51 #include <tbm_surface.h>
52 #include "tbm_wayland.h"
53
54 #define DEBUG
55
56 //#define USE_CONTIG_ONLY
57 #define USE_DMAIMPORT
58
59 #define TBM_COLOR_FORMAT_COUNT 8
60
61
62
63 #ifdef DEBUG
64 #define LOG_TAG    "TBM_BACKEND"
65 #include <dlog.h>
66 static int bDebug=0;
67
68 char* target_name()
69 {
70     FILE *f;
71     char *slash;
72     static int     initialized = 0;
73     static char app_name[128];
74
75     if ( initialized )
76         return app_name;
77
78     /* get the application name */
79     f = fopen("/proc/self/cmdline", "r");
80
81     if ( !f )
82     {
83         return 0;
84     }
85
86     memset(app_name, 0x00, sizeof(app_name));
87
88     if ( fgets(app_name, 100, f) == NULL )
89     {
90         fclose(f);
91         return 0;
92     }
93
94     fclose(f);
95
96     if ( (slash=strrchr(app_name, '/')) != NULL )
97     {
98         memmove(app_name, slash+1, strlen(slash));
99     }
100
101     initialized = 1;
102
103     return app_name;
104 }
105 #define TBM_SPRD_LOG(fmt, args...)        LOGE("\033[31m"  "[%s]" fmt "\033[0m", target_name(), ##args)
106 #define DBG(fmt, args...)        if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args)
107 #else
108 #define TBM_SPRD_LOG(...)
109 #define DBG(...)
110 #endif
111
112 #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
113
114 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
115 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128)
116 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
117
118
119 /* check condition */
120 #define SPRD_RETURN_IF_FAIL(cond) {\
121     if (!(cond)) {\
122         TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
123         return;\
124     }\
125 }
126 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
127     if (!(cond)) {\
128         TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
129         return val;\
130     }\
131 }
132
133 struct dma_buf_info {
134     unsigned long    size;
135     unsigned int    fence_supported;
136     unsigned int    padding;
137 };
138
139 #define DMA_BUF_ACCESS_READ        0x1
140 #define DMA_BUF_ACCESS_WRITE        0x2
141 #define DMA_BUF_ACCESS_DMA        0x4
142 #define DMA_BUF_ACCESS_MAX        0x8
143
144 #define DMA_FENCE_LIST_MAX         5
145
146 struct dma_buf_fence {
147     unsigned long        ctx;
148     unsigned int        type;
149 };
150
151 #define DMABUF_IOCTL_BASE    'F'
152 #define DMABUF_IOWR(nr, type)    _IOWR(DMABUF_IOCTL_BASE, nr, type)
153
154 #define DMABUF_IOCTL_GET_INFO    DMABUF_IOWR(0x00, struct dma_buf_info)
155 #define DMABUF_IOCTL_GET_FENCE    DMABUF_IOWR(0x01, struct dma_buf_fence)
156 #define DMABUF_IOCTL_PUT_FENCE    DMABUF_IOWR(0x02, struct dma_buf_fence)
157
158 typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd;
159 typedef struct _tbm_bo_sprd *tbm_bo_sprd;
160
161 typedef struct _sprd_private
162 {
163     int ref_count;
164 } PrivGem;
165
166 /* tbm buffor object for sprd */
167 struct _tbm_bo_sprd
168 {
169     int fd;
170
171     unsigned int name;    /* FLINK ID */
172
173     unsigned int gem;     /* GEM Handle */
174
175     unsigned int dmabuf;  /* fd for dmabuf */
176
177     void *pBase;          /* virtual address */
178
179     unsigned int size;
180
181     unsigned int flags_sprd;
182     unsigned int flags_tbm;
183
184     PrivGem* private;
185
186     pthread_mutex_t mutex;
187     struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
188     int device;
189     int opt;
190 };
191
192 /* tbm bufmgr private for sprd */
193 struct _tbm_bufmgr_sprd
194 {
195     int fd;
196     void* hashBos;
197
198     int use_dma_fence;
199
200     int fd_owner;
201 };
202
203 char *STR_DEVICE[]=
204 {
205     "DEF",
206     "CPU",
207     "2D",
208     "3D",
209     "MM"
210 };
211
212 char *STR_OPT[]=
213 {
214     "NONE",
215     "RD",
216     "WR",
217     "RDWR"
218 };
219
220
221 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
222                                                                     TBM_FORMAT_BGRA8888,
223                                                                     TBM_FORMAT_RGBX8888,
224                                                                     TBM_FORMAT_RGB888,
225                                                                     TBM_FORMAT_NV12,
226                                                                     TBM_FORMAT_NV21,
227                                                                     TBM_FORMAT_YUV420,
228                                                                     TBM_FORMAT_YVU420 };
229
230
231 #ifndef USE_CONTIG_ONLY
232 static unsigned int
233 _get_sprd_flag_from_tbm (unsigned int ftbm)
234 {
235     unsigned int flags = 0;
236
237 /*
238  * TBM_BO_DEFAULT  => ION_HEAP_ID_MASK_SYSTEM
239  * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
240  * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
241  * To be updated appropriately once DRM-GEM supports different heap id masks.
242  * */
243
244     if (ftbm & TBM_BO_SCANOUT)
245     {
246       flags = SPRD_BO_CONTIG;
247     }
248     else
249     {
250       flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
251     }
252
253     if (ftbm & TBM_BO_WC)
254         flags |= SPRD_BO_WC;
255     else if (ftbm & TBM_BO_NONCACHABLE)
256         flags |= SPRD_BO_NONCACHABLE;
257
258     return flags;
259 }
260
261 static unsigned int
262 _get_tbm_flag_from_sprd (unsigned int fsprd)
263 {
264     unsigned int flags = 0;
265
266     if (fsprd & SPRD_BO_NONCONTIG)
267         flags |= TBM_BO_DEFAULT;
268     else
269         flags |= TBM_BO_SCANOUT;
270
271     if (fsprd & SPRD_BO_WC)
272         flags |= TBM_BO_WC;
273     else if (fsprd & SPRD_BO_CACHABLE)
274         flags |= TBM_BO_DEFAULT;
275     else
276         flags |= TBM_BO_NONCACHABLE;
277
278     return flags;
279 }
280 #endif
281
282 static unsigned int
283 _get_name (int fd, unsigned int gem)
284 {
285     struct drm_gem_flink arg = {0,};
286
287     arg.handle = gem;
288     if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg))
289     {
290         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
291                  "error %s:%d fail to get flink gem=%d\n",
292                  getpid(), __FUNCTION__, __LINE__, gem);
293         return 0;
294     }
295
296     return (unsigned int)arg.name;
297 }
298
299 static tbm_bo_handle
300 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
301 {
302     tbm_bo_handle bo_handle;
303     memset (&bo_handle, 0x0, sizeof (uint64_t));
304
305     switch(device)
306     {
307     case TBM_DEVICE_DEFAULT:
308     case TBM_DEVICE_2D:
309         bo_handle.u32 = (uint32_t)bo_sprd->gem;
310         break;
311     case TBM_DEVICE_CPU:
312         if (!bo_sprd->pBase)
313         {
314             struct drm_sprd_gem_mmap arg = {0,};
315
316             arg.handle = bo_sprd->gem;
317             arg.size = bo_sprd->size;
318             if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg)))
319             {
320                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
321                          "error %s:%d Cannot usrptr gem=%d\n",
322                          getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
323                 return (tbm_bo_handle) NULL;
324             }
325             bo_sprd->pBase = (void*)((uint32_t)arg.mapped);
326         }
327
328         bo_handle.ptr = (void *)bo_sprd->pBase;
329         break;
330     case TBM_DEVICE_3D:
331 #ifdef USE_DMAIMPORT
332    if (!bo_sprd->dmabuf)
333         {
334             struct drm_prime_handle arg = {0, };
335             arg.handle = bo_sprd->gem;
336             if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
337             {
338                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
339                          "error %s:%d Cannot dmabuf=%d\n",
340                          getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
341                 return (tbm_bo_handle) NULL;
342             }
343             bo_sprd->dmabuf = arg.fd;
344         }
345
346         bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
347
348 #endif
349         break;
350
351     case TBM_DEVICE_MM:
352 #ifdef USE_HEAP_ID
353         //TODO : Add ioctl for GSP MAP once available.
354     DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM:  \n", getpid(),
355          __FUNCTION_);_
356
357 #else
358         if (!bo_sprd->dmabuf)
359         {
360             struct drm_prime_handle arg = {0, };
361
362             arg.handle = bo_sprd->gem;
363             if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
364             {
365                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
366                          "error %s:%d Cannot dmabuf=%d\n",
367                          getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
368                 return (tbm_bo_handle) NULL;
369             }
370             bo_sprd->dmabuf = arg.fd;
371         }
372
373         bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
374 #endif
375         break;
376     default:
377         bo_handle.ptr = (void *) NULL;
378         break;
379     }
380
381     return bo_handle;
382 }
383
384 #ifdef USE_CACHE
385 static int
386 _sprd_cache_flush (int fd, tbm_bo_sprd bo_sprd, int flags)
387 {
388     struct drm_sprd_gem_cache_op cache_op = {0, };
389     int ret;
390
391     /* if bo_sprd is null, do cache_flush_all */
392     if(bo_sprd)
393     {
394         cache_op.flags = 0;
395         cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
396         cache_op.size = bo_sprd->size;
397     }
398     else
399     {
400         flags = TBM_CACHE_FLUSH_ALL;
401         cache_op.flags = 0;
402         cache_op.usr_addr = 0;
403         cache_op.size = 0;
404     }
405
406     if (flags & TBM_CACHE_INV)
407     {
408         if(flags & TBM_CACHE_ALL)
409             cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
410         else
411             cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
412     }
413
414     if (flags & TBM_CACHE_CLN)
415     {
416         if(flags & TBM_CACHE_ALL)
417             cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
418         else
419             cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
420     }
421
422     if(flags & TBM_CACHE_ALL)
423         cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
424
425     ret = drmCommandWriteRead (fd, DRM_SPRD_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
426     if (ret)
427     {
428         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
429                  "error %s:%d fail to flush the cache.\n",
430                  getpid(), __FUNCTION__, __LINE__);
431         return 0;
432     }
433
434     return 1;
435 }
436 #endif
437
438 static int
439 tbm_sprd_bo_size (tbm_bo bo)
440 {
441     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
442
443     tbm_bo_sprd bo_sprd;
444
445     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
446
447     return bo_sprd->size;
448 }
449
450 static void *
451 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
452 {
453     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
454
455     tbm_bo_sprd bo_sprd;
456     tbm_bufmgr_sprd bufmgr_sprd;
457     unsigned int sprd_flags;
458
459     bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
460     SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
461
462     bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
463     if (!bo_sprd)
464     {
465         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
466                  "error %s:%d fail to allocate the bo private\n",
467                  getpid(), __FUNCTION__, __LINE__);
468         return 0;
469     }
470
471 #ifdef USE_CONTIG_ONLY
472     flags = TBM_BO_SCANOUT;
473     sprd_flags = SPRD_BO_CONTIG;
474 #else
475     sprd_flags = _get_sprd_flag_from_tbm (flags);
476     if((flags & TBM_BO_SCANOUT) &&
477         size <= 4*1024)
478     {
479         sprd_flags |= SPRD_BO_NONCONTIG;
480     }
481 #endif // USE_CONTIG_ONLY
482     struct drm_sprd_gem_create arg = {0, };
483     arg.size = size;
484     arg.flags = sprd_flags;
485     if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg, sizeof(arg)))
486     {
487         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
488                  "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
489                  getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
490         free (bo_sprd);
491         return 0;
492     }
493
494     bo_sprd->fd = bufmgr_sprd->fd;
495     bo_sprd->gem = arg.handle;
496     bo_sprd->size = size;
497     bo_sprd->flags_tbm = flags;
498     bo_sprd->flags_sprd = sprd_flags;
499     bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
500
501     pthread_mutex_init(&bo_sprd->mutex, NULL);
502
503     if (bufmgr_sprd->use_dma_fence
504         && !bo_sprd->dmabuf)
505     {
506         struct drm_prime_handle arg = {0, };
507
508         arg.handle = bo_sprd->gem;
509         if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
510         {
511             TBM_SPRD_LOG ("[libtbm-sprd:%d] "
512                     "error %s:%d Cannot dmabuf=%d\n",
513                     getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
514             free (bo_sprd);
515             return 0;
516         }
517         bo_sprd->dmabuf = arg.fd;
518     }
519
520     /* add bo to hash */
521     PrivGem* privGem = calloc (1, sizeof(PrivGem));
522     privGem->ref_count = 1;
523     if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
524     {
525         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
526                  "error %s:%d Cannot insert bo to Hash(%d)\n",
527                  getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
528     }
529
530     DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
531          __FUNCTION__, bo_sprd->size,
532          bo_sprd->gem, bo_sprd->name,
533          flags, sprd_flags);
534
535     return (void *)bo_sprd;
536 }
537
538 static void
539 tbm_sprd_bo_free(tbm_bo bo)
540 {
541     tbm_bo_sprd bo_sprd;
542     tbm_bufmgr_sprd bufmgr_sprd;
543
544     if (!bo)
545         return;
546
547     bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
548     SPRD_RETURN_IF_FAIL (bufmgr_sprd!=NULL);
549
550     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
551     SPRD_RETURN_IF_FAIL (bo_sprd!=NULL);
552
553     DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
554          getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
555
556     if (bo_sprd->pBase)
557     {
558         if (munmap(bo_sprd->pBase, bo_sprd->size) == -1)
559         {
560             TBM_SPRD_LOG ("[libtbm-sprd:%d] "
561                      "error %s:%d\n",
562                      getpid(), __FUNCTION__, __LINE__);
563         }
564     }
565
566     /* close dmabuf */
567     if (bo_sprd->dmabuf)
568     {
569         close (bo_sprd->dmabuf);
570         bo_sprd->dmabuf = 0;
571     }
572
573     /* delete bo from hash */
574     PrivGem *privGem = NULL;
575     int ret;
576
577     ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
578     if (ret == 0)
579     {
580         privGem->ref_count--;
581         if (privGem->ref_count == 0)
582         {
583             drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
584             free (privGem);
585             privGem = NULL;
586         }
587     }
588     else
589     {
590         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
591                  "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
592                  getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
593     }
594
595     /* Free gem handle */
596     struct drm_gem_close arg = {0, };
597     memset (&arg, 0, sizeof(arg));
598     arg.handle = bo_sprd->gem;
599     if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg))
600     {
601         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
602                  "error %s:%d\n",
603                  getpid(), __FUNCTION__, __LINE__);
604     }
605
606     free (bo_sprd);
607 }
608
609
610 static void *
611 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
612 {
613     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
614
615     tbm_bufmgr_sprd bufmgr_sprd;
616     tbm_bo_sprd bo_sprd;
617
618     bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
619     SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
620
621     struct drm_gem_open arg = {0, };
622     struct drm_sprd_gem_info info = {0, };
623
624     arg.name = key;
625     if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg))
626     {
627         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
628                 "error %s:%d Cannot open gem name=%d\n",
629                 getpid(), __FUNCTION__, __LINE__, key);
630         return 0;
631     }
632
633     info.handle = arg.handle;
634     if (drmCommandWriteRead(bufmgr_sprd->fd,
635                            DRM_SPRD_GEM_GET,
636                            &info,
637                            sizeof(struct drm_sprd_gem_info)))
638     {
639         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
640                 "error %s:%d Cannot get gem info=%d\n",
641                 getpid(), __FUNCTION__, __LINE__, key);
642         return 0;
643     }
644
645     bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
646     if (!bo_sprd)
647     {
648         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
649                 "error %s:%d fail to allocate the bo private\n",
650                 getpid(), __FUNCTION__, __LINE__);
651         return 0;
652     }
653
654     bo_sprd->fd = bufmgr_sprd->fd;
655     bo_sprd->gem = arg.handle;
656     bo_sprd->size = arg.size;
657     bo_sprd->flags_sprd = info.flags;
658     bo_sprd->name = key;
659 #ifdef USE_CONTIG_ONLY
660     bo_sprd->flags_sprd = SPRD_BO_CONTIG;
661     bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
662 #else
663     bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
664 #endif
665
666
667     if (!bo_sprd->dmabuf)
668     {
669         struct drm_prime_handle arg = {0, };
670
671         arg.handle = bo_sprd->gem;
672         if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
673         {
674             TBM_SPRD_LOG ("[libtbm-sprd:%d] "
675                     "error %s:%d Cannot dmabuf=%d\n",
676                     getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
677             free (bo_sprd);
678             return 0;
679         }
680         bo_sprd->dmabuf = arg.fd;
681     }
682
683     /* add bo to hash */
684     PrivGem *privGem = NULL;
685     int ret;
686
687     ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
688     if (ret == 0)
689     {
690         privGem->ref_count++;
691     }
692     else if (ret == 1)
693     {
694         privGem = calloc (1, sizeof(PrivGem));
695         privGem->ref_count = 1;
696         if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
697         {
698             TBM_SPRD_LOG ("[libtbm-sprd:%d] "
699                     "error %s:%d Cannot insert bo to Hash(%d)\n",
700                     getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
701         }
702     }
703     else
704     {
705         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
706                 "error %s:%d Cannot insert bo to Hash(%d)\n",
707                 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
708     }
709
710     DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
711          __FUNCTION__, bo_sprd->size,
712          bo_sprd->gem, bo_sprd->name,
713          bo_sprd->flags_tbm, bo_sprd->flags_sprd);
714
715     return (void *)bo_sprd;
716 }
717
718 static void *
719 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
720 {
721     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
722
723     tbm_bufmgr_sprd bufmgr_sprd;
724     tbm_bo_sprd bo_sprd;
725
726     bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
727     SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
728
729     unsigned int gem = 0;
730     unsigned int real_size = -1;
731     struct drm_sprd_gem_info info = {0, };
732
733     //getting handle from fd
734     struct drm_prime_handle arg = {0, };
735
736     arg.fd = key;
737     arg.flags = 0;
738     if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
739     {
740         TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
741                  bo, arg.fd, strerror(errno));
742         return NULL;
743     }
744     gem = arg.handle;
745
746     /* Determine size of bo.  The fd-to-handle ioctl really should
747      * return the size, but it doesn't.  If we have kernel 3.12 or
748      * later, we can lseek on the prime fd to get the size.  Older
749      * kernels will just fail, in which case we fall back to the
750      * provided (estimated or guess size). */
751     real_size = lseek(key, 0, SEEK_END);
752
753     info.handle = gem;
754     if (drmCommandWriteRead(bufmgr_sprd->fd,
755                            DRM_SPRD_GEM_GET,
756                            &info,
757                            sizeof(struct drm_sprd_gem_info)))
758     {
759         TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
760                 bo, gem, key, strerror(errno));
761         return 0;
762     }
763
764     if (real_size == -1)
765        real_size = info.size;
766
767     bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
768     if (!bo_sprd)
769     {
770         TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
771         return 0;
772     }
773
774     bo_sprd->fd = bufmgr_sprd->fd;
775     bo_sprd->gem = gem;
776     bo_sprd->size = real_size;
777     bo_sprd->flags_sprd = info.flags;
778     bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
779
780     bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
781     if (!bo_sprd->name)
782     {
783         TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
784             bo, gem, key, strerror(errno));
785         free (bo_sprd);
786         return 0;
787     }
788
789     /* add bo to hash */
790     PrivGem *privGem = NULL;
791     int ret;
792
793     ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
794     if (ret == 0)
795     {
796         privGem->ref_count++;
797     }
798     else if (ret == 1)
799     {
800         privGem = calloc (1, sizeof(PrivGem));
801         if (!privGem)
802         {
803             TBM_SPRD_LOG ("[libtbm-sprd:%d] "
804                     "error %s:%d Fail to calloc privGem\n",
805                     getpid(), __FUNCTION__, __LINE__);
806             free (bo_sprd);
807             return 0;
808         }
809
810         privGem->ref_count = 1;
811         if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
812         {
813             TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
814                 bo, bo_sprd->name, gem, key);
815         }
816     }
817     else
818     {
819         TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
820                 bo, bo_sprd->name, gem, key);
821     }
822
823     DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
824          bo,
825          bo_sprd->gem, bo_sprd->name,
826          bo_sprd->dmabuf,
827          key,
828          bo_sprd->flags_tbm, bo_sprd->flags_sprd,
829          bo_sprd->size);
830
831     return (void *)bo_sprd;
832 }
833
834 static unsigned int
835 tbm_sprd_bo_export (tbm_bo bo)
836 {
837     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
838
839     tbm_bo_sprd bo_sprd;
840
841     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
842     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
843
844     if (!bo_sprd->name)
845     {
846         bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
847         if (!bo_sprd->name)
848         {
849             TBM_SPRD_LOG ("[libtbm-sprd:%d] "
850                     "error %s:%d Cannot get name\n",
851                     getpid(), __FUNCTION__, __LINE__);
852             return 0;
853         }
854     }
855
856     DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
857          __FUNCTION__, bo_sprd->size,
858          bo_sprd->gem, bo_sprd->name,
859          bo_sprd->flags_tbm, bo_sprd->flags_sprd);
860
861     return (unsigned int)bo_sprd->name;
862 }
863
864 tbm_fd
865 tbm_sprd_bo_export_fd (tbm_bo bo)
866 {
867     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, -1);
868
869     tbm_bo_sprd bo_sprd;
870     int ret;
871
872     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
873     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, -1);
874
875     struct drm_prime_handle arg = {0, };
876
877     arg.handle = bo_sprd->gem;
878     ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
879     if (ret)
880     {
881         TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
882             bo, bo_sprd->gem, strerror(errno));
883         return (tbm_fd) ret;
884     }
885
886     DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
887          bo,
888          bo_sprd->gem, bo_sprd->name,
889          bo_sprd->dmabuf,
890          arg.fd,
891          bo_sprd->flags_tbm, bo_sprd->flags_sprd,
892          bo_sprd->size);
893
894     return (tbm_fd)arg.fd;
895 }
896
897
898 static tbm_bo_handle
899 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
900 {
901     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
902
903     tbm_bo_handle bo_handle;
904     tbm_bo_sprd bo_sprd;
905
906     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
907     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
908
909     if (!bo_sprd->gem)
910     {
911         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
912                 "error %s:%d Cannot map gem=%d\n",
913                 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
914         return (tbm_bo_handle) NULL;
915     }
916
917     DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
918          __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
919
920     /*Get mapped bo_handle*/
921     bo_handle = _sprd_bo_handle (bo_sprd, device);
922     if (bo_handle.ptr == NULL)
923     {
924         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
925                 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
926                 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
927         return (tbm_bo_handle) NULL;
928     }
929
930     return bo_handle;
931 }
932
933 static tbm_bo_handle
934 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
935 {
936     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
937
938     tbm_bo_handle bo_handle;
939     tbm_bo_sprd bo_sprd;
940
941     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
942     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
943
944     if (!bo_sprd->gem)
945     {
946         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
947                 "error %s:%d Cannot map gem=%d\n",
948                 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
949         return (tbm_bo_handle) NULL;
950     }
951
952     DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
953          __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
954
955     /*Get mapped bo_handle*/
956     bo_handle = _sprd_bo_handle (bo_sprd, device);
957     if (bo_handle.ptr == NULL)
958     {
959         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
960                 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
961                 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
962         return (tbm_bo_handle) NULL;
963     }
964
965     return bo_handle;
966 }
967
968 static int
969 tbm_sprd_bo_unmap (tbm_bo bo)
970 {
971     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
972
973     tbm_bo_sprd bo_sprd;
974
975     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
976     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
977
978     if (!bo_sprd->gem)
979         return 0;
980
981     DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
982          __FUNCTION__, bo_sprd->gem, bo_sprd->name);
983
984     return 1;
985 }
986
987 static int
988 tbm_sprd_bo_cache_flush (tbm_bo bo, int flags)
989 {
990     tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
991     SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
992
993     /* cache flush is managed by kernel side when using dma-fence. */
994     if (bufmgr_sprd->use_dma_fence)
995        return 1;
996
997     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
998
999     tbm_bo_sprd bo_sprd;
1000
1001     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1002     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1003
1004 #ifdef USE_CACHE
1005     if (!_sprd_cache_flush(bo_sprd->fd, bo_sprd, flags))
1006         return 0;
1007 #endif
1008
1009     return 1;
1010 }
1011
1012 static int
1013 tbm_sprd_bo_get_global_key (tbm_bo bo)
1014 {
1015     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1016
1017     tbm_bo_sprd bo_sprd;
1018
1019     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1020     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1021
1022     if (!bo_sprd->name)
1023     {
1024         if (!bo_sprd->gem)
1025             return 0;
1026
1027         bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1028     }
1029
1030     return bo_sprd->name;
1031 }
1032
1033 static int
1034 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1035 {
1036     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1037
1038 #if USE_BACKEND_LOCK
1039     tbm_bufmgr_sprd bufmgr_sprd;
1040     tbm_bo_sprd bo_sprd;
1041     struct dma_buf_fence fence;
1042     int ret=0;
1043
1044     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1045     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1046
1047     bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1048     SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
1049
1050     memset(&fence, 0, sizeof(struct dma_buf_fence));
1051
1052     /* Check if the given type is valid or not. */
1053     if (opt & TBM_OPTION_WRITE)
1054     {
1055         if (device == TBM_DEVICE_CPU)
1056             fence.type = DMA_BUF_ACCESS_WRITE;
1057         else if (device == TBM_DEVICE_3D)
1058             fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1059         else
1060         {
1061             DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1062             return 0;
1063         }
1064     }
1065     else if (opt & TBM_OPTION_READ)
1066     {
1067         if (device == TBM_DEVICE_CPU)
1068             fence.type = DMA_BUF_ACCESS_READ;
1069         else if (device == TBM_DEVICE_3D)
1070             fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1071         else
1072         {
1073             DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1074             return 0;
1075         }
1076     }
1077     else
1078     {
1079         TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
1080         return 0;
1081     }
1082
1083     /* Check if the tbm manager supports dma fence or not. */
1084     if (!bufmgr_sprd->use_dma_fence)
1085     {
1086         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1087                 "error %s:%d  Not support DMA FENCE(%s)\n",
1088                 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1089         return 0;
1090
1091     }
1092
1093     ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1094     if (ret < 0)
1095     {
1096         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1097                 "error %s:%d  Can not set GET FENCE(%s)\n",
1098                 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1099         return 0;
1100     }
1101
1102     pthread_mutex_lock(&bo_sprd->mutex);
1103     int i;
1104     for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1105     {
1106         if (bo_sprd->dma_fence[i].ctx == 0)
1107         {
1108             bo_sprd->dma_fence[i].type = fence.type;
1109             bo_sprd->dma_fence[i].ctx = fence.ctx;
1110             break;
1111         }
1112     }
1113     if (i == DMA_FENCE_LIST_MAX)
1114     {
1115         //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1116         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1117                 "error %s:%d  fence list is full\n",
1118                 getpid(), __FUNCTION__, __LINE__);
1119     }
1120     pthread_mutex_unlock(&bo_sprd->mutex);
1121
1122     DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1123             __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1124
1125 #endif
1126     return 1;
1127 }
1128
1129 static int
1130 tbm_sprd_bo_unlock(tbm_bo bo)
1131 {
1132     SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1133
1134 #if USE_BACKEND_LOCK
1135     tbm_bo_sprd bo_sprd;
1136     struct dma_buf_fence fence;
1137     int ret=0;
1138
1139     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1140     SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1141
1142     if (!bo_sprd->dma_fence[0].ctx)
1143     {
1144         DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1145         return 0;
1146     }
1147
1148     if (!bo_sprd->dma_fence[0].type)
1149     {
1150         DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1151         return 0;
1152     }
1153
1154     pthread_mutex_lock(&bo_sprd->mutex);
1155     fence.type = bo_sprd->dma_fence[0].type;
1156     fence.ctx = bo_sprd->dma_fence[0].ctx;
1157     int i;
1158     for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1159     {
1160         bo_sprd->dma_fence[i-1].type = bo_sprd->dma_fence[i].type;
1161         bo_sprd->dma_fence[i-1].ctx = bo_sprd->dma_fence[i].ctx;
1162     }
1163     bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1164     bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1165     pthread_mutex_unlock(&bo_sprd->mutex);
1166
1167     ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1168     if (ret < 0)
1169     {
1170         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1171                 "error %s:%d  Can not set PUT FENCE(%s)\n",
1172                 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1173         return 0;
1174     }
1175
1176     DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1177             __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1178
1179 #endif
1180     return 1;
1181 }
1182
1183 static void
1184 tbm_sprd_bufmgr_deinit (void *priv)
1185 {
1186     SPRD_RETURN_IF_FAIL (priv!=NULL);
1187
1188     tbm_bufmgr_sprd bufmgr_sprd;
1189
1190     bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1191
1192     if (bufmgr_sprd->hashBos)
1193     {
1194         unsigned long key;
1195         void *value;
1196
1197         while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0)
1198         {
1199             free (value);
1200             drmHashDelete (bufmgr_sprd->hashBos, key);
1201         }
1202
1203         drmHashDestroy (bufmgr_sprd->hashBos);
1204         bufmgr_sprd->hashBos = NULL;
1205     }
1206
1207     if (bufmgr_sprd->fd_owner)
1208         close (bufmgr_sprd->fd_owner);
1209
1210     free (bufmgr_sprd);
1211 }
1212
1213 int
1214 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1215 {
1216     uint32_t* color_formats=NULL;
1217
1218     color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1219
1220     if( color_formats == NULL )
1221     {
1222         return 0;
1223     }
1224     memcpy( color_formats, tbm_sprd_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1225
1226
1227     *formats = color_formats;
1228     *num = TBM_COLOR_FORMAT_COUNT;
1229
1230
1231     return 1;
1232 }
1233
1234
1235 /**
1236  * @brief get the plane data of the surface.
1237  * @param[in] surface : the surface
1238  * @param[in] width : the width of the surface
1239  * @param[in] height : the height of the surface
1240  * @param[in] format : the format of the surface
1241  * @param[in] plane_idx : the format of the surface
1242  * @param[out] size : the size of the plane
1243  * @param[out] offset : the offset of the plane
1244  * @param[out] pitch : the pitch of the plane
1245  * @param[out] padding : the padding of the plane
1246  * @return 1 if this function succeeds, otherwise 0.
1247  */
1248 int
1249 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)
1250 {
1251     int ret = 1;
1252     int bpp;
1253     int _offset =0;
1254     int _pitch =0;
1255     int _size =0;
1256     int _bo_idx = 0;
1257
1258     switch(format)
1259     {
1260         /* 16 bpp RGB */
1261         case TBM_FORMAT_XRGB4444:
1262         case TBM_FORMAT_XBGR4444:
1263         case TBM_FORMAT_RGBX4444:
1264         case TBM_FORMAT_BGRX4444:
1265         case TBM_FORMAT_ARGB4444:
1266         case TBM_FORMAT_ABGR4444:
1267         case TBM_FORMAT_RGBA4444:
1268         case TBM_FORMAT_BGRA4444:
1269         case TBM_FORMAT_XRGB1555:
1270         case TBM_FORMAT_XBGR1555:
1271         case TBM_FORMAT_RGBX5551:
1272         case TBM_FORMAT_BGRX5551:
1273         case TBM_FORMAT_ARGB1555:
1274         case TBM_FORMAT_ABGR1555:
1275         case TBM_FORMAT_RGBA5551:
1276         case TBM_FORMAT_BGRA5551:
1277         case TBM_FORMAT_RGB565:
1278             bpp = 16;
1279             _offset = 0;
1280             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1281             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1282             _bo_idx = 0;
1283             break;
1284         /* 24 bpp RGB */
1285         case TBM_FORMAT_RGB888:
1286         case TBM_FORMAT_BGR888:
1287             bpp = 24;
1288             _offset = 0;
1289             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1290             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1291             _bo_idx = 0;
1292             break;
1293         /* 32 bpp RGB */
1294         case TBM_FORMAT_XRGB8888:
1295         case TBM_FORMAT_XBGR8888:
1296         case TBM_FORMAT_RGBX8888:
1297         case TBM_FORMAT_BGRX8888:
1298         case TBM_FORMAT_ARGB8888:
1299         case TBM_FORMAT_ABGR8888:
1300         case TBM_FORMAT_RGBA8888:
1301         case TBM_FORMAT_BGRA8888:
1302             bpp = 32;
1303             _offset = 0;
1304             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1305             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1306             _bo_idx = 0;
1307             break;
1308
1309         /* packed YCbCr */
1310         case TBM_FORMAT_YUYV:
1311         case TBM_FORMAT_YVYU:
1312         case TBM_FORMAT_UYVY:
1313         case TBM_FORMAT_VYUY:
1314         case TBM_FORMAT_AYUV:
1315             bpp = 32;
1316             _offset = 0;
1317             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1318             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1319             _bo_idx = 0;
1320             break;
1321
1322         /*
1323         * 2 plane YCbCr
1324         * index 0 = Y plane, [7:0] Y
1325         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1326         * or
1327         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1328         */
1329         case TBM_FORMAT_NV12:
1330         case TBM_FORMAT_NV21:
1331             bpp = 12;
1332             if(plane_idx == 0)
1333             {
1334                 _offset = 0;
1335                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1336                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1337                 _bo_idx = 0;
1338             }
1339             else if( plane_idx ==1 )
1340             {
1341                 _offset = width*height;
1342                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1343                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1344                 _bo_idx = 0;
1345             }
1346             break;
1347
1348         case TBM_FORMAT_NV16:
1349         case TBM_FORMAT_NV61:
1350             bpp = 16;
1351             //if(plane_idx == 0)
1352             {
1353                 _offset = 0;
1354         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1355                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1356                 _bo_idx = 0;
1357         if(plane_idx == 0)
1358             break;
1359             }
1360             //else if( plane_idx ==1 )
1361             {
1362                 _offset += _size;
1363         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1364                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1365                 _bo_idx = 0;
1366             }
1367             break;
1368
1369         /*
1370         * 3 plane YCbCr
1371         * index 0: Y plane, [7:0] Y
1372         * index 1: Cb plane, [7:0] Cb
1373         * index 2: Cr plane, [7:0] Cr
1374         * or
1375         * index 1: Cr plane, [7:0] Cr
1376         * index 2: Cb plane, [7:0] Cb
1377         */
1378         /*
1379         NATIVE_BUFFER_FORMAT_YV12
1380         NATIVE_BUFFER_FORMAT_I420
1381         */
1382         case TBM_FORMAT_YUV410:
1383         case TBM_FORMAT_YVU410:
1384             bpp = 9;
1385             break;
1386         case TBM_FORMAT_YUV411:
1387         case TBM_FORMAT_YVU411:
1388         case TBM_FORMAT_YUV420:
1389         case TBM_FORMAT_YVU420:
1390             bpp = 12;
1391             //if(plane_idx == 0)
1392             {
1393                 _offset = 0;
1394                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1395                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1396                 _bo_idx = 0;
1397                 if(plane_idx == 0)
1398                     break;
1399             }
1400             //else if( plane_idx == 1 )
1401             {
1402                 _offset += _size;
1403                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1404                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1405                 _bo_idx = 0;
1406                 if(plane_idx == 1)
1407                     break;
1408             }
1409             //else if (plane_idx == 2 )
1410             {
1411                 _offset += _size;
1412                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1413                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1414                 _bo_idx = 0;
1415             }
1416             break;
1417         case TBM_FORMAT_YUV422:
1418         case TBM_FORMAT_YVU422:
1419             bpp = 16;
1420             //if(plane_idx == 0)
1421             {
1422                 _offset = 0;
1423                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1424                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1425                 _bo_idx = 0;
1426                 if(plane_idx == 0)
1427                     break;
1428             }
1429             //else if( plane_idx == 1 )
1430             {
1431                 _offset += _size;
1432                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1433                 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1434                 _bo_idx = 0;
1435                 if(plane_idx == 1)
1436                     break;
1437             }
1438             //else if (plane_idx == 2 )
1439             {
1440                 _offset += _size;
1441                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1442                 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1443                 _bo_idx = 0;
1444             }
1445             break;
1446         case TBM_FORMAT_YUV444:
1447         case TBM_FORMAT_YVU444:
1448             bpp = 24;
1449             //if(plane_idx == 0)
1450             {
1451                 _offset = 0;
1452                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1453                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1454                 _bo_idx = 0;
1455                 if(plane_idx == 0)
1456                     break;
1457             }
1458             //else if( plane_idx == 1 )
1459             {
1460                 _offset += _size;
1461                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1462                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1463                 _bo_idx = 0;
1464                 if(plane_idx == 1)
1465                     break;
1466             }
1467             //else if (plane_idx == 2 )
1468             {
1469                 _offset += _size;
1470                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1471                _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1472                 _bo_idx = 0;
1473             }
1474             break;
1475         default:
1476             bpp = 0;
1477             break;
1478     }
1479
1480     *size = _size;
1481     *offset = _offset;
1482     *pitch = _pitch;
1483     *bo_idx = _bo_idx;
1484
1485     return ret;
1486 }
1487 /**
1488 * @brief get the size of the surface with a format.
1489 * @param[in] surface : the surface
1490 * @param[in] width : the width of the surface
1491 * @param[in] height : the height of the surface
1492 * @param[in] format : the format of the surface
1493 * @return size of the surface if this function succeeds, otherwise 0.
1494 */
1495
1496 int
1497 tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1498 {
1499     int ret = 0;
1500     int bpp = 0;
1501     int _pitch =0;
1502     int _size =0;
1503     int align =TBM_SURFACE_ALIGNMENT_PLANE;
1504
1505
1506     switch(format)
1507     {
1508         /* 16 bpp RGB */
1509         case TBM_FORMAT_XRGB4444:
1510         case TBM_FORMAT_XBGR4444:
1511         case TBM_FORMAT_RGBX4444:
1512         case TBM_FORMAT_BGRX4444:
1513         case TBM_FORMAT_ARGB4444:
1514         case TBM_FORMAT_ABGR4444:
1515         case TBM_FORMAT_RGBA4444:
1516         case TBM_FORMAT_BGRA4444:
1517         case TBM_FORMAT_XRGB1555:
1518         case TBM_FORMAT_XBGR1555:
1519         case TBM_FORMAT_RGBX5551:
1520         case TBM_FORMAT_BGRX5551:
1521         case TBM_FORMAT_ARGB1555:
1522         case TBM_FORMAT_ABGR1555:
1523         case TBM_FORMAT_RGBA5551:
1524         case TBM_FORMAT_BGRA5551:
1525         case TBM_FORMAT_RGB565:
1526             bpp = 16;
1527             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1528             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1529             break;
1530         /* 24 bpp RGB */
1531         case TBM_FORMAT_RGB888:
1532         case TBM_FORMAT_BGR888:
1533             bpp = 24;
1534             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1535             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1536             break;
1537         /* 32 bpp RGB */
1538         case TBM_FORMAT_XRGB8888:
1539         case TBM_FORMAT_XBGR8888:
1540         case TBM_FORMAT_RGBX8888:
1541         case TBM_FORMAT_BGRX8888:
1542         case TBM_FORMAT_ARGB8888:
1543         case TBM_FORMAT_ABGR8888:
1544         case TBM_FORMAT_RGBA8888:
1545         case TBM_FORMAT_BGRA8888:
1546             bpp = 32;
1547             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1548             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1549             break;
1550         /* packed YCbCr */
1551         case TBM_FORMAT_YUYV:
1552         case TBM_FORMAT_YVYU:
1553         case TBM_FORMAT_UYVY:
1554         case TBM_FORMAT_VYUY:
1555         case TBM_FORMAT_AYUV:
1556             bpp = 32;
1557             _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1558             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1559             break;
1560         /*
1561         * 2 plane YCbCr
1562         * index 0 = Y plane, [7:0] Y
1563         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1564         * or
1565         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1566         */
1567         case TBM_FORMAT_NV12:
1568         case TBM_FORMAT_NV21:
1569             bpp = 12;
1570             //plane_idx == 0
1571             {
1572                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1573                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1574             }
1575             //plane_idx ==1
1576             {
1577                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1578                 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1579             }
1580             break;
1581         case TBM_FORMAT_NV16:
1582         case TBM_FORMAT_NV61:
1583             bpp = 16;
1584             //plane_idx == 0
1585             {
1586                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1587                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1588             }
1589             //plane_idx ==1
1590             {
1591                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1592                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1593             }
1594
1595             break;
1596         /*
1597         * 3 plane YCbCr
1598         * index 0: Y plane, [7:0] Y
1599         * index 1: Cb plane, [7:0] Cb
1600         * index 2: Cr plane, [7:0] Cr
1601         * or
1602         * index 1: Cr plane, [7:0] Cr
1603         * index 2: Cb plane, [7:0] Cb
1604         */
1605         case TBM_FORMAT_YUV410:
1606         case TBM_FORMAT_YVU410:
1607             bpp = 9;
1608         align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1609             break;
1610         case TBM_FORMAT_YUV411:
1611         case TBM_FORMAT_YVU411:
1612         case TBM_FORMAT_YUV420:
1613         case TBM_FORMAT_YVU420:
1614             bpp = 12;
1615         //plane_idx == 0
1616             {
1617         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1618                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1619             }
1620             //plane_idx == 1
1621             {
1622         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1623         _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1624             }
1625             //plane_idx == 2
1626             {
1627         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1628                 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1629             }
1630
1631             break;
1632         case TBM_FORMAT_YUV422:
1633         case TBM_FORMAT_YVU422:
1634             bpp = 16;
1635         //plane_idx == 0
1636             {
1637         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1638                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1639             }
1640             //plane_idx == 1
1641             {
1642         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1643         _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1644             }
1645             //plane_idx == 2
1646             {
1647         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1648                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1649             }
1650             break;
1651         case TBM_FORMAT_YUV444:
1652         case TBM_FORMAT_YVU444:
1653             bpp = 24;
1654         align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1655             break;
1656
1657         default:
1658             bpp = 0;
1659             break;
1660     }
1661
1662     if(_size > 0)
1663         ret = _size;
1664     else
1665         ret =  SIZE_ALIGN( (width * height * bpp) >> 3, align);
1666
1667     return ret;
1668
1669 }
1670
1671 int
1672 tbm_sprd_surface_get_num_bos(tbm_format format)
1673 {
1674     int num = 0;
1675
1676     switch(format)
1677     {
1678         /* 16 bpp RGB */
1679         case TBM_FORMAT_XRGB4444:
1680         case TBM_FORMAT_XBGR4444:
1681         case TBM_FORMAT_RGBX4444:
1682         case TBM_FORMAT_BGRX4444:
1683         case TBM_FORMAT_ARGB4444:
1684         case TBM_FORMAT_ABGR4444:
1685         case TBM_FORMAT_RGBA4444:
1686         case TBM_FORMAT_BGRA4444:
1687         case TBM_FORMAT_XRGB1555:
1688         case TBM_FORMAT_XBGR1555:
1689         case TBM_FORMAT_RGBX5551:
1690         case TBM_FORMAT_BGRX5551:
1691         case TBM_FORMAT_ARGB1555:
1692         case TBM_FORMAT_ABGR1555:
1693         case TBM_FORMAT_RGBA5551:
1694         case TBM_FORMAT_BGRA5551:
1695         case TBM_FORMAT_RGB565:
1696         /* 24 bpp RGB */
1697         case TBM_FORMAT_RGB888:
1698         case TBM_FORMAT_BGR888:
1699         /* 32 bpp RGB */
1700         case TBM_FORMAT_XRGB8888:
1701         case TBM_FORMAT_XBGR8888:
1702         case TBM_FORMAT_RGBX8888:
1703         case TBM_FORMAT_BGRX8888:
1704         case TBM_FORMAT_ARGB8888:
1705         case TBM_FORMAT_ABGR8888:
1706         case TBM_FORMAT_RGBA8888:
1707         case TBM_FORMAT_BGRA8888:
1708         /* packed YCbCr */
1709         case TBM_FORMAT_YUYV:
1710         case TBM_FORMAT_YVYU:
1711         case TBM_FORMAT_UYVY:
1712         case TBM_FORMAT_VYUY:
1713         case TBM_FORMAT_AYUV:
1714         /*
1715         * 2 plane YCbCr
1716         * index 0 = Y plane, [7:0] Y
1717         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1718         * or
1719         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1720         */
1721         case TBM_FORMAT_NV12:
1722         case TBM_FORMAT_NV21:
1723         case TBM_FORMAT_NV16:
1724         case TBM_FORMAT_NV61:
1725         /*
1726         * 3 plane YCbCr
1727         * index 0: Y plane, [7:0] Y
1728         * index 1: Cb plane, [7:0] Cb
1729         * index 2: Cr plane, [7:0] Cr
1730         * or
1731         * index 1: Cr plane, [7:0] Cr
1732         * index 2: Cb plane, [7:0] Cb
1733         */
1734         case TBM_FORMAT_YUV410:
1735         case TBM_FORMAT_YVU410:
1736         case TBM_FORMAT_YUV411:
1737         case TBM_FORMAT_YVU411:
1738         case TBM_FORMAT_YUV420:
1739         case TBM_FORMAT_YVU420:
1740         case TBM_FORMAT_YUV422:
1741         case TBM_FORMAT_YVU422:
1742         case TBM_FORMAT_YUV444:
1743         case TBM_FORMAT_YVU444:
1744             num = 1;
1745             break;
1746
1747         default:
1748             num = 0;
1749             break;
1750     }
1751
1752     return num;
1753 }
1754
1755 tbm_bo_handle
1756 tbm_sprd_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1757 {
1758     SPRD_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1759     SPRD_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1760
1761     tbm_bo_handle bo_handle;
1762     memset (&bo_handle, 0x0, sizeof (uint64_t));
1763
1764     tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_priv_from_bufmgr(bufmgr);
1765
1766     switch(device)
1767     {
1768     case TBM_DEVICE_DEFAULT:
1769     case TBM_DEVICE_2D:
1770     {
1771         //getting handle from fd
1772         struct drm_prime_handle arg = {0, };
1773
1774         arg.fd = fd;
1775         arg.flags = 0;
1776         if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1777         {
1778             TBM_SPRD_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1779                      arg.fd, strerror(errno));
1780             return (tbm_bo_handle) NULL;
1781         }
1782
1783         bo_handle.u32 = (uint32_t)arg.handle;;
1784         break;
1785     }
1786     case TBM_DEVICE_CPU:
1787         TBM_SPRD_LOG ("Not supported device:%d\n", device);
1788         bo_handle.ptr = (void *) NULL;
1789         break;
1790     case TBM_DEVICE_3D:
1791     case TBM_DEVICE_MM:
1792         bo_handle.u32 = (uint32_t)fd;
1793         break;
1794     default:
1795         TBM_SPRD_LOG ("error Not supported device:%d\n", device);
1796         bo_handle.ptr = (void *) NULL;
1797         break;
1798     }
1799
1800     return bo_handle;
1801 }
1802
1803 int
1804 tbm_sprd_bo_get_flags (tbm_bo bo)
1805 {
1806     SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1807
1808     tbm_bo_sprd bo_sprd;
1809
1810     bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1811     SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1812
1813     return bo_sprd->flags_tbm;
1814 }
1815
1816
1817 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1818
1819 static TBMModuleVersionInfo SprdVersRec =
1820 {
1821     "sprd",
1822     "Samsung",
1823     TBM_ABI_VERSION,
1824 };
1825
1826 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1827
1828 int
1829 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1830 {
1831     tbm_bufmgr_sprd bufmgr_sprd;
1832     tbm_bufmgr_backend bufmgr_backend;
1833
1834     if (!bufmgr)
1835         return 0;
1836
1837     bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1838     if (!bufmgr_sprd)
1839     {
1840         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1841         return 0;
1842     }
1843
1844     if (fd < 0)
1845     {
1846         bufmgr_sprd->fd = tbm_bufmgr_get_drm_fd_wayland();
1847         bufmgr_sprd->fd_owner = 1;
1848     }
1849     else
1850         bufmgr_sprd->fd = fd;
1851
1852     if (bufmgr_sprd->fd  < 0)
1853     {
1854         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1855         free (bufmgr_sprd);
1856         return 0;
1857     }
1858
1859     //Create Hash Table
1860     bufmgr_sprd->hashBos = drmHashCreate ();
1861
1862     //Check if the tbm manager supports dma fence or not.
1863     int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1864     int length;
1865     char buf[1];
1866     if (fp != -1)
1867     {
1868         length = read(fp, buf, 1);
1869
1870         if (length == 1 && buf[0] == '1')
1871             bufmgr_sprd->use_dma_fence = 1;
1872
1873         close(fp);
1874     }
1875
1876     bufmgr_backend = tbm_backend_alloc();
1877     if (!bufmgr_backend)
1878     {
1879         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1880
1881         if (bufmgr_sprd->fd_owner)
1882             close(bufmgr_sprd->fd);
1883
1884         free (bufmgr_sprd);
1885         return 0;
1886     }
1887
1888     bufmgr_backend->priv = (void *)bufmgr_sprd;
1889     bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit,
1890     bufmgr_backend->bo_size = tbm_sprd_bo_size,
1891     bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc,
1892     bufmgr_backend->bo_free = tbm_sprd_bo_free,
1893     bufmgr_backend->bo_import = tbm_sprd_bo_import,
1894     bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd,
1895     bufmgr_backend->bo_export = tbm_sprd_bo_export,
1896     bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd,
1897     bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle,
1898     bufmgr_backend->bo_map = tbm_sprd_bo_map,
1899     bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap,
1900     bufmgr_backend->bo_cache_flush = tbm_sprd_bo_cache_flush,
1901     bufmgr_backend->bo_get_global_key = tbm_sprd_bo_get_global_key;
1902     bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1903     bufmgr_backend->surface_get_size = tbm_sprd_surface_get_size;
1904     bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1905     bufmgr_backend->fd_to_handle = tbm_sprd_fd_to_handle;
1906     bufmgr_backend->surface_get_num_bos = tbm_sprd_surface_get_num_bos;
1907     bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1908
1909     if (bufmgr_sprd->use_dma_fence)
1910     {
1911         bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1912         bufmgr_backend->bo_lock = NULL;
1913         bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1914         bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1915     }
1916     else
1917     {
1918         bufmgr_backend->flags = 0;
1919         bufmgr_backend->bo_lock = NULL;
1920         bufmgr_backend->bo_unlock = NULL;
1921     }
1922
1923     if (!tbm_backend_init (bufmgr, bufmgr_backend))
1924     {
1925         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1926         tbm_backend_free (bufmgr_backend);
1927
1928         if (bufmgr_sprd->fd_owner)
1929             close(bufmgr_sprd->fd);
1930
1931         free (bufmgr_sprd);
1932         return 0;
1933     }
1934
1935 #ifdef DEBUG
1936     {
1937         char* env;
1938         env = getenv ("TBM_SPRD_DEBUG");
1939         if (env)
1940         {
1941             bDebug = atoi (env);
1942             TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1943         }
1944         else
1945         {
1946             bDebug = 0;
1947         }
1948     }
1949 #endif
1950
1951     DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1952          __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1953
1954     DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
1955          __FUNCTION__, bufmgr_sprd->fd);
1956
1957     return 1;
1958 }
1959
1960