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