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