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