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