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