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