Use device name by drmGetDeviceNameFromFd and search drm device by udev if drmopen...
[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 = 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         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         close (bufmgr_sprd->tgl_fd);
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->fd);
1528
1529         free (bufmgr_sprd);
1530 }
1531
1532 int
1533 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1534 {
1535         uint32_t *color_formats = NULL;
1536
1537         color_formats = (uint32_t *)calloc (1,
1538                                             sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT);
1539
1540         if ( color_formats == NULL ) {
1541                 return 0;
1542         }
1543         memcpy( color_formats, tbm_sprd_color_format_list ,
1544                 sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1545
1546
1547         *formats = color_formats;
1548         *num = TBM_COLOR_FORMAT_COUNT;
1549
1550
1551         return 1;
1552 }
1553
1554
1555 /**
1556  * @brief get the plane data of the surface.
1557  * @param[in] surface : the surface
1558  * @param[in] width : the width of the surface
1559  * @param[in] height : the height of the surface
1560  * @param[in] format : the format of the surface
1561  * @param[in] plane_idx : the format of the surface
1562  * @param[out] size : the size of the plane
1563  * @param[out] offset : the offset of the plane
1564  * @param[out] pitch : the pitch of the plane
1565  * @param[out] padding : the padding of the plane
1566  * @return 1 if this function succeeds, otherwise 0.
1567  */
1568 int
1569 tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height,
1570                                 tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset,
1571                                 uint32_t *pitch, int *bo_idx)
1572 {
1573         int ret = 1;
1574         int bpp;
1575         int _offset = 0;
1576         int _pitch = 0;
1577         int _size = 0;
1578         int _bo_idx = 0;
1579
1580         switch (format) {
1581                 /* 16 bpp RGB */
1582         case TBM_FORMAT_XRGB4444:
1583         case TBM_FORMAT_XBGR4444:
1584         case TBM_FORMAT_RGBX4444:
1585         case TBM_FORMAT_BGRX4444:
1586         case TBM_FORMAT_ARGB4444:
1587         case TBM_FORMAT_ABGR4444:
1588         case TBM_FORMAT_RGBA4444:
1589         case TBM_FORMAT_BGRA4444:
1590         case TBM_FORMAT_XRGB1555:
1591         case TBM_FORMAT_XBGR1555:
1592         case TBM_FORMAT_RGBX5551:
1593         case TBM_FORMAT_BGRX5551:
1594         case TBM_FORMAT_ARGB1555:
1595         case TBM_FORMAT_ABGR1555:
1596         case TBM_FORMAT_RGBA5551:
1597         case TBM_FORMAT_BGRA5551:
1598         case TBM_FORMAT_RGB565:
1599                 bpp = 16;
1600                 _offset = 0;
1601                 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1602                 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1603                 _bo_idx = 0;
1604                 break;
1605                 /* 24 bpp RGB */
1606         case TBM_FORMAT_RGB888:
1607         case TBM_FORMAT_BGR888:
1608                 bpp = 24;
1609                 _offset = 0;
1610                 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1611                 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1612                 _bo_idx = 0;
1613                 break;
1614                 /* 32 bpp RGB */
1615         case TBM_FORMAT_XRGB8888:
1616         case TBM_FORMAT_XBGR8888:
1617         case TBM_FORMAT_RGBX8888:
1618         case TBM_FORMAT_BGRX8888:
1619         case TBM_FORMAT_ARGB8888:
1620         case TBM_FORMAT_ABGR8888:
1621         case TBM_FORMAT_RGBA8888:
1622         case TBM_FORMAT_BGRA8888:
1623                 bpp = 32;
1624                 _offset = 0;
1625                 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1626                 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1627                 _bo_idx = 0;
1628                 break;
1629
1630                 /* packed YCbCr */
1631         case TBM_FORMAT_YUYV:
1632         case TBM_FORMAT_YVYU:
1633         case TBM_FORMAT_UYVY:
1634         case TBM_FORMAT_VYUY:
1635         case TBM_FORMAT_AYUV:
1636                 bpp = 32;
1637                 _offset = 0;
1638                 _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1639                 _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1640                 _bo_idx = 0;
1641                 break;
1642
1643                 /*
1644                 * 2 plane YCbCr
1645                 * index 0 = Y plane, [7:0] Y
1646                 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1647                 * or
1648                 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1649                 */
1650         case TBM_FORMAT_NV12:
1651         case TBM_FORMAT_NV21:
1652                 bpp = 12;
1653                 if (plane_idx == 0) {
1654                         _offset = 0;
1655                         _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1656                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1657                         _bo_idx = 0;
1658                 } else if ( plane_idx == 1 ) {
1659                         _offset = width * height;
1660                         _pitch = SIZE_ALIGN( width , TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1661                         _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1662                         _bo_idx = 0;
1663                 }
1664                 break;
1665
1666         case TBM_FORMAT_NV16:
1667         case TBM_FORMAT_NV61:
1668                 bpp = 16;
1669                 //if(plane_idx == 0)
1670                 {
1671                         _offset = 0;
1672                         _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1673                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1674                         _bo_idx = 0;
1675                         if (plane_idx == 0)
1676                                 break;
1677                 }
1678                 //else if( plane_idx ==1 )
1679                 {
1680                         _offset += _size;
1681                         _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1682                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1683                         _bo_idx = 0;
1684                 }
1685                 break;
1686
1687                 /*
1688                 * 3 plane YCbCr
1689                 * index 0: Y plane, [7:0] Y
1690                 * index 1: Cb plane, [7:0] Cb
1691                 * index 2: Cr plane, [7:0] Cr
1692                 * or
1693                 * index 1: Cr plane, [7:0] Cr
1694                 * index 2: Cb plane, [7:0] Cb
1695                 */
1696                 /*
1697                 NATIVE_BUFFER_FORMAT_YV12
1698                 NATIVE_BUFFER_FORMAT_I420
1699                 */
1700         case TBM_FORMAT_YUV410:
1701         case TBM_FORMAT_YVU410:
1702                 bpp = 9;
1703                 break;
1704         case TBM_FORMAT_YUV411:
1705         case TBM_FORMAT_YVU411:
1706         case TBM_FORMAT_YUV420:
1707         case TBM_FORMAT_YVU420:
1708                 bpp = 12;
1709                 //if(plane_idx == 0)
1710                 {
1711                         _offset = 0;
1712                         _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1713                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1714                         _bo_idx = 0;
1715                         if (plane_idx == 0)
1716                                 break;
1717                 }
1718                 //else if( plane_idx == 1 )
1719                 {
1720                         _offset += _size;
1721                         _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1722                         _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1723                         _bo_idx = 0;
1724                         if (plane_idx == 1)
1725                                 break;
1726                 }
1727                 //else if (plane_idx == 2 )
1728                 {
1729                         _offset += _size;
1730                         _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1731                         _size = SIZE_ALIGN(_pitch * (height / 2), TBM_SURFACE_ALIGNMENT_PLANE);
1732                         _bo_idx = 0;
1733                 }
1734                 break;
1735         case TBM_FORMAT_YUV422:
1736         case TBM_FORMAT_YVU422:
1737                 bpp = 16;
1738                 //if(plane_idx == 0)
1739                 {
1740                         _offset = 0;
1741                         _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1742                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1743                         _bo_idx = 0;
1744                         if (plane_idx == 0)
1745                                 break;
1746                 }
1747                 //else if( plane_idx == 1 )
1748                 {
1749                         _offset += _size;
1750                         _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1751                         _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1752                         _bo_idx = 0;
1753                         if (plane_idx == 1)
1754                                 break;
1755                 }
1756                 //else if (plane_idx == 2 )
1757                 {
1758                         _offset += _size;
1759                         _pitch = SIZE_ALIGN(width / 2, TBM_SURFACE_ALIGNMENT_PITCH_YUV / 2);
1760                         _size = SIZE_ALIGN(_pitch * (height), TBM_SURFACE_ALIGNMENT_PLANE);
1761                         _bo_idx = 0;
1762                 }
1763                 break;
1764         case TBM_FORMAT_YUV444:
1765         case TBM_FORMAT_YVU444:
1766                 bpp = 24;
1767                 //if(plane_idx == 0)
1768                 {
1769                         _offset = 0;
1770                         _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1771                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1772                         _bo_idx = 0;
1773                         if (plane_idx == 0)
1774                                 break;
1775                 }
1776                 //else if( plane_idx == 1 )
1777                 {
1778                         _offset += _size;
1779                         _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1780                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1781                         _bo_idx = 0;
1782                         if (plane_idx == 1)
1783                                 break;
1784                 }
1785                 //else if (plane_idx == 2 )
1786                 {
1787                         _offset += _size;
1788                         _pitch = SIZE_ALIGN(width, TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1789                         _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
1790                         _bo_idx = 0;
1791                 }
1792                 break;
1793         default:
1794                 bpp = 0;
1795                 break;
1796         }
1797
1798         *size = _size;
1799         *offset = _offset;
1800         *pitch = _pitch;
1801         *bo_idx = _bo_idx;
1802
1803         return ret;
1804 }
1805
1806 int
1807 tbm_sprd_bo_get_flags (tbm_bo bo)
1808 {
1809         SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1810
1811         tbm_bo_sprd bo_sprd;
1812
1813         bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1814         SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1815
1816         return bo_sprd->flags_tbm;
1817 }
1818
1819 int
1820 tbm_sprd_bufmgr_bind_native_display (tbm_bufmgr bufmgr, void *NativeDisplay)
1821 {
1822         tbm_bufmgr_sprd bufmgr_sprd;
1823
1824         bufmgr_sprd = tbm_backend_get_priv_from_bufmgr(bufmgr);
1825         SPRD_RETURN_VAL_IF_FAIL(bufmgr_sprd != NULL, 0);
1826
1827         if (!tbm_drm_helper_wl_auth_server_init(NativeDisplay, bufmgr_sprd->fd,
1828                                            bufmgr_sprd->device_name, 0)) {
1829                 TBM_SPRD_LOG("[libtbm-sprd:%d] error:Fail to tbm_drm_helper_wl_server_init\n");
1830                 return 0;
1831         }
1832
1833         bufmgr_sprd->bind_display = NativeDisplay;
1834
1835         return 1;
1836 }
1837
1838 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1839
1840 static TBMModuleVersionInfo SprdVersRec = {
1841         "sprd",
1842         "Samsung",
1843         TBM_ABI_VERSION,
1844 };
1845
1846 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1847
1848 int
1849 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1850 {
1851         tbm_bufmgr_sprd bufmgr_sprd;
1852         tbm_bufmgr_backend bufmgr_backend;
1853
1854         if (!bufmgr)
1855                 return 0;
1856
1857         bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1858         if (!bufmgr_sprd) {
1859                 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1860                 return 0;
1861         }
1862
1863         if (tbm_backend_is_display_server()) {
1864                 int master_fd = -1;
1865
1866                 bufmgr_sprd->fd = -1;
1867                 master_fd = tbm_drm_helper_get_master_fd();
1868                 if (master_fd < 0) {
1869                         bufmgr_sprd->fd = _tbm_sprd_open_drm();
1870                         tbm_drm_helper_set_master_fd(bufmgr_sprd->fd);
1871                 } else {
1872                         bufmgr_sprd->fd = dup(master_fd);
1873                 }
1874
1875                 if (bufmgr_sprd->fd < 0) {
1876                         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1877                         free (bufmgr_sprd);
1878                         return 0;
1879                 }
1880
1881                 bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
1882
1883                 if (!bufmgr_sprd->device_name)
1884                 {
1885                         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get device name!\n", getpid());
1886                         free (bufmgr_sprd);
1887                         return 0;
1888                 }
1889
1890         } else {
1891                 if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
1892                         TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to get auth drm info!\n", getpid());
1893                         free (bufmgr_sprd);
1894                         return 0;
1895                 }
1896         }
1897
1898         /* open tgl fd for saving cache flush data */
1899         bufmgr_sprd->tgl_fd = open(tgl_devfile, O_RDWR);
1900
1901         if (bufmgr_sprd->tgl_fd < 0) {
1902                 bufmgr_sprd->tgl_fd = open(tgl_devfile1, O_RDWR);
1903                 if (bufmgr_sprd->tgl_fd < 0) {
1904                         TBM_SPRD_LOG("[libtbm:%d] "
1905                                      "error: Fail to open global_lock:%s\n",
1906                                      getpid(), tgl_devfile);
1907
1908                         free (bufmgr_sprd);
1909                         return 0;
1910                 }
1911         }
1912
1913         if (!_tgl_init(bufmgr_sprd->tgl_fd, GLOBAL_KEY)) {
1914                 TBM_SPRD_LOG("[libtbm:%d] "
1915                              "error: Fail to initialize the tgl\n",
1916                              getpid());
1917
1918                 free (bufmgr_sprd);
1919                 return 0;
1920         }
1921
1922         //Create Hash Table
1923         bufmgr_sprd->hashBos = drmHashCreate ();
1924
1925         //Check if the tbm manager supports dma fence or not.
1926         int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1927         int length;
1928         char buf[1];
1929         if (fp != -1) {
1930                 length = read(fp, buf, 1);
1931
1932                 if (length == 1 && buf[0] == '1')
1933                         bufmgr_sprd->use_dma_fence = 1;
1934
1935                 close(fp);
1936         }
1937
1938         bufmgr_backend = tbm_backend_alloc();
1939         if (!bufmgr_backend) {
1940                 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1941
1942                 free (bufmgr_sprd);
1943                 return 0;
1944         }
1945
1946         bufmgr_backend->priv = (void *)bufmgr_sprd;
1947         bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit;
1948         bufmgr_backend->bo_size = tbm_sprd_bo_size;
1949         bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc;
1950         bufmgr_backend->bo_free = tbm_sprd_bo_free;
1951         bufmgr_backend->bo_import = tbm_sprd_bo_import;
1952         bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd;
1953         bufmgr_backend->bo_export = tbm_sprd_bo_export;
1954         bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd;
1955         bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle;
1956         bufmgr_backend->bo_map = tbm_sprd_bo_map;
1957         bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap;
1958         bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1959         bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1960         bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1961         bufmgr_backend->bo_lock = NULL;
1962         bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1963         bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1964         bufmgr_backend->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
1965
1966         bufmgr_backend->flags |= TBM_LOCK_CTRL_BACKEND;
1967         bufmgr_backend->flags |= TBM_USE_2_0_BACKEND;
1968
1969         if (!tbm_backend_init (bufmgr, bufmgr_backend)) {
1970                 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1971                 tbm_backend_free (bufmgr_backend);
1972
1973                 free (bufmgr_sprd);
1974                 return 0;
1975         }
1976
1977 #ifdef DEBUG
1978         {
1979                 char *env;
1980                 env = getenv ("TBM_SPRD_DEBUG");
1981                 if (env) {
1982                         bDebug = atoi (env);
1983                         TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1984                 } else {
1985                         bDebug = 0;
1986                 }
1987         }
1988 #endif
1989
1990         DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1991              __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1992
1993         DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
1994              __FUNCTION__, bufmgr_sprd->fd);
1995
1996         return 1;
1997 }
1998
1999