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