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