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