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