Don't use sharing master fd code with libtdm-sprd backend
[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 #if 0
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 fd = -1;
392                 int ret;
393
394                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
395                               "%s:%d search drm-device by udev\n",
396                               getpid(), __FUNCTION__, __LINE__);
397
398                 udev = udev_new();
399                 if (!udev) {
400                         TBM_SPRD_LOG("udev_new() failed.\n");
401                         return -1;
402                 }
403
404                 e = udev_enumerate_new(udev);
405                 udev_enumerate_add_match_subsystem(e, "drm");
406                 udev_enumerate_add_match_sysname(e, "card[0-9]*");
407                 udev_enumerate_scan_devices(e);
408
409                 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
410                         device = udev_device_new_from_syspath(udev_enumerate_get_udev(e),
411                                                               udev_list_entry_get_name(entry));
412                         device_parent = udev_device_get_parent(device);
413                         /* Not need unref device_parent. device_parent and device have same refcnt */
414                         if (device_parent) {
415                                 if (strcmp(udev_device_get_sysname(device_parent), "sprd-drm") == 0) {
416                                         drm_device = device;
417                                         DBG("[%s] Found render device: '%s' (%s)\n",
418                                             target_name(),
419                                             udev_device_get_syspath(drm_device),
420                                             udev_device_get_sysname(device_parent));
421                                         break;
422                                 }
423                         }
424                         udev_device_unref(device);
425                 }
426
427                 udev_enumerate_unref(e);
428
429                 /* Get device file path. */
430                 filepath = udev_device_get_devnode(drm_device);
431                 if (!filepath) {
432                         TBM_SPRD_LOG("udev_device_get_devnode() failed.\n");
433                         udev_device_unref(drm_device);
434                         udev_unref(udev);
435                         return -1;
436                 }
437
438                 /* Open DRM device file and check validity. */
439                 fd = open(filepath, O_RDWR | O_CLOEXEC);
440                 if (fd < 0) {
441                         TBM_SPRD_LOG("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
442                         udev_device_unref(drm_device);
443                         udev_unref(udev);
444                         return -1;
445                 }
446
447                 ret = fstat(fd, &s);
448                 if (ret) {
449                         TBM_SPRD_LOG("fstat() failed %s.\n");
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 #endif
463
464 static int
465 _sprd_bo_cache_flush (tbm_bo bo, int flags)
466 {
467         tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
468         SPRD_RETURN_VAL_IF_FAIL (bufmgr_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         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
475
476         tbm_bo_sprd bo_sprd;
477
478         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
479         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
480
481 #ifdef USE_CACHE
482         struct drm_sprd_gem_cache_op cache_op = {0, };
483         int ret;
484
485         /* if bo_sprd is null, do cache_flush_all */
486         if (bo_sprd) {
487                 cache_op.flags = 0;
488                 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
489                 cache_op.size = bo_sprd->size;
490         } else {
491                 flags = TBM_SPRD_CACHE_FLUSH_ALL;
492                 cache_op.flags = 0;
493                 cache_op.usr_addr = 0;
494                 cache_op.size = 0;
495         }
496
497         if (flags & TBM_SPRD_CACHE_INV) {
498                 if (flags & TBM_SPRD_CACHE_ALL)
499                         cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
500                 else
501                         cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
502         }
503
504         if (flags & TBM_SPRD_CACHE_CLN) {
505                 if (flags & TBM_SPRD_CACHE_ALL)
506                         cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
507                 else
508                         cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
509         }
510
511         if (flags & TBM_SPRD_CACHE_ALL)
512                 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
513
514         ret = drmCommandWriteRead (bufmgr_sprd->fd, DRM_SPRD_GEM_CACHE_OP, &cache_op,
515                                    sizeof(cache_op));
516         if (ret) {
517                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
518                               "error %s:%d fail to flush the cache.\n",
519                               getpid(), __FUNCTION__, __LINE__);
520                 return 0;
521         }
522 #endif
523
524         return 1;
525 }
526
527 static int
528 _bo_init_cache_state(tbm_bufmgr_sprd bufmgr_sprd, tbm_bo_sprd bo_sprd)
529 {
530         tbm_bo_cache_state cache_state;
531
532         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
533         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
534
535         _tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name);
536
537         cache_state.data.isDirtied = DEVICE_NONE;
538         cache_state.data.isCached = 0;
539         cache_state.data.cntFlush = 0;
540
541         _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, cache_state.val);
542
543         return 1;
544 }
545
546 static int
547 _bo_set_cache_state(tbm_bo bo, int device, int opt)
548 {
549         tbm_bo_sprd bo_sprd;
550         tbm_bufmgr_sprd bufmgr_sprd;
551         char need_flush = 0;
552         unsigned short cntFlush = 0;
553
554         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
555         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
556
557         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
558         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
559
560         if (bo_sprd->flags_sprd & SPRD_BO_NONCACHABLE)
561                 return 1;
562
563         /* get cache state of a bo */
564         bo_sprd->cache_state.val = _tgl_get_data(bufmgr_sprd->tgl_fd, bo_sprd->name, NULL);
565
566         /* get global cache flush count */
567         cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
568
569         if (opt == TBM_DEVICE_CPU) {
570                 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CO &&
571                     bo_sprd->cache_state.data.isCached)
572                         need_flush = TBM_SPRD_CACHE_INV;
573
574                 bo_sprd->cache_state.data.isCached = 1;
575                 if (opt & TBM_OPTION_WRITE)
576                         bo_sprd->cache_state.data.isDirtied = DEVICE_CA;
577                 else {
578                         if (bo_sprd->cache_state.data.isDirtied != DEVICE_CA)
579                                 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
580                 }
581         } else {
582                 if (bo_sprd->cache_state.data.isDirtied == DEVICE_CA &&
583                     bo_sprd->cache_state.data.isCached &&
584                     bo_sprd->cache_state.data.cntFlush == cntFlush)
585                         need_flush = TBM_SPRD_CACHE_CLN | TBM_SPRD_CACHE_ALL;
586
587                 if (opt & TBM_OPTION_WRITE)
588                         bo_sprd->cache_state.data.isDirtied = DEVICE_CO;
589                 else {
590                         if (bo_sprd->cache_state.data.isDirtied != DEVICE_CO)
591                                 bo_sprd->cache_state.data.isDirtied = DEVICE_NONE;
592                 }
593         }
594
595         if (need_flush) {
596                 if (need_flush & TBM_SPRD_CACHE_ALL)
597                         _tgl_set_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
598
599                 /* call cache flush */
600                 _sprd_bo_cache_flush (bo, need_flush);
601
602                 DBG("[libtbm:%d] \tcache(%d,%d)....flush:0x%x, cntFlush(%d)\n",
603                     getpid(),
604                     bo_sprd->cache_state.data.isCached,
605                     bo_sprd->cache_state.data.isDirtied,
606                     need_flush,
607                     cntFlush);
608         }
609
610         return 1;
611 }
612
613 static int
614 _bo_save_cache_state(tbm_bo bo)
615 {
616         unsigned short cntFlush = 0;
617         tbm_bo_sprd bo_sprd;
618         tbm_bufmgr_sprd bufmgr_sprd;
619
620         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
621         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
622
623         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
624         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
625
626         /* get global cache flush count */
627         cntFlush = (unsigned short)_tgl_get_data(bufmgr_sprd->tgl_fd, GLOBAL_KEY, NULL);
628
629         /* save global cache flush count */
630         bo_sprd->cache_state.data.cntFlush = cntFlush;
631         _tgl_set_data(bufmgr_sprd->tgl_fd, bo_sprd->name, bo_sprd->cache_state.val);
632
633         return 1;
634 }
635
636 static void
637 _bo_destroy_cache_state(tbm_bo bo)
638 {
639         tbm_bo_sprd bo_sprd;
640         tbm_bufmgr_sprd bufmgr_sprd;
641
642         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
643         SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
644
645         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
646         SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
647
648         _tgl_destroy(bufmgr_sprd->tgl_fd, bo_sprd->name);
649 }
650
651 #ifndef USE_CONTIG_ONLY
652 static unsigned int
653 _get_sprd_flag_from_tbm (unsigned int ftbm)
654 {
655         unsigned int flags = 0;
656
657         /*
658          * TBM_BO_DEFAULT  => ION_HEAP_ID_MASK_SYSTEM
659          * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
660          * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
661          * To be updated appropriately once DRM-GEM supports different heap id masks.
662          * */
663
664         if (ftbm & TBM_BO_SCANOUT) {
665                 flags = SPRD_BO_CONTIG;
666         } else {
667                 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
668         }
669
670         if (ftbm & TBM_BO_WC)
671                 flags |= SPRD_BO_WC;
672         else if (ftbm & TBM_BO_NONCACHABLE)
673                 flags |= SPRD_BO_NONCACHABLE;
674
675         return flags;
676 }
677
678 static unsigned int
679 _get_tbm_flag_from_sprd (unsigned int fsprd)
680 {
681         unsigned int flags = 0;
682
683         if (fsprd & SPRD_BO_NONCONTIG)
684                 flags |= TBM_BO_DEFAULT;
685         else
686                 flags |= TBM_BO_SCANOUT;
687
688         if (fsprd & SPRD_BO_WC)
689                 flags |= TBM_BO_WC;
690         else if (fsprd & SPRD_BO_CACHABLE)
691                 flags |= TBM_BO_DEFAULT;
692         else
693                 flags |= TBM_BO_NONCACHABLE;
694
695         return flags;
696 }
697 #endif
698
699 static unsigned int
700 _get_name (int fd, unsigned int gem)
701 {
702         struct drm_gem_flink arg = {0,};
703
704         arg.handle = gem;
705         if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
706                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
707                               "error %s:%d fail to get flink gem=%d\n",
708                               getpid(), __FUNCTION__, __LINE__, gem);
709                 return 0;
710         }
711
712         return (unsigned int)arg.name;
713 }
714
715 static tbm_bo_handle
716 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
717 {
718         tbm_bo_handle bo_handle;
719         memset (&bo_handle, 0x0, sizeof (uint64_t));
720
721         switch (device) {
722         case TBM_DEVICE_DEFAULT:
723         case TBM_DEVICE_2D:
724                 bo_handle.u32 = (uint32_t)bo_sprd->gem;
725                 break;
726         case TBM_DEVICE_CPU:
727                 if (!bo_sprd->pBase) {
728                         struct drm_sprd_gem_mmap arg = {0,};
729
730                         arg.handle = bo_sprd->gem;
731                         arg.size = bo_sprd->size;
732                         if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) {
733                                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
734                                               "error %s:%d Cannot usrptr gem=%d\n",
735                                               getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
736                                 return (tbm_bo_handle) NULL;
737                         }
738                         bo_sprd->pBase = (void *)((uint32_t)arg.mapped);
739                 }
740
741                 bo_handle.ptr = (void *)bo_sprd->pBase;
742                 break;
743         case TBM_DEVICE_3D:
744 #ifdef USE_DMAIMPORT
745                 if (!bo_sprd->dmabuf) {
746                         struct drm_prime_handle arg = {0, };
747                         arg.handle = bo_sprd->gem;
748                         if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
749                                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
750                                               "error %s:%d Cannot dmabuf=%d\n",
751                                               getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
752                                 return (tbm_bo_handle) NULL;
753                         }
754                         bo_sprd->dmabuf = arg.fd;
755                 }
756
757                 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
758
759 #endif
760                 break;
761
762         case TBM_DEVICE_MM:
763 #ifdef USE_HEAP_ID
764                 //TODO : Add ioctl for GSP MAP once available.
765                 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM:  \n", getpid(),
766                      __FUNCTION_);
767                 _
768
769 #else
770                 if (!bo_sprd->dmabuf) {
771                         struct drm_prime_handle arg = {0, };
772
773                         arg.handle = bo_sprd->gem;
774                         if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
775                                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
776                                               "error %s:%d Cannot dmabuf=%d\n",
777                                               getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
778                                 return (tbm_bo_handle) NULL;
779                         }
780                         bo_sprd->dmabuf = arg.fd;
781                 }
782
783                 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
784 #endif
785                 break;
786         default:
787                 bo_handle.ptr = (void *) NULL;
788                 break;
789         }
790
791         return bo_handle;
792 }
793
794 static int
795 tbm_sprd_bo_size (tbm_bo bo)
796 {
797         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
798
799         tbm_bo_sprd bo_sprd;
800
801         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
802
803         return bo_sprd->size;
804 }
805
806 static void *
807 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
808 {
809         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
810
811         tbm_bo_sprd bo_sprd;
812         tbm_bufmgr_sprd bufmgr_sprd;
813         unsigned int sprd_flags;
814
815         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
816         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
817
818         bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
819         if (!bo_sprd) {
820                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
821                               "error %s:%d fail to allocate the bo private\n",
822                               getpid(), __FUNCTION__, __LINE__);
823                 return 0;
824         }
825
826 #ifdef USE_CONTIG_ONLY
827         flags = TBM_BO_SCANOUT;
828         sprd_flags = SPRD_BO_CONTIG;
829 #else
830         sprd_flags = _get_sprd_flag_from_tbm (flags);
831         if ((flags & TBM_BO_SCANOUT) &&
832             size <= 4 * 1024) {
833                 sprd_flags |= SPRD_BO_NONCONTIG;
834         }
835 #endif // USE_CONTIG_ONLY
836         struct drm_sprd_gem_create arg = {0, };
837         arg.size = size;
838         arg.flags = sprd_flags;
839         if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg,
840                                 sizeof(arg))) {
841                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
842                               "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
843                               getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
844                 free (bo_sprd);
845                 return 0;
846         }
847
848         bo_sprd->fd = bufmgr_sprd->fd;
849         bo_sprd->gem = arg.handle;
850         bo_sprd->size = size;
851         bo_sprd->flags_tbm = flags;
852         bo_sprd->flags_sprd = sprd_flags;
853         bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
854
855         if (!_bo_init_cache_state(bufmgr_sprd, bo_sprd)) {
856                 TBM_SPRD_LOG ("error fail init cache state(%d)\n", bo_sprd->name);
857                 free (bo_sprd);
858                 return 0;
859         }
860
861         pthread_mutex_init(&bo_sprd->mutex, NULL);
862
863         if (bufmgr_sprd->use_dma_fence
864             && !bo_sprd->dmabuf) {
865                 struct drm_prime_handle arg = {0, };
866
867                 arg.handle = bo_sprd->gem;
868                 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
869                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
870                                       "error %s:%d Cannot dmabuf=%d\n",
871                                       getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
872                         free (bo_sprd);
873                         return 0;
874                 }
875                 bo_sprd->dmabuf = arg.fd;
876         }
877
878         /* add bo to hash */
879         PrivGem *privGem = calloc (1, sizeof(PrivGem));
880         privGem->ref_count = 1;
881         privGem->bo_priv = bo_sprd;
882         if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
883                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
884                               "error %s:%d Cannot insert bo to Hash(%d)\n",
885                               getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
886         }
887
888         DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
889              __FUNCTION__, bo_sprd->size,
890              bo_sprd->gem, bo_sprd->name,
891              flags, sprd_flags);
892
893         return (void *)bo_sprd;
894 }
895
896 static void
897 tbm_sprd_bo_free(tbm_bo bo)
898 {
899         tbm_bo_sprd bo_sprd;
900         tbm_bufmgr_sprd bufmgr_sprd;
901
902         if (!bo)
903                 return;
904
905         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
906         SPRD_RETURN_IF_FAIL (bufmgr_sprd != NULL);
907
908         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
909         SPRD_RETURN_IF_FAIL (bo_sprd != NULL);
910
911         DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
912              getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
913
914         if (bo_sprd->pBase) {
915                 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) {
916                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
917                                       "error %s:%d\n",
918                                       getpid(), __FUNCTION__, __LINE__);
919                 }
920         }
921
922         /* close dmabuf */
923         if (bo_sprd->dmabuf) {
924                 close (bo_sprd->dmabuf);
925                 bo_sprd->dmabuf = 0;
926         }
927
928         /* delete bo from hash */
929         PrivGem *privGem = NULL;
930         int ret;
931
932         ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void **)&privGem);
933         if (ret == 0) {
934                 privGem->ref_count--;
935                 if (privGem->ref_count == 0) {
936                         drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
937                         free (privGem);
938                         privGem = NULL;
939                 }
940         } else {
941                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
942                               "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
943                               getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
944         }
945
946         _bo_destroy_cache_state(bo);
947
948         /* Free gem handle */
949         struct drm_gem_close arg = {0, };
950         memset (&arg, 0, sizeof(arg));
951         arg.handle = bo_sprd->gem;
952         if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) {
953                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
954                               "error %s:%d\n",
955                               getpid(), __FUNCTION__, __LINE__);
956         }
957
958         free (bo_sprd);
959 }
960
961
962 static void *
963 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
964 {
965         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
966
967         tbm_bufmgr_sprd bufmgr_sprd;
968         tbm_bo_sprd bo_sprd;
969         PrivGem *privGem = NULL;
970         int ret;
971
972         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
973         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
974
975         ret = drmHashLookup (bufmgr_sprd->hashBos, key, (void **)&privGem);
976         if (ret == 0) {
977                 privGem->ref_count++;
978                 return privGem->bo_priv;
979         }
980
981         struct drm_gem_open arg = {0, };
982         struct drm_sprd_gem_info info = {0, };
983
984         arg.name = key;
985         if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) {
986                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
987                               "error %s:%d Cannot open gem name=%d\n",
988                               getpid(), __FUNCTION__, __LINE__, key);
989                 return 0;
990         }
991
992         info.handle = arg.handle;
993         if (drmCommandWriteRead(bufmgr_sprd->fd,
994                                 DRM_SPRD_GEM_GET,
995                                 &info,
996                                 sizeof(struct drm_sprd_gem_info))) {
997                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
998                               "error %s:%d Cannot get gem info=%d\n",
999                               getpid(), __FUNCTION__, __LINE__, key);
1000                 return 0;
1001         }
1002
1003         bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1004         if (!bo_sprd) {
1005                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1006                               "error %s:%d fail to allocate the bo private\n",
1007                               getpid(), __FUNCTION__, __LINE__);
1008                 return 0;
1009         }
1010
1011         bo_sprd->fd = bufmgr_sprd->fd;
1012         bo_sprd->gem = arg.handle;
1013         bo_sprd->size = arg.size;
1014         bo_sprd->flags_sprd = info.flags;
1015         bo_sprd->name = key;
1016 #ifdef USE_CONTIG_ONLY
1017         bo_sprd->flags_sprd = SPRD_BO_CONTIG;
1018         bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
1019 #else
1020         bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1021 #endif
1022
1023         if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
1024                 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
1025                 free (bo_sprd);
1026                 return 0;
1027         }
1028
1029         if (!bo_sprd->dmabuf) {
1030                 struct drm_prime_handle arg = {0, };
1031
1032                 arg.handle = bo_sprd->gem;
1033                 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
1034                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1035                                       "error %s:%d Cannot dmabuf=%d\n",
1036                                       getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1037                         free (bo_sprd);
1038                         return 0;
1039                 }
1040                 bo_sprd->dmabuf = arg.fd;
1041         }
1042
1043         /* add bo to hash */
1044         privGem = calloc (1, sizeof(PrivGem));
1045         privGem->ref_count = 1;
1046         privGem->bo_priv = bo_sprd;
1047         if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1048                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1049                               "error %s:%d Cannot insert bo to Hash(%d)\n",
1050                               getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
1051         }
1052
1053         DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1054              __FUNCTION__, bo_sprd->size,
1055              bo_sprd->gem, bo_sprd->name,
1056              bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1057
1058         return (void *)bo_sprd;
1059 }
1060
1061 static void *
1062 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
1063 {
1064         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1065
1066         tbm_bufmgr_sprd bufmgr_sprd;
1067         tbm_bo_sprd bo_sprd;
1068         PrivGem *privGem = NULL;
1069         int ret;
1070         int name;
1071
1072         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1073         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1074
1075         //getting handle from fd
1076         unsigned int gem = 0;
1077         struct drm_prime_handle arg = {0, };
1078
1079         arg.fd = key;
1080         arg.flags = 0;
1081         if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
1082                 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
1083                               bo, arg.fd, strerror(errno));
1084                 return NULL;
1085         }
1086         gem = arg.handle;
1087
1088         name = _get_name (bufmgr_sprd->fd, gem);
1089
1090         ret = drmHashLookup (bufmgr_sprd->hashBos, name, (void **)&privGem);
1091         if (ret == 0) {
1092                 if (gem == privGem->bo_priv->gem) {
1093                         privGem->ref_count++;
1094                         return privGem->bo_priv;
1095                 }
1096         }
1097
1098         unsigned int real_size = -1;
1099         struct drm_sprd_gem_info info = {0, };
1100
1101         /* Determine size of bo.  The fd-to-handle ioctl really should
1102          * return the size, but it doesn't.  If we have kernel 3.12 or
1103          * later, we can lseek on the prime fd to get the size.  Older
1104          * kernels will just fail, in which case we fall back to the
1105          * provided (estimated or guess size). */
1106         real_size = lseek(key, 0, SEEK_END);
1107
1108         info.handle = gem;
1109         if (drmCommandWriteRead(bufmgr_sprd->fd,
1110                                 DRM_SPRD_GEM_GET,
1111                                 &info,
1112                                 sizeof(struct drm_sprd_gem_info))) {
1113                 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
1114                               bo, gem, key, strerror(errno));
1115                 return 0;
1116         }
1117
1118         if (real_size == -1)
1119                 real_size = info.size;
1120
1121         bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
1122         if (!bo_sprd) {
1123                 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
1124                 return 0;
1125         }
1126
1127         bo_sprd->fd = bufmgr_sprd->fd;
1128         bo_sprd->gem = gem;
1129         bo_sprd->size = real_size;
1130         bo_sprd->flags_sprd = info.flags;
1131         bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
1132
1133         bo_sprd->name = name;
1134         if (!bo_sprd->name) {
1135                 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
1136                               bo, gem, key, strerror(errno));
1137                 free (bo_sprd);
1138                 return 0;
1139         }
1140
1141         if (!_tgl_init(bufmgr_sprd->tgl_fd, bo_sprd->name)) {
1142                 TBM_SPRD_LOG ("error fail tgl init(%d)\n", bo_sprd->name);
1143                 free (bo_sprd);
1144                 return 0;
1145         }
1146
1147         /* add bo to hash */
1148         privGem = NULL;
1149
1150         privGem = calloc (1, sizeof(PrivGem));
1151         if (!privGem) {
1152                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1153                               "error %s:%d Fail to calloc privGem\n",
1154                               getpid(), __FUNCTION__, __LINE__);
1155                 free (bo_sprd);
1156                 return 0;
1157         }
1158
1159         privGem->ref_count = 1;
1160         privGem->bo_priv = bo_sprd;
1161         if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) {
1162                 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
1163                               bo, bo_sprd->name, gem, key);
1164         }
1165
1166         DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1167              target_name(),
1168              bo,
1169              bo_sprd->gem, bo_sprd->name,
1170              bo_sprd->dmabuf,
1171              key,
1172              bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1173              bo_sprd->size);
1174
1175         return (void *)bo_sprd;
1176 }
1177
1178 static unsigned int
1179 tbm_sprd_bo_export (tbm_bo bo)
1180 {
1181         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1182
1183         tbm_bo_sprd bo_sprd;
1184
1185         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1186         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1187
1188         if (!bo_sprd->name) {
1189                 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1190                 if (!bo_sprd->name) {
1191                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1192                                       "error %s:%d Cannot get name\n",
1193                                       getpid(), __FUNCTION__, __LINE__);
1194                         return 0;
1195                 }
1196         }
1197
1198         DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
1199              __FUNCTION__, bo_sprd->size,
1200              bo_sprd->gem, bo_sprd->name,
1201              bo_sprd->flags_tbm, bo_sprd->flags_sprd);
1202
1203         return (unsigned int)bo_sprd->name;
1204 }
1205
1206 tbm_fd
1207 tbm_sprd_bo_export_fd (tbm_bo bo)
1208 {
1209         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, -1);
1210
1211         tbm_bo_sprd bo_sprd;
1212         int ret;
1213
1214         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1215         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, -1);
1216
1217         struct drm_prime_handle arg = {0, };
1218
1219         arg.handle = bo_sprd->gem;
1220         ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
1221         if (ret) {
1222                 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
1223                               bo, bo_sprd->gem, strerror(errno));
1224                 return (tbm_fd) ret;
1225         }
1226
1227         DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n",
1228              target_name(),
1229              bo,
1230              bo_sprd->gem, bo_sprd->name,
1231              bo_sprd->dmabuf,
1232              arg.fd,
1233              bo_sprd->flags_tbm, bo_sprd->flags_sprd,
1234              bo_sprd->size);
1235
1236         return (tbm_fd)arg.fd;
1237 }
1238
1239
1240 static tbm_bo_handle
1241 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
1242 {
1243         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1244
1245         tbm_bo_handle bo_handle;
1246         tbm_bo_sprd bo_sprd;
1247
1248         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1249         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1250
1251         if (!bo_sprd->gem) {
1252                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1253                               "error %s:%d Cannot map gem=%d\n",
1254                               getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1255                 return (tbm_bo_handle) NULL;
1256         }
1257
1258         DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
1259              __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
1260
1261         /*Get mapped bo_handle*/
1262         bo_handle = _sprd_bo_handle (bo_sprd, device);
1263         if (bo_handle.ptr == NULL) {
1264                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1265                               "error %s:%d Cannot get handle: gem:%d, device:%d\n",
1266                               getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
1267                 return (tbm_bo_handle) NULL;
1268         }
1269
1270         return bo_handle;
1271 }
1272
1273 static tbm_bo_handle
1274 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
1275 {
1276         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, (tbm_bo_handle) NULL);
1277
1278         tbm_bo_handle bo_handle;
1279         tbm_bo_sprd bo_sprd;
1280
1281         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1282         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, (tbm_bo_handle) NULL);
1283
1284         if (!bo_sprd->gem) {
1285                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1286                               "error %s:%d Cannot map gem=%d\n",
1287                               getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
1288                 return (tbm_bo_handle) NULL;
1289         }
1290
1291         DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
1292              __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
1293
1294         /*Get mapped bo_handle*/
1295         bo_handle = _sprd_bo_handle (bo_sprd, device);
1296         if (bo_handle.ptr == NULL) {
1297                 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1298                               "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
1299                               getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
1300                 return (tbm_bo_handle) NULL;
1301         }
1302
1303         if (bo_sprd->map_cnt == 0)
1304                 _bo_set_cache_state (bo, device, opt);
1305
1306         bo_sprd->map_cnt++;
1307
1308         return bo_handle;
1309 }
1310
1311 static int
1312 tbm_sprd_bo_unmap (tbm_bo bo)
1313 {
1314         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1315
1316         tbm_bo_sprd bo_sprd;
1317
1318         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1319         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1320
1321         if (!bo_sprd->gem)
1322                 return 0;
1323
1324         bo_sprd->map_cnt--;
1325
1326         if (bo_sprd->map_cnt == 0)
1327                 _bo_save_cache_state (bo);
1328
1329         DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
1330              __FUNCTION__, bo_sprd->gem, bo_sprd->name);
1331
1332         return 1;
1333 }
1334
1335 static int
1336 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1337 {
1338         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1339
1340 #if USE_BACKEND_LOCK
1341         tbm_bufmgr_sprd bufmgr_sprd;
1342         tbm_bo_sprd bo_sprd;
1343         int ret = 0;
1344
1345         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1346         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1347
1348         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1349         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1350
1351         if (bufmgr_sprd->use_dma_fence) {
1352                 struct dma_buf_fence fence;
1353
1354                 memset(&fence, 0, sizeof(struct dma_buf_fence));
1355
1356                 /* Check if the given type is valid or not. */
1357                 if (opt & TBM_OPTION_WRITE) {
1358                         if (device == TBM_DEVICE_CPU)
1359                                 fence.type = DMA_BUF_ACCESS_WRITE;
1360                         else if (device == TBM_DEVICE_3D)
1361                                 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1362                         else {
1363                                 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1364                                      getpid(), __FUNCTION__);
1365                                 return 0;
1366                         }
1367                 } else if (opt & TBM_OPTION_READ) {
1368                         if (device == TBM_DEVICE_CPU)
1369                                 fence.type = DMA_BUF_ACCESS_READ;
1370                         else if (device == TBM_DEVICE_3D)
1371                                 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1372                         else {
1373                                 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n",
1374                                      getpid(), __FUNCTION__);
1375                                 return 0;
1376                         }
1377                 } else {
1378                         TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(),
1379                                       __FUNCTION__, __LINE__);
1380                         return 0;
1381                 }
1382
1383                 /* Check if the tbm manager supports dma fence or not. */
1384                 if (!bufmgr_sprd->use_dma_fence) {
1385                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1386                                       "error %s:%d  Not support DMA FENCE(%s)\n",
1387                                       getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1388                         return 0;
1389
1390                 }
1391
1392                 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1393                 if (ret < 0) {
1394                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1395                                       "error %s:%d  Can not set GET FENCE(%s)\n",
1396                                       getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1397                         return 0;
1398                 }
1399
1400                 pthread_mutex_lock(&bo_sprd->mutex);
1401                 int i;
1402                 for (i = 0; i < DMA_FENCE_LIST_MAX; i++) {
1403                         if (bo_sprd->dma_fence[i].ctx == 0) {
1404                                 bo_sprd->dma_fence[i].type = fence.type;
1405                                 bo_sprd->dma_fence[i].ctx = fence.ctx;
1406                                 break;
1407                         }
1408                 }
1409                 if (i == DMA_FENCE_LIST_MAX) {
1410                         //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1411                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1412                                       "error %s:%d  fence list is full\n",
1413                                       getpid(), __FUNCTION__, __LINE__);
1414                 }
1415                 pthread_mutex_unlock(&bo_sprd->mutex);
1416
1417                 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n",
1418                      getpid(),
1419                      __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1420         } else {
1421                 ret = _tgl_lock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1422
1423                 DBG ("[libtbm-sprd:%d] lock tgl flink_id:%d\n",
1424                      getpid(), __FUNCTION__, bo_sprd->name);
1425
1426                 return ret;
1427         }
1428
1429 #endif
1430         return 1;
1431 }
1432
1433 static int
1434 tbm_sprd_bo_unlock(tbm_bo bo)
1435 {
1436         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1437
1438 #if USE_BACKEND_LOCK
1439         tbm_bufmgr_sprd bufmgr_sprd;
1440         tbm_bo_sprd bo_sprd;
1441         int ret = 0;
1442
1443         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1444         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1445
1446         bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1447         SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd != NULL, 0);
1448
1449         if (bufmgr_sprd->use_dma_fence) {
1450                 struct dma_buf_fence fence;
1451
1452                 if (!bo_sprd->dma_fence[0].ctx) {
1453                         DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(),
1454                              __FUNCTION__);
1455                         return 0;
1456                 }
1457
1458                 if (!bo_sprd->dma_fence[0].type) {
1459                         DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(),
1460                              __FUNCTION__);
1461                         return 0;
1462                 }
1463
1464                 pthread_mutex_lock(&bo_sprd->mutex);
1465                 fence.type = bo_sprd->dma_fence[0].type;
1466                 fence.ctx = bo_sprd->dma_fence[0].ctx;
1467                 int i;
1468                 for (i = 1; i < DMA_FENCE_LIST_MAX; i++) {
1469                         bo_sprd->dma_fence[i - 1].type = bo_sprd->dma_fence[i].type;
1470                         bo_sprd->dma_fence[i - 1].ctx = bo_sprd->dma_fence[i].ctx;
1471                 }
1472                 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0;
1473                 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0;
1474                 pthread_mutex_unlock(&bo_sprd->mutex);
1475
1476                 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1477                 if (ret < 0) {
1478                         TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1479                                       "error %s:%d  Can not set PUT FENCE(%s)\n",
1480                                       getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1481                         return 0;
1482                 }
1483
1484                 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n",
1485                      getpid(),
1486                      __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1487         } else {
1488                 ret = _tgl_unlock(bufmgr_sprd->tgl_fd, bo_sprd->name);
1489
1490                 DBG ("[libtbm-sprd:%d] unlock tgl flink_id:%d\n",
1491                      getpid(), __FUNCTION__, bo_sprd->name);
1492
1493                 return ret;
1494         }
1495 #endif
1496         return 1;
1497 }
1498
1499 static void
1500 tbm_sprd_bufmgr_deinit (void *priv)
1501 {
1502         SPRD_RETURN_IF_FAIL (priv != NULL);
1503
1504         tbm_bufmgr_sprd bufmgr_sprd;
1505
1506         bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1507
1508         if (bufmgr_sprd->hashBos) {
1509                 unsigned long key;
1510                 void *value;
1511
1512                 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) {
1513                         free (value);
1514                         drmHashDelete (bufmgr_sprd->hashBos, key);
1515                 }
1516
1517                 drmHashDestroy (bufmgr_sprd->hashBos);
1518                 bufmgr_sprd->hashBos = NULL;
1519         }
1520
1521         if (bufmgr_sprd->bind_display)
1522                 tbm_drm_helper_wl_auth_server_deinit();
1523
1524         if (bufmgr_sprd->device_name)
1525                 free(bufmgr_sprd->device_name);
1526
1527         close (bufmgr_sprd->tgl_fd);
1528         close (bufmgr_sprd->fd);
1529
1530         free (bufmgr_sprd);
1531 }
1532
1533 int
1534 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1535 {
1536         uint32_t *color_formats = NULL;
1537
1538         color_formats = (uint32_t *)calloc (1,
1539                                             sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1540
1541         if ( color_formats == NULL ) {
1542                 return 0;
1543         }
1544         memcpy( color_formats, tbm_sprd_color_format_list ,
1545                 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1546
1547
1548         *formats = color_formats;
1549         *num = TBM_COLOR_FORMAT_COUNT;
1550
1551
1552         return 1;
1553 }
1554
1555
1556 /**
1557  * @brief get the plane data of the surface.
1558  * @param[in] surface : 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(tbm_surface_h surface, 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 #if 0
1866                 /* this code is applied with libtdm-sprd */
1867                 int master_fd = -1;
1868
1869                 bufmgr_sprd->fd = -1;
1870                 master_fd = tbm_drm_helper_get_master_fd();
1871                 if (master_fd < 0) {
1872                         bufmgr_sprd->fd = _tbm_sprd_open_drm();
1873                         tbm_drm_helper_set_master_fd(bufmgr_sprd->fd);
1874                 } else {
1875                         bufmgr_sprd->fd = dup(master_fd);
1876                 }
1877 #else
1878                 bufmgr_sprd->fd = dup(fd);
1879 #endif
1880
1881                 if (bufmgr_sprd->fd < 0) {
1882                         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1883                         free (bufmgr_sprd);
1884                         return 0;
1885                 }
1886
1887                 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1888
1889                 if (!bufmgr_sprd->device_name)
1890                 {
1891                         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1892                         free (bufmgr_sprd);
1893                         return 0;
1894                 }
1895
1896         } else {
1897                 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1898                         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1899                         free (bufmgr_sprd);
1900                         return 0;
1901                 }
1902         }
1903
1904         /* open tgl fd for saving cache flush data */
1905         bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
1906
1907         if (bufmgr_sprd->tgl_fd < 0) {
1908                 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
1909                 if (bufmgr_sprd->tgl_fd < 0) {
1910                         TBM_SPRD_LOG("[libtbm:%d] "
1911                                      "error: Fail to open global_lock:%s\n",
1912                                      getpid(), tgl_devfile);
1913
1914                         close(bufmgr_sprd->fd);
1915                         free (bufmgr_sprd);
1916                         return 0;
1917                 }
1918         }
1919
1920         if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
1921                 TBM_SPRD_LOG("[libtbm:%d] "
1922                              "error: Fail to initialize the tgl\n",
1923                              getpid());
1924
1925                 close(bufmgr_sprd->fd);
1926                 close(bufmgr_sprd->tgl_fd);
1927
1928                 free (bufmgr_sprd);
1929                 return 0;
1930         }
1931
1932         //Create Hash Table
1933         bufmgr_sprd->hashBos = drmHashCreate ();
1934
1935         //Check if the tbm manager supports dma fence or not.
1936         int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1937         int length;
1938         char buf[1];
1939         if (fp != -1) {
1940                 length = read(fp, buf, 1);
1941
1942                 if (length == 1 && buf[0] == '1')
1943                         bufmgr_sprd->use_dma_fence = 1;
1944
1945                 close(fp);
1946         }
1947
1948         bufmgr_backend = tbm_backend_alloc();
1949         if (!bufmgr_backend) {
1950                 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1951
1952                 close(bufmgr_sprd->fd);
1953                 close(bufmgr_sprd->tgl_fd);
1954
1955                 free (bufmgr_sprd);
1956                 return 0;
1957         }
1958
1959         bufmgr_backend->priv = (void *)bufmgr_sprd;
1960         bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1961         bufmgr_backend->bo_size = tbm_sprd_bo_size;
1962         bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1963         bufmgr_backend->bo_free = tbm_sprd_bo_free;
1964         bufmgr_backend->bo_import = tbm_sprd_bo_import;
1965         bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1966         bufmgr_backend->bo_export = tbm_sprd_bo_export;
1967         bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1968         bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1969         bufmgr_backend->bo_map = tbm_sprd_bo_map;
1970         bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1971         bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1972         bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1973         bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1974         bufmgr_backend->bo_lock = NULL;
1975         bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1976         bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1977         bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1978
1979         bufmgr_backend->flags |= TBM_LOCK_CTRL_BACKEND;
1980         bufmgr_backend->flags |= TBM_USE_2_0_BACKEND;
1981
1982         if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
1983                 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1984                 tbm_backend_free (bufmgr_backend);
1985
1986                 close(bufmgr_sprd->tgl_fd);
1987                 close(bufmgr_sprd->fd);
1988
1989                 free (bufmgr_sprd);
1990                 return 0;
1991         }
1992
1993 #ifdef DEBUG
1994         {
1995                 char *env;
1996                 env = getenv ("TBM_SPRD_DEBUG");
1997                 if (env) {
1998                         bDebug = atoi (env);
1999                         TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
2000                 } else {
2001                         bDebug = 0;
2002                 }
2003         }
2004 #endif
2005
2006         DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
2007              __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
2008
2009         DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
2010              __FUNCTION__, bufmgr_sprd->fd);
2011
2012         return 1;
2013 }
2014
2015