1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  * Copyright@ Samsung Electronics Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*!
19  * \file      exynos_gscaler.c
20  * \brief     header file for Gscaler HAL
21  * \author    ShinWon Lee (shinwon.lee@samsung.com)
22  * \date      2012/01/09
23  *
24  * <b>Revision History: </b>
25  * - 2012.01.09 : ShinWon Lee(shinwon.lee@samsung.com) \n
26  *   Create
27  *
28  * - 2012.02.07 : ShinWon Lee(shinwon.lee@samsung.com) \n
29  *   Change file name to exynos_gscaler.h
30  *
31  * - 2012.02.09 : Sangwoo, Parkk(sw5771.park@samsung.com) \n
32  *   Use Multiple Gscaler by Multiple Process
33  *
34  * - 2012.02.20 : Sangwoo, Park(sw5771.park@samsung.com) \n
35  *   Add exynos_gsc_set_rotation() API
36  *
37  * - 2012.02.20 : ShinWon Lee(shinwon.lee@samsung.com) \n
38  *   Add size constrain
39  *
40  */
41 
42 //#define LOG_NDEBUG 0
43 #include "exynos_gsc_utils.h"
44 #include "content_protect.h"
45 
46 static int exynos_gsc_m2m_wait_frame_done(void *handle);
47 static int exynos_gsc_m2m_stop(void *handle);
48 
m_gsc_get_plane_count(int v4l_pixel_format)49 static unsigned int m_gsc_get_plane_count(
50     int v4l_pixel_format)
51 {
52     int plane_count = 0;
53 
54     switch (v4l_pixel_format) {
55     case V4L2_PIX_FMT_RGB32:
56     case V4L2_PIX_FMT_BGR32:
57     case V4L2_PIX_FMT_RGB24:
58     case V4L2_PIX_FMT_RGB565:
59     case V4L2_PIX_FMT_RGB555X:
60     case V4L2_PIX_FMT_RGB444:
61     case V4L2_PIX_FMT_YUYV:
62     case V4L2_PIX_FMT_UYVY:
63     case V4L2_PIX_FMT_NV16:
64     case V4L2_PIX_FMT_NV61:
65         plane_count = 1;
66         break;
67     case V4L2_PIX_FMT_NV12M:
68     case V4L2_PIX_FMT_NV12MT_16X16:
69     case V4L2_PIX_FMT_NV12:
70     case V4L2_PIX_FMT_NV21:
71     case V4L2_PIX_FMT_NV21M:
72         plane_count = 2;
73         break;
74     case V4L2_PIX_FMT_YVU420M:
75     case V4L2_PIX_FMT_YUV422P:
76     case V4L2_PIX_FMT_YUV420M:
77         plane_count = 3;
78         break;
79     default:
80         ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
81              __func__, v4l_pixel_format);
82         plane_count = -1;
83         break;
84     }
85 
86     return plane_count;
87 }
88 
m_gsc_get_plane_size(unsigned int * plane_size,unsigned int width,unsigned int height,int v4l_pixel_format)89 static unsigned int m_gsc_get_plane_size(
90     unsigned int *plane_size,
91     unsigned int  width,
92     unsigned int  height,
93     int           v4l_pixel_format)
94 {
95     switch (v4l_pixel_format) {
96     /* 1 plane */
97     case V4L2_PIX_FMT_RGB32:
98     case V4L2_PIX_FMT_BGR32:
99         plane_size[0] = width * height * 4;
100         plane_size[1] = 0;
101         plane_size[2] = 0;
102         break;
103     case V4L2_PIX_FMT_RGB24:
104         plane_size[0] = width * height * 3;
105         plane_size[1] = 0;
106         plane_size[2] = 0;
107         break;
108     case V4L2_PIX_FMT_RGB565:
109     case V4L2_PIX_FMT_RGB555X:
110     case V4L2_PIX_FMT_RGB444:
111     case V4L2_PIX_FMT_YUYV:
112     case V4L2_PIX_FMT_UYVY:
113         plane_size[0] = width * height * 2;
114         plane_size[1] = 0;
115         plane_size[2] = 0;
116         break;
117     /* 2 planes */
118     case V4L2_PIX_FMT_NV12M:
119     case V4L2_PIX_FMT_NV12:
120     case V4L2_PIX_FMT_NV21:
121     case V4L2_PIX_FMT_NV21M:
122         plane_size[0] = width * height;
123         plane_size[1] = width * (height / 2);
124         plane_size[2] = 0;
125         break;
126     case V4L2_PIX_FMT_NV16:
127     case V4L2_PIX_FMT_NV61:
128         plane_size[0] = width * height * 2;
129         plane_size[1] = 0;
130         plane_size[2] = 0;
131         break;
132     case V4L2_PIX_FMT_NV12MT_16X16:
133         plane_size[0] = ALIGN(width, 16) * ALIGN(height, 16);
134         plane_size[1] = ALIGN(width, 16) * ALIGN(height / 2, 8);
135         plane_size[2] = 0;
136         break;
137     /* 3 planes */
138     case V4L2_PIX_FMT_YVU420M:
139     case V4L2_PIX_FMT_YUV422P:
140         plane_size[0] = width * height;
141         plane_size[1] = (width / 2) * (height / 2);
142         plane_size[2] = (width / 2) * (height / 2);
143         break;
144     default:
145         ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
146              __func__, v4l_pixel_format);
147         return -1;
148         break;
149     }
150 
151     return 0;
152 }
153 
m_exynos_gsc_multiple_of_n(int number,int N)154 static int m_exynos_gsc_multiple_of_n(
155     int number, int N)
156 {
157     int result = number;
158     switch (N) {
159     case 1:
160     case 2:
161     case 4:
162     case 8:
163     case 16:
164     case 32:
165     case 64:
166     case 128:
167     case 256:
168         result = (number - (number & (N-1)));
169         break;
170     default:
171         result = number - (number % N);
172         break;
173     }
174     return result;
175 }
176 
m_exynos_gsc_check_src_size(unsigned int * w,unsigned int * h,unsigned int * crop_x,unsigned int * crop_y,unsigned int * crop_w,unsigned int * crop_h,int v4l2_colorformat)177 static bool m_exynos_gsc_check_src_size(
178     unsigned int *w,      unsigned int *h,
179     unsigned int *crop_x, unsigned int *crop_y,
180     unsigned int *crop_w, unsigned int *crop_h,
181     int v4l2_colorformat)
182 {
183     if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) {
184         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
185             __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h);
186         return false;
187     }
188 
189     if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) {
190         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
191             __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h);
192         return false;
193     }
194 
195     switch (v4l2_colorformat) {
196     // YUV420
197     case V4L2_PIX_FMT_YUV420M:
198     case V4L2_PIX_FMT_YVU420M:
199     case V4L2_PIX_FMT_NV12M:
200     case V4L2_PIX_FMT_NV12MT:
201     case V4L2_PIX_FMT_NV21:
202     case V4L2_PIX_FMT_NV21M:
203         *w = (*w + 15) & ~15;
204         *h = (*h + 15) & ~15;
205         //*w      = m_exynos_gsc_multiple_of_n(*w, 16);
206         //*h      = m_exynos_gsc_multiple_of_n(*h, 16);
207         *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4);
208         *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 4);
209         break;
210     // YUV422
211     case V4L2_PIX_FMT_YUYV:
212     case V4L2_PIX_FMT_YUV422P:
213     case V4L2_PIX_FMT_UYVY:
214     case V4L2_PIX_FMT_NV16:
215     case V4L2_PIX_FMT_YVYU:
216     case V4L2_PIX_FMT_VYUY:
217         *h = (*h + 7) & ~7;
218         //*h      = m_exynos_gsc_multiple_of_n(*h, 8);
219         *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4);
220         *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2);
221         break;
222     // RGB
223     case V4L2_PIX_FMT_RGB32:
224     case V4L2_PIX_FMT_RGB24:
225     case V4L2_PIX_FMT_RGB565:
226     case V4L2_PIX_FMT_BGR32:
227     case V4L2_PIX_FMT_RGB555X:
228     case V4L2_PIX_FMT_RGB444:
229     default:
230         *h = (*h + 7) & ~7;
231         //*h      = m_exynos_gsc_multiple_of_n(*h, 8);
232         *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 2);
233         *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2);
234         break;
235     }
236 
237     return true;
238 }
239 
m_exynos_gsc_check_dst_size(unsigned int * w,unsigned int * h,unsigned int * crop_x,unsigned int * crop_y,unsigned int * crop_w,unsigned int * crop_h,int v4l2_colorformat,int rotation)240 static bool m_exynos_gsc_check_dst_size(
241     unsigned int *w,      unsigned int *h,
242     unsigned int *crop_x, unsigned int *crop_y,
243     unsigned int *crop_w, unsigned int *crop_h,
244     int v4l2_colorformat,
245     int rotation)
246 {
247     unsigned int *new_w;
248     unsigned int *new_h;
249     unsigned int *new_crop_w;
250     unsigned int *new_crop_h;
251 
252         new_w = w;
253         new_h = h;
254         new_crop_w = crop_w;
255         new_crop_h = crop_h;
256 
257     if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) {
258         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
259             __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h);
260         return false;
261     }
262 
263     if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) {
264         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
265             __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h);
266         return false;
267     }
268 
269     switch (v4l2_colorformat) {
270     // YUV420
271     case V4L2_PIX_FMT_NV12M:
272     case V4L2_PIX_FMT_NV12MT:
273     case V4L2_PIX_FMT_NV21:
274     case V4L2_PIX_FMT_NV21M:
275     case V4L2_PIX_FMT_YUV420M:
276     case V4L2_PIX_FMT_YVU420M:
277         *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2);
278         *new_h = m_exynos_gsc_multiple_of_n(*new_h, 2);
279         break;
280     // YUV422
281     case V4L2_PIX_FMT_YUYV:
282     case V4L2_PIX_FMT_YUV422P:
283     case V4L2_PIX_FMT_UYVY:
284     case V4L2_PIX_FMT_NV16:
285     case V4L2_PIX_FMT_YVYU:
286     case V4L2_PIX_FMT_VYUY:
287         *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2);
288         break;
289     // RGB
290     case V4L2_PIX_FMT_RGB32:
291     case V4L2_PIX_FMT_RGB24:
292     case V4L2_PIX_FMT_RGB565:
293     case V4L2_PIX_FMT_BGR32:
294     case V4L2_PIX_FMT_RGB555X:
295     case V4L2_PIX_FMT_RGB444:
296     default:
297         break;
298     }
299 
300     return true;
301 }
302 
m_exynos_gsc_output_create(struct GSC_HANDLE * gsc_handle,int dev_num,int out_mode)303 static int m_exynos_gsc_output_create(
304     struct GSC_HANDLE *gsc_handle,
305     int dev_num,
306     int out_mode)
307 {
308     struct media_device *media0;
309     struct media_entity *gsc_sd_entity;
310     struct media_entity *gsc_vd_entity;
311     struct media_entity *sink_sd_entity;
312     struct media_link *links;
313     char node[32];
314     char devname[32];
315     unsigned int cap;
316     int         i;
317     int         fd = 0;
318 
319     Exynos_gsc_In();
320 
321     if ((out_mode != GSC_OUT_FIMD) &&
322         (out_mode != GSC_OUT_TV))
323         return -1;
324 
325     gsc_handle->out_mode = out_mode;
326     /* GSCX => FIMD_WINX : arbitrary linking is not allowed */
327     if ((out_mode == GSC_OUT_FIMD) &&
328         (dev_num > 2))
329         return -1;
330 
331     /* media0 */
332     sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0);
333     media0 = exynos_media_open(node);
334     if (media0 == NULL) {
335         ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
336         return false;
337     }
338 
339     /* Get the sink subdev entity by name and make the node of sink subdev*/
340     if (out_mode == GSC_OUT_FIMD)
341         sprintf(devname, PFX_FIMD_ENTITY, dev_num);
342     else
343         sprintf(devname, PFX_MXR_ENTITY, 0);
344 
345     sink_sd_entity = exynos_media_get_entity_by_name(media0, devname, strlen(devname));
346     sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
347     if ( sink_sd_entity->fd < 0) {
348         ALOGE("%s:: failed to open sink subdev node", __func__);
349         goto gsc_output_err;
350     }
351 
352     /* get GSC video dev & sub dev entity by name*/
353     sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num);
354     gsc_vd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname));
355 
356     sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num);
357     gsc_sd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname));
358 
359     /* gsc sub-dev open */
360     sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num);
361     gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
362 
363     /* setup link : GSC : video device --> sub device */
364     for (i = 0; i < (int) gsc_vd_entity->num_links; i++) {
365         links = &gsc_vd_entity->links[i];
366 
367         if (links == NULL ||
368             links->source->entity != gsc_vd_entity ||
369             links->sink->entity   != gsc_sd_entity) {
370             continue;
371         } else if (exynos_media_setup_link(media0,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
372             ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed",
373                   __func__, links->source->entity->info.id, links->sink->entity->info.id);
374             return -1;
375         }
376     }
377 
378     /* setup link : GSC: sub device --> sink device */
379     for (i = 0; i < (int) gsc_sd_entity->num_links; i++) {
380         links = &gsc_sd_entity->links[i];
381 
382         if (links == NULL || links->source->entity != gsc_sd_entity ||
383                              links->sink->entity   != sink_sd_entity) {
384             continue;
385         } else if (exynos_media_setup_link(media0,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
386             ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed",
387                   __func__, links->source->entity->info.id, links->sink->entity->info.id);
388             return -1;
389         }
390     }
391 
392     /* gsc video-dev open */
393     sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num);
394     gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR);
395     cap = V4L2_CAP_STREAMING |
396           V4L2_CAP_VIDEO_OUTPUT_MPLANE;
397 
398     if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
399         ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
400         goto gsc_output_err;
401     }
402     gsc_handle->gsc_sd_entity = gsc_sd_entity;
403     gsc_handle->gsc_vd_entity = gsc_vd_entity;
404     gsc_handle->sink_sd_entity = sink_sd_entity;
405     gsc_handle->media0 = media0;
406 
407     Exynos_gsc_Out();
408 
409     return 0;
410 
411 gsc_output_err:
412     /* to do */
413     return -1;
414 
415 }
416 
m_exynos_gsc_m2m_create(int dev)417 static int m_exynos_gsc_m2m_create(
418     int dev)
419 {
420     int          fd = 0;
421     int          video_node_num;
422     unsigned int cap;
423     char         node[32];
424 
425     Exynos_gsc_In();
426 
427     switch(dev) {
428     case 0:
429         video_node_num = NODE_NUM_GSC_0;
430         break;
431     case 1:
432         video_node_num = NODE_NUM_GSC_1;
433         break;
434     case 2:
435         video_node_num = NODE_NUM_GSC_2;
436         break;
437     case 3:
438         video_node_num = NODE_NUM_GSC_3;
439         break;
440     default:
441         ALOGE("%s::unexpected dev(%d) fail", __func__, dev);
442         return -1;
443         break;
444     }
445 
446     sprintf(node, "%s%d", PFX_NODE_GSC, video_node_num);
447     fd = exynos_v4l2_open(node, O_RDWR);
448     if (fd < 0) {
449         ALOGE("%s::exynos_v4l2_open(%s) fail", __func__, node);
450         return -1;
451     }
452 
453     cap = V4L2_CAP_STREAMING |
454           V4L2_CAP_VIDEO_OUTPUT_MPLANE |
455           V4L2_CAP_VIDEO_CAPTURE_MPLANE;
456 
457     if (exynos_v4l2_querycap(fd, cap) == false) {
458         ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
459         if (0 < fd)
460             close(fd);
461         fd = 0;
462         return -1;
463     }
464 
465     Exynos_gsc_Out();
466 
467     return fd;
468 }
469 
470 
m_exynos_gsc_out_destroy(struct GSC_HANDLE * gsc_handle)471 static bool m_exynos_gsc_out_destroy(struct GSC_HANDLE *gsc_handle)
472 {
473     struct media_link * links;
474     int i;
475 
476     Exynos_gsc_In();
477 
478     if (gsc_handle == NULL) {
479         ALOGE("%s::gsc_handle is NULL", __func__);
480         return false;
481     }
482 
483     if (gsc_handle->src.stream_on == true) {
484         if (exynos_gsc_out_stop((void *)gsc_handle) < 0)
485             ALOGE("%s::exynos_gsc_out_stop() fail", __func__);
486 
487             gsc_handle->src.stream_on = false;
488     }
489 
490     /* unlink : gscaler-out --> fimd */
491         for (i = 0; i < (int) gsc_handle->gsc_sd_entity->num_links; i++) {
492             links = &gsc_handle->gsc_sd_entity->links[i];
493 
494             if (links == NULL || links->source->entity != gsc_handle->gsc_sd_entity ||
495                                  links->sink->entity   != gsc_handle->sink_sd_entity) {
496                 continue;
497             } else if (exynos_media_setup_link(gsc_handle->media0,  links->source,
498                                                                         links->sink, 0) < 0) {
499                 ALOGE("%s::exynos_media_setup_unlink [src.entity=%d->sink.entity=%d] failed",
500                       __func__, links->source->entity->info.id, links->sink->entity->info.id);
501             }
502         }
503 
504         close(gsc_handle->gsc_vd_entity->fd);
505         close(gsc_handle->gsc_sd_entity->fd);
506         gsc_handle->gsc_vd_entity->fd = -1;
507         gsc_handle->gsc_vd_entity->fd = -1;
508 
509         Exynos_gsc_Out();
510 
511         return true;
512 
513 }
514 
m_exynos_gsc_destroy(struct GSC_HANDLE * gsc_handle)515 static bool m_exynos_gsc_destroy(
516     struct GSC_HANDLE *gsc_handle)
517 {
518     Exynos_gsc_In();
519 
520     /* just in case, we call stop here because we cannot afford to leave
521      * secure side protection on if things failed.
522      */
523     exynos_gsc_m2m_stop(gsc_handle);
524 
525     if (0 < gsc_handle->gsc_fd)
526         close(gsc_handle->gsc_fd);
527     gsc_handle->gsc_fd = 0;
528 
529     Exynos_gsc_Out();
530 
531     return true;
532 }
533 
m_exynos_gsc_find_and_trylock_and_create(struct GSC_HANDLE * gsc_handle)534 bool m_exynos_gsc_find_and_trylock_and_create(
535     struct GSC_HANDLE *gsc_handle)
536 {
537     int          i                 = 0;
538     bool         flag_find_new_gsc = false;
539     unsigned int total_sleep_time  = 0;
540 
541     Exynos_gsc_In();
542 
543     do {
544         for (i = 0; i < NUM_OF_GSC_HW; i++) {
545             // HACK : HWComposer, HDMI uses gscaler with their own code.
546             //        So, This obj_mutex cannot defense their open()
547             if (i == 0 || i == 3)
548                 continue;
549 
550             if (exynos_mutex_trylock(gsc_handle->obj_mutex[i]) == true) {
551 
552                 // destroy old one.
553                 m_exynos_gsc_destroy(gsc_handle);
554 
555                 // create new one.
556                 gsc_handle->gsc_id = i;
557                 gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(i);
558                 if (gsc_handle->gsc_fd < 0) {
559                     gsc_handle->gsc_fd = 0;
560                     exynos_mutex_unlock(gsc_handle->obj_mutex[i]);
561                     continue;
562                 }
563 
564                 /* Trade temporary object for one in the pool */
565                 if (gsc_handle->cur_obj_mutex) {
566                     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
567                     if (gsc_handle->destroy_cur_obj_mutex)
568                         exynos_mutex_destroy(gsc_handle->cur_obj_mutex);
569                 }
570 
571                 gsc_handle->destroy_cur_obj_mutex = false;
572                 gsc_handle->cur_obj_mutex = gsc_handle->obj_mutex[i];
573 
574                 flag_find_new_gsc = true;
575                 break;
576             }
577         }
578 
579         // waiting for another process doesn't use gscaler.
580         // we need to make decision how to do.
581         if (flag_find_new_gsc == false) {
582             usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
583             total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
584             ALOGV("%s::waiting for anthere process doens't use gscaler", __func__);
585         }
586 
587     } while(   flag_find_new_gsc == false
588             && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
589 
590     if (flag_find_new_gsc == false)
591         ALOGE("%s::we don't have no available gsc.. fail", __func__);
592 
593     Exynos_gsc_Out();
594 
595     return flag_find_new_gsc;
596 }
597 
m_exynos_gsc_set_format(int fd,struct gsc_info * info)598 static bool m_exynos_gsc_set_format(
599     int              fd,
600     struct gsc_info *info)
601 {
602     Exynos_gsc_In();
603 
604     struct v4l2_requestbuffers req_buf;
605     int                        plane_count;
606 
607     plane_count = m_gsc_get_plane_count(info->v4l2_colorformat);
608     if (plane_count < 0) {
609         ALOGE("%s::not supported v4l2_colorformat", __func__);
610         return false;
611     }
612 
613     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) {
614         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__);
615         return false;
616     }
617 
618     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) {
619         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__);
620         return false;
621     }
622 
623     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) {
624         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__);
625         return false;
626     }
627 
628     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CSC_RANGE, info->csc_range) < 0) {
629         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
630         return false;
631     }
632     info->format.type = info->buf_type;
633     info->format.fmt.pix_mp.width       = info->width;
634     info->format.fmt.pix_mp.height      = info->height;
635     info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat;
636     info->format.fmt.pix_mp.field       = V4L2_FIELD_ANY;
637     info->format.fmt.pix_mp.num_planes  = plane_count;
638 
639     if (exynos_v4l2_s_fmt(fd, &info->format) < 0) {
640         ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__);
641         return false;
642     }
643 
644     info->crop.type     = info->buf_type;
645     info->crop.c.left   = info->crop_left;
646     info->crop.c.top    = info->crop_top;
647     info->crop.c.width  = info->crop_width;
648     info->crop.c.height = info->crop_height;
649 
650     if (exynos_v4l2_s_crop(fd, &info->crop) < 0) {
651         ALOGE("%s::exynos_v4l2_s_crop() fail", __func__);
652         return false;
653     }
654 
655     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) {
656         ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
657         return false;
658     }
659 
660     req_buf.count  = 1;
661     req_buf.type   = info->buf_type;
662     req_buf.memory = V4L2_MEMORY_DMABUF;
663     if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) {
664         ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__);
665         return false;
666     }
667 
668     Exynos_gsc_Out();
669 
670     return true;
671 }
672 
m_exynos_gsc_set_addr(int fd,struct gsc_info * info)673 static bool m_exynos_gsc_set_addr(
674     int              fd,
675     struct gsc_info *info)
676 {
677     unsigned int i;
678     unsigned int plane_size[NUM_OF_GSC_PLANES];
679 
680     m_gsc_get_plane_size(plane_size,
681                          info->width,
682                          info->height,
683                          info->v4l2_colorformat);
684 
685     info->buffer.index    = 0;
686     info->buffer.flags    = V4L2_BUF_FLAG_USE_SYNC;
687     info->buffer.type     = info->buf_type;
688     info->buffer.memory   = V4L2_MEMORY_DMABUF;
689     info->buffer.m.planes = info->planes;
690     info->buffer.length   = info->format.fmt.pix_mp.num_planes;
691     info->buffer.reserved = info->acquireFenceFd;
692 
693     for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) {
694         info->buffer.m.planes[i].m.fd = (int)info->addr[i];
695         info->buffer.m.planes[i].length    = plane_size[i];
696         info->buffer.m.planes[i].bytesused = 0;
697     }
698 
699     if (exynos_v4l2_qbuf(fd, &info->buffer) < 0) {
700         ALOGE("%s::exynos_v4l2_qbuf() fail", __func__);
701         return false;
702     }
703     info->buffer_queued = true;
704 
705     info->releaseFenceFd = info->buffer.reserved;
706 
707     return true;
708 }
709 
exynos_gsc_create(void)710 void *exynos_gsc_create(
711     void)
712 {
713     int i     = 0;
714     int op_id = 0;
715     char mutex_name[32];
716 
717     Exynos_gsc_In();
718 
719     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
720     if (gsc_handle == NULL) {
721         ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
722         goto err;
723     }
724 
725     gsc_handle->gsc_fd = 0;
726     memset(&gsc_handle->src, 0, sizeof(struct gsc_info));
727     memset(&gsc_handle->dst, 0, sizeof(struct gsc_info));
728 
729     gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
730     gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
731 
732     gsc_handle->op_mutex = NULL;
733     for (i = 0; i < NUM_OF_GSC_HW; i++)
734         gsc_handle->obj_mutex[i] = NULL;
735 
736     gsc_handle->cur_obj_mutex = NULL;
737     gsc_handle->destroy_cur_obj_mutex = false;
738     gsc_handle->flag_local_path = false;
739     gsc_handle->flag_exclusive_open = false;
740 
741     srand(time(NULL));
742     op_id = rand() % 1000000; // just make random id
743     sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id);
744     gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name);
745     if (gsc_handle->op_mutex == NULL) {
746         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
747         goto err;
748     }
749 
750     exynos_mutex_lock(gsc_handle->op_mutex);
751 
752     // check if it is available
753     for (i = 0; i < NUM_OF_GSC_HW; i++) {
754         sprintf(mutex_name, "%sObject%d", LOG_TAG, i);
755 
756         gsc_handle->obj_mutex[i] = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
757         if (gsc_handle->obj_mutex[i] == NULL) {
758             ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
759             goto err;
760         }
761     }
762 
763     if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) {
764         ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__);
765         goto err;
766     }
767 
768     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
769     exynos_mutex_unlock(gsc_handle->op_mutex);
770 
771     return (void *)gsc_handle;
772 
773 err:
774     if (gsc_handle) {
775         m_exynos_gsc_destroy(gsc_handle);
776 
777         if (gsc_handle->cur_obj_mutex)
778             exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
779 
780         for (i = 0; i < NUM_OF_GSC_HW; i++) {
781             if ((gsc_handle->obj_mutex[i] != NULL) &&
782                 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
783                 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
784                     ALOGE("%s::exynos_mutex_destroy() fail", __func__);
785             }
786         }
787 
788         if (gsc_handle->op_mutex)
789             exynos_mutex_unlock(gsc_handle->op_mutex);
790 
791         if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
792             ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
793 
794         free(gsc_handle);
795     }
796 
797     Exynos_gsc_Out();
798 
799     return NULL;
800 }
801 
exynos_gsc_reserve(int dev_num)802 void *exynos_gsc_reserve(int dev_num)
803 {
804     char mutex_name[32];
805     unsigned int total_sleep_time  = 0;
806     bool    gsc_flag = false;
807 
808     if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) {
809         ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
810         return NULL;
811     }
812 
813     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
814     if (gsc_handle == NULL) {
815         ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
816         goto err;
817     }
818 
819     gsc_handle->gsc_fd = -1;
820     gsc_handle->op_mutex = NULL;
821     gsc_handle->cur_obj_mutex = NULL;
822     gsc_handle->destroy_cur_obj_mutex = true;
823 
824     sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num);
825     gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
826     if (gsc_handle->cur_obj_mutex == NULL) {
827         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
828         goto err;
829     }
830 
831     do {
832         if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) {
833             gsc_flag = true;
834             break;
835         }
836         usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
837         total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
838         ALOGV("%s::waiting for another process to release the requested gscaler", __func__);
839     } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
840 
841     if (gsc_flag == true)
842          return (void *)gsc_handle;
843 
844 err:
845     if (gsc_handle) {
846         free(gsc_handle);
847     }
848 
849     return NULL;
850 }
851 
exynos_gsc_release(void * handle)852 void exynos_gsc_release(void *handle)
853 {
854     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle;
855 
856     if (handle == NULL) {
857         ALOGE("%s::handle == NULL() fail", __func__);
858         return;
859     }
860 
861     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
862     exynos_mutex_destroy(gsc_handle->cur_obj_mutex);
863     free(gsc_handle);
864     return;
865 }
866 
exynos_gsc_create_exclusive(int dev_num,int mode,int out_mode,int allow_drm)867 void *exynos_gsc_create_exclusive(
868     int dev_num,
869     int mode,
870     int out_mode,
871     int allow_drm)
872 {
873     int i     = 0;
874     int op_id = 0;
875     char mutex_name[32];
876     unsigned int total_sleep_time  = 0;
877     bool    gsc_flag = false;
878     int ret = 0;
879 
880     Exynos_gsc_In();
881 
882     if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) {
883         ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
884         return NULL;
885     }
886 
887     if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) {
888         ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode);
889         return NULL;
890     }
891 
892     /* currently only gscalers 0 and 3 are DRM capable */
893     if (allow_drm && (dev_num != 0 && dev_num != 3)) {
894         ALOGE("%s::fail:: gscaler %d does not support drm\n", __func__,
895               dev_num);
896         return NULL;
897     }
898 
899     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
900     if (gsc_handle == NULL) {
901         ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
902         goto err;
903     }
904     memset(gsc_handle, 0, sizeof(struct GSC_HANDLE));
905     gsc_handle->gsc_fd = -1;
906     gsc_handle->gsc_mode = mode;
907     gsc_handle->gsc_id = dev_num;
908     gsc_handle->allow_drm = allow_drm;
909 
910     gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
911     gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
912 
913     gsc_handle->op_mutex = NULL;
914     for (i = 0; i < NUM_OF_GSC_HW; i++)
915         gsc_handle->obj_mutex[i] = NULL;
916 
917     gsc_handle->cur_obj_mutex = NULL;
918     gsc_handle->destroy_cur_obj_mutex = false;
919     gsc_handle->flag_local_path = false;
920     gsc_handle->flag_exclusive_open = true;
921 
922     srand(time(NULL));
923     op_id = rand() % 1000000; // just make random id
924     sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id);
925     gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name);
926     if (gsc_handle->op_mutex == NULL) {
927         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
928         goto err;
929     }
930 
931     exynos_mutex_lock(gsc_handle->op_mutex);
932 
933     sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num);
934     gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
935     if (gsc_handle->cur_obj_mutex == NULL) {
936         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
937         goto err;
938     }
939     gsc_handle->destroy_cur_obj_mutex = true;
940 
941     do {
942         if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) {
943             if (mode == GSC_M2M_MODE) {
944                 gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(dev_num);
945                 if (gsc_handle->gsc_fd < 0) {
946                     ALOGE("%s::m_exynos_gsc_m2m_create(%i) fail", __func__, dev_num);
947                     goto err;
948                 }
949             } else if (mode == GSC_OUTPUT_MODE) {
950                 ret = m_exynos_gsc_output_create(gsc_handle, dev_num, out_mode);
951                 if (ret < 0) {
952                     ALOGE("%s::m_exynos_gsc_output_create(%i) fail", __func__, dev_num);
953                     goto err;
954                 }
955             }
956             /*else
957                 gsc_handle->gsc_fd = m_exynos_gsc_capture_create(dev_num);*/
958 
959             gsc_flag = true;
960             break;
961         }
962         usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
963         total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
964         ALOGV("%s::waiting for anthere process doens't use gscaler", __func__);
965     } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
966 
967     exynos_mutex_unlock(gsc_handle->op_mutex);
968     if (gsc_flag == true) {
969         Exynos_gsc_Out();
970         return (void *)gsc_handle;
971         }
972 
973 err:
974     if (gsc_handle) {
975         m_exynos_gsc_destroy(gsc_handle);
976 
977         if (gsc_handle->cur_obj_mutex) {
978             exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
979             if (gsc_handle->destroy_cur_obj_mutex)
980                 exynos_mutex_destroy(gsc_handle->cur_obj_mutex);
981         }
982 
983         for (i = 0; i < NUM_OF_GSC_HW; i++) {
984             if ((gsc_handle->obj_mutex[i] != NULL) &&
985                 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
986                 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
987                     ALOGE("%s::exynos_mutex_destroy() fail", __func__);
988             }
989         }
990 
991         if (gsc_handle->op_mutex)
992             exynos_mutex_unlock(gsc_handle->op_mutex);
993 
994         if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
995             ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
996 
997         free(gsc_handle);
998     }
999 
1000     Exynos_gsc_Out();
1001 
1002     return NULL;
1003 }
1004 
exynos_gsc_destroy(void * handle)1005 void exynos_gsc_destroy(
1006     void *handle)
1007 {
1008     int i = 0;
1009     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle;
1010 
1011     Exynos_gsc_In();
1012 
1013     if (handle == NULL) {
1014         ALOGE("%s::handle == NULL() fail", __func__);
1015         return;
1016     }
1017 
1018     exynos_mutex_lock(gsc_handle->op_mutex);
1019 
1020     if (gsc_handle->flag_exclusive_open == false)
1021         exynos_mutex_lock(gsc_handle->cur_obj_mutex);
1022 
1023     if (gsc_handle->gsc_mode == GSC_OUTPUT_MODE)
1024         m_exynos_gsc_out_destroy(gsc_handle);
1025     else
1026         m_exynos_gsc_destroy(gsc_handle);
1027 
1028     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
1029 
1030     for (i = 0; i < NUM_OF_GSC_HW; i++) {
1031         if ((gsc_handle->obj_mutex[i] != NULL) &&
1032             (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
1033             if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
1034                 ALOGE("%s::exynos_mutex_destroy(obj_mutex) fail", __func__);
1035         }
1036     }
1037 
1038     if (gsc_handle->destroy_cur_obj_mutex)
1039         exynos_mutex_destroy(gsc_handle->cur_obj_mutex);
1040 
1041     exynos_mutex_unlock(gsc_handle->op_mutex);
1042 
1043     if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
1044         ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
1045 
1046     if (gsc_handle)
1047         free(gsc_handle);
1048 
1049     Exynos_gsc_Out();
1050 
1051 }
1052 
exynos_gsc_set_src_format(void * handle,unsigned int width,unsigned int height,unsigned int crop_left,unsigned int crop_top,unsigned int crop_width,unsigned int crop_height,unsigned int v4l2_colorformat,unsigned int cacheable,unsigned int mode_drm)1053 int exynos_gsc_set_src_format(
1054     void        *handle,
1055     unsigned int width,
1056     unsigned int height,
1057     unsigned int crop_left,
1058     unsigned int crop_top,
1059     unsigned int crop_width,
1060     unsigned int crop_height,
1061     unsigned int v4l2_colorformat,
1062     unsigned int cacheable,
1063     unsigned int mode_drm)
1064 {
1065     Exynos_gsc_In();
1066 
1067     struct GSC_HANDLE *gsc_handle;
1068     gsc_handle = (struct GSC_HANDLE *)handle;
1069 
1070     if (handle == NULL) {
1071         ALOGE("%s::handle == NULL() fail", __func__);
1072         return -1;
1073     }
1074 
1075     exynos_mutex_lock(gsc_handle->op_mutex);
1076 
1077     gsc_handle->src.width            = width;
1078     gsc_handle->src.height           = height;
1079     gsc_handle->src.crop_left        = crop_left;
1080     gsc_handle->src.crop_top         = crop_top;
1081     gsc_handle->src.crop_width       = crop_width;
1082     gsc_handle->src.crop_height      = crop_height;
1083     gsc_handle->src.v4l2_colorformat = v4l2_colorformat;
1084     gsc_handle->src.cacheable        = cacheable;
1085     gsc_handle->src.mode_drm         = mode_drm;
1086     gsc_handle->src.dirty            = true;
1087 
1088 
1089     exynos_mutex_unlock(gsc_handle->op_mutex);
1090 
1091     Exynos_gsc_Out();
1092 
1093     return 0;
1094 }
1095 
exynos_gsc_set_dst_format(void * handle,unsigned int width,unsigned int height,unsigned int crop_left,unsigned int crop_top,unsigned int crop_width,unsigned int crop_height,unsigned int v4l2_colorformat,unsigned int cacheable,unsigned int mode_drm,unsigned int narrowRgb)1096 int exynos_gsc_set_dst_format(
1097     void        *handle,
1098     unsigned int width,
1099     unsigned int height,
1100     unsigned int crop_left,
1101     unsigned int crop_top,
1102     unsigned int crop_width,
1103     unsigned int crop_height,
1104     unsigned int v4l2_colorformat,
1105     unsigned int cacheable,
1106     unsigned int mode_drm,
1107     unsigned int narrowRgb)
1108 {
1109     Exynos_gsc_In();
1110 
1111     struct GSC_HANDLE *gsc_handle;
1112     gsc_handle = (struct GSC_HANDLE *)handle;
1113 
1114     if (handle == NULL) {
1115         ALOGE("%s::handle == NULL() fail", __func__);
1116         return -1;
1117     }
1118 
1119     exynos_mutex_lock(gsc_handle->op_mutex);
1120 
1121     gsc_handle->dst.width            = width;
1122     gsc_handle->dst.height           = height;
1123     gsc_handle->dst.crop_left        = crop_left;
1124     gsc_handle->dst.crop_top         = crop_top;
1125     gsc_handle->dst.crop_width       = crop_width;
1126     gsc_handle->dst.crop_height      = crop_height;
1127     gsc_handle->dst.v4l2_colorformat = v4l2_colorformat;
1128     gsc_handle->dst.cacheable        = cacheable;
1129     gsc_handle->dst.mode_drm         = mode_drm;
1130     gsc_handle->dst.dirty            = true;
1131     gsc_handle->dst.csc_range        = !narrowRgb;
1132 
1133     exynos_mutex_unlock(gsc_handle->op_mutex);
1134 
1135     Exynos_gsc_Out();
1136     return 0;
1137 }
1138 
exynos_gsc_set_rotation(void * handle,int rotation,int flip_horizontal,int flip_vertical)1139 int exynos_gsc_set_rotation(
1140     void *handle,
1141     int   rotation,
1142     int   flip_horizontal,
1143     int   flip_vertical)
1144 {
1145     int ret = -1;
1146     struct GSC_HANDLE *gsc_handle;
1147     gsc_handle = (struct GSC_HANDLE *)handle;
1148 
1149     if (handle == NULL) {
1150         ALOGE("%s::handle == NULL() fail", __func__);
1151         return ret;
1152     }
1153 
1154     exynos_mutex_lock(gsc_handle->op_mutex);
1155 
1156     int new_rotation = rotation % 360;
1157 
1158     if (new_rotation % 90 != 0) {
1159         ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__, rotation);
1160         goto done;
1161     }
1162 
1163     if(new_rotation < 0)
1164         new_rotation = -new_rotation;
1165 
1166     gsc_handle->dst.rotation        = new_rotation;
1167     gsc_handle->dst.flip_horizontal = flip_horizontal;
1168     gsc_handle->dst.flip_vertical   = flip_vertical;
1169 
1170     ret = 0;
1171 done:
1172     exynos_mutex_unlock(gsc_handle->op_mutex);
1173 
1174     return ret;
1175 }
1176 
exynos_gsc_set_src_addr(void * handle,void * addr[3],int acquireFenceFd)1177 int exynos_gsc_set_src_addr(
1178     void *handle,
1179     void *addr[3],
1180     int acquireFenceFd)
1181 {
1182     struct GSC_HANDLE *gsc_handle;
1183     gsc_handle = (struct GSC_HANDLE *)handle;
1184 
1185     Exynos_gsc_In();
1186 
1187     if (handle == NULL) {
1188         ALOGE("%s::handle == NULL() fail", __func__);
1189         return -1;
1190     }
1191 
1192     exynos_mutex_lock(gsc_handle->op_mutex);
1193 
1194     gsc_handle->src.addr[0] = addr[0];
1195     gsc_handle->src.addr[1] = addr[1];
1196     gsc_handle->src.addr[2] = addr[2];
1197     gsc_handle->src.acquireFenceFd = acquireFenceFd;
1198 
1199     exynos_mutex_unlock(gsc_handle->op_mutex);
1200 
1201     Exynos_gsc_Out();
1202 
1203     return 0;
1204 }
1205 
exynos_gsc_set_dst_addr(void * handle,void * addr[3],int acquireFenceFd)1206 int exynos_gsc_set_dst_addr(
1207     void *handle,
1208     void *addr[3],
1209     int acquireFenceFd)
1210 {
1211     struct GSC_HANDLE *gsc_handle;
1212     gsc_handle = (struct GSC_HANDLE *)handle;
1213     int ret = 0;
1214 
1215     Exynos_gsc_In();
1216 
1217     if (handle == NULL) {
1218         ALOGE("%s::handle == NULL() fail", __func__);
1219         return -1;
1220     }
1221 
1222     exynos_mutex_lock(gsc_handle->op_mutex);
1223 
1224     gsc_handle->dst.addr[0] = addr[0];
1225     gsc_handle->dst.addr[1] = addr[1];
1226     gsc_handle->dst.addr[2] = addr[2];
1227     gsc_handle->dst.acquireFenceFd = acquireFenceFd;
1228 
1229 
1230     exynos_mutex_unlock(gsc_handle->op_mutex);
1231 
1232     Exynos_gsc_Out();
1233 
1234     return ret;
1235 }
1236 
rotateValueHAL2GSC(unsigned int transform,unsigned int * rotate,unsigned int * hflip,unsigned int * vflip)1237 static void rotateValueHAL2GSC(unsigned int transform,
1238     unsigned int *rotate,
1239     unsigned int *hflip,
1240     unsigned int *vflip)
1241 {
1242     int rotate_flag = transform & 0x7;
1243     *rotate = 0;
1244     *hflip = 0;
1245     *vflip = 0;
1246 
1247     switch (rotate_flag) {
1248     case HAL_TRANSFORM_ROT_90:
1249         *rotate = 90;
1250         break;
1251     case HAL_TRANSFORM_ROT_180:
1252         *rotate = 180;
1253         break;
1254     case HAL_TRANSFORM_ROT_270:
1255         *rotate = 270;
1256         break;
1257     case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
1258         *rotate = 90;
1259         *vflip = 1; /* set vflip to compensate the rot & flip order. */
1260         break;
1261     case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
1262         *rotate = 90;
1263         *hflip = 1; /* set hflip to compensate the rot & flip order. */
1264         break;
1265     case HAL_TRANSFORM_FLIP_H:
1266         *hflip = 1;
1267          break;
1268     case HAL_TRANSFORM_FLIP_V:
1269         *vflip = 1;
1270          break;
1271     default:
1272         break;
1273     }
1274 }
1275 
get_plane_size(int V4L2_PIX,unsigned int * size,unsigned int frame_size,int src_planes)1276 static bool get_plane_size(int V4L2_PIX,
1277     unsigned int * size,
1278     unsigned int frame_size,
1279     int src_planes)
1280 {
1281     unsigned int frame_ratio = 1;
1282     int src_bpp    = get_yuv_bpp(V4L2_PIX);
1283 
1284     src_planes = (src_planes == -1) ? 1 : src_planes;
1285     frame_ratio = 8 * (src_planes -1) / (src_bpp - 8);
1286 
1287     switch (src_planes) {
1288     case 1:
1289         switch (V4L2_PIX) {
1290         case V4L2_PIX_FMT_BGR32:
1291         case V4L2_PIX_FMT_RGB32:
1292             size[0] = frame_size << 2;
1293             break;
1294         case V4L2_PIX_FMT_RGB565X:
1295         case V4L2_PIX_FMT_NV16:
1296         case V4L2_PIX_FMT_NV61:
1297         case V4L2_PIX_FMT_YUYV:
1298         case V4L2_PIX_FMT_UYVY:
1299         case V4L2_PIX_FMT_VYUY:
1300         case V4L2_PIX_FMT_YVYU:
1301             size[0] = frame_size << 1;
1302             break;
1303         case V4L2_PIX_FMT_YUV420:
1304         case V4L2_PIX_FMT_NV12:
1305         case V4L2_PIX_FMT_NV21:
1306         case V4L2_PIX_FMT_NV21M:
1307             size[0] = (frame_size * 3) >> 1;
1308             break;
1309         default:
1310             ALOGE("%s::invalid color type", __func__);
1311             return false;
1312             break;
1313         }
1314         size[1] = 0;
1315         size[2] = 0;
1316         break;
1317     case 2:
1318         size[0] = frame_size;
1319         size[1] = frame_size / frame_ratio;
1320         size[2] = 0;
1321         break;
1322     case 3:
1323         size[0] = frame_size;
1324         size[1] = frame_size / frame_ratio;
1325         size[2] = frame_size / frame_ratio;
1326         break;
1327     default:
1328         ALOGE("%s::invalid color foarmt", __func__);
1329         return false;
1330         break;
1331     }
1332 
1333     return true;
1334 }
1335 
exynos_gsc_m2m_config(void * handle,exynos_gsc_img * src_img,exynos_gsc_img * dst_img)1336 int exynos_gsc_m2m_config(void *handle,
1337     exynos_gsc_img *src_img,
1338     exynos_gsc_img *dst_img)
1339 {
1340     struct GSC_HANDLE *gsc_handle;
1341     int32_t      src_color_space;
1342     int32_t      dst_color_space;
1343     int ret;
1344     unsigned int rotate;
1345     unsigned int hflip;
1346     unsigned int vflip;
1347 
1348     Exynos_gsc_In();
1349 
1350     gsc_handle = (struct GSC_HANDLE *)handle;
1351     if (gsc_handle == NULL) {
1352         ALOGE("%s::gsc_handle == NULL() fail", __func__);
1353         return -1;
1354     }
1355 
1356     if ((src_img->drmMode && !gsc_handle->allow_drm) ||
1357         (src_img->drmMode != dst_img->drmMode)) {
1358         ALOGE("%s::invalid drm state request for gsc%d (s=%d d=%d)",
1359               __func__, gsc_handle->gsc_id,
1360               src_img->drmMode, dst_img->drmMode);
1361         return -1;
1362     }
1363 
1364     src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1365     dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1366     rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1367     exynos_gsc_set_rotation(gsc_handle, rotate, hflip, vflip);
1368 
1369     ret = exynos_gsc_set_src_format(gsc_handle,  src_img->fw, src_img->fh,
1370                                   src_img->x, src_img->y, src_img->w, src_img->h,
1371                                   src_color_space, src_img->cacheable, src_img->drmMode);
1372     if (ret < 0) {
1373         ALOGE("%s: fail: exynos_gsc_set_src_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1374             __func__, src_img->fw, src_img->fh, src_img->x, src_img->y, src_img->w, src_img->h,
1375             src_color_space, src_img->rot);
1376         return -1;
1377     }
1378 
1379     ret = exynos_gsc_set_dst_format(gsc_handle, dst_img->fw, dst_img->fh,
1380                                   dst_img->x, dst_img->y, dst_img->w, dst_img->h,
1381                                   dst_color_space, dst_img->cacheable, dst_img->drmMode,
1382                                   dst_img->narrowRgb);
1383     if (ret < 0) {
1384         ALOGE("%s: fail: exynos_gsc_set_dst_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1385             __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y, dst_img->w, dst_img->h,
1386             src_color_space, dst_img->rot);
1387         return -1;
1388     }
1389 
1390     Exynos_gsc_Out();
1391 
1392     return 0;
1393 }
1394 
exynos_gsc_out_config(void * handle,exynos_gsc_img * src_img,exynos_gsc_img * dst_img)1395 int exynos_gsc_out_config(void *handle,
1396     exynos_gsc_img *src_img,
1397     exynos_gsc_img *dst_img)
1398 {
1399     struct GSC_HANDLE *gsc_handle;
1400     struct v4l2_format  fmt;
1401     struct v4l2_crop    crop;
1402     struct v4l2_requestbuffers reqbuf;
1403     struct v4l2_subdev_format sd_fmt;
1404     struct v4l2_subdev_crop   sd_crop;
1405     int i;
1406     unsigned int rotate;
1407     unsigned int hflip;
1408     unsigned int vflip;
1409     unsigned int plane_size[NUM_OF_GSC_PLANES];
1410     bool rgb;
1411     int csc_range = !dst_img->narrowRgb;
1412 
1413     struct v4l2_rect dst_rect;
1414     int32_t      src_color_space;
1415     int32_t      dst_color_space;
1416     int32_t      src_planes;
1417 
1418     gsc_handle = (struct GSC_HANDLE *)handle;
1419      if (gsc_handle == NULL) {
1420         ALOGE("%s::gsc_handle == NULL() fail", __func__);
1421         return -1;
1422     }
1423 
1424     Exynos_gsc_In();
1425 
1426      if (gsc_handle->src.stream_on != false) {
1427         ALOGE("Error: Src is already streamed on !!!!");
1428         return -1;
1429      }
1430 
1431     memcpy(&gsc_handle->src_img, src_img, sizeof(exynos_gsc_img));
1432     memcpy(&gsc_handle->dst_img, dst_img, sizeof(exynos_gsc_img));
1433     src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1434     dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1435     src_planes = get_yuv_planes(src_color_space);
1436     src_planes = (src_planes == -1) ? 1 : src_planes;
1437     rgb = get_yuv_planes(dst_color_space) == -1;
1438     rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1439 
1440     if (m_exynos_gsc_check_src_size(&gsc_handle->src_img.fw, &gsc_handle->src_img.fh,
1441                                         &gsc_handle->src_img.x, &gsc_handle->src_img.y,
1442                                         &gsc_handle->src_img.w, &gsc_handle->src_img.h,
1443                                         src_color_space) == false) {
1444             ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__);
1445             return -1;
1446     }
1447 
1448     if (m_exynos_gsc_check_dst_size(&gsc_handle->dst_img.fw, &gsc_handle->dst_img.fh,
1449                                         &gsc_handle->dst_img.x, &gsc_handle->dst_img.y,
1450                                         &gsc_handle->dst_img.w, &gsc_handle->dst_img.h,
1451                                         dst_color_space,
1452                                         rotate) == false) {
1453             ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__);
1454             return -1;
1455     }
1456 
1457     /*set: src v4l2_buffer*/
1458     gsc_handle->src.src_buf_idx = 0;
1459     gsc_handle->src.qbuf_cnt = 0;
1460     /* set format: src pad of GSC sub-dev*/
1461     sd_fmt.pad   = GSCALER_SUBDEV_PAD_SOURCE;
1462     sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1463     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
1464         sd_fmt.format.width  = gsc_handle->dst_img.fw;
1465         sd_fmt.format.height = gsc_handle->dst_img.fh;
1466     } else {
1467         sd_fmt.format.width  = gsc_handle->dst_img.w;
1468         sd_fmt.format.height = gsc_handle->dst_img.h;
1469     }
1470     sd_fmt.format.code   = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
1471                                     V4L2_MBUS_FMT_YUV8_1X24;
1472     if (exynos_subdev_s_fmt(gsc_handle->gsc_sd_entity->fd, &sd_fmt) < 0) {
1473             ALOGE("%s::GSC subdev set format failed", __func__);
1474             return -1;
1475     }
1476 
1477     /* set crop: src crop of GSC sub-dev*/
1478     sd_crop.pad   = GSCALER_SUBDEV_PAD_SOURCE;
1479     sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1480     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
1481         sd_crop.rect.left   = gsc_handle->dst_img.x;
1482         sd_crop.rect.top    = gsc_handle->dst_img.y;
1483         sd_crop.rect.width  = gsc_handle->dst_img.w;
1484         sd_crop.rect.height = gsc_handle->dst_img.h;
1485     } else {
1486         sd_crop.rect.left   = 0;
1487         sd_crop.rect.top    = 0;
1488         sd_crop.rect.width  = gsc_handle->dst_img.w;
1489         sd_crop.rect.height = gsc_handle->dst_img.h;
1490     }
1491     if (exynos_subdev_s_crop(gsc_handle->gsc_sd_entity->fd, &sd_crop) < 0) {
1492             ALOGE("%s::GSC subdev set crop failed", __func__);
1493             return -1;
1494     }
1495 
1496     /* sink pad is connected to GSC out */
1497     /*  set format: sink sub-dev */
1498     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
1499         sd_fmt.pad   = FIMD_SUBDEV_PAD_SINK;
1500         sd_fmt.format.width  = gsc_handle->dst_img.w;
1501         sd_fmt.format.height = gsc_handle->dst_img.h;
1502     } else {
1503         sd_fmt.pad   = MIXER_V_SUBDEV_PAD_SINK;
1504         sd_fmt.format.width  = gsc_handle->dst_img.w + gsc_handle->dst_img.x*2;
1505         sd_fmt.format.height = gsc_handle->dst_img.h + gsc_handle->dst_img.y*2;
1506     }
1507 
1508     sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1509     sd_fmt.format.code   = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
1510                                     V4L2_MBUS_FMT_YUV8_1X24;
1511     if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) {
1512         ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad);
1513         return -1;
1514     }
1515 
1516     /*  set crop: sink sub-dev */
1517     if (gsc_handle->out_mode == GSC_OUT_FIMD)
1518         sd_crop.pad   = FIMD_SUBDEV_PAD_SINK;
1519     else
1520         sd_crop.pad   = MIXER_V_SUBDEV_PAD_SINK;
1521 
1522     sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1523     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
1524         sd_crop.rect.left   = gsc_handle->dst_img.x;
1525         sd_crop.rect.top    = gsc_handle->dst_img.y;
1526         sd_crop.rect.width  = gsc_handle->dst_img.w;
1527         sd_crop.rect.height = gsc_handle->dst_img.h;
1528     } else {
1529         sd_crop.rect.left   = 0;
1530         sd_crop.rect.top    = 0;
1531         sd_crop.rect.width  = gsc_handle->dst_img.w;
1532         sd_crop.rect.height = gsc_handle->dst_img.h;
1533     }
1534     if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) {
1535             ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad);
1536             return -1;
1537     }
1538 
1539     if (gsc_handle->out_mode != GSC_OUT_FIMD) {
1540         sd_fmt.pad   = MIXER_V_SUBDEV_PAD_SOURCE;
1541         sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1542         sd_fmt.format.width  = gsc_handle->dst_img.w + gsc_handle->dst_img.x*2;
1543         sd_fmt.format.height = gsc_handle->dst_img.h + gsc_handle->dst_img.y*2;
1544         sd_fmt.format.code   = V4L2_MBUS_FMT_XRGB8888_4X8_LE;
1545         if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) {
1546             ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad);
1547             return -1;
1548         }
1549 
1550         sd_fmt.pad   = MIXER_V_SUBDEV_PAD_SOURCE;
1551         sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1552         sd_crop.rect.left   = gsc_handle->dst_img.x;
1553         sd_crop.rect.top    = gsc_handle->dst_img.y;
1554         sd_crop.rect.width  = gsc_handle->dst_img.w;
1555         sd_crop.rect.height = gsc_handle->dst_img.h;
1556         if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) {
1557             ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad);
1558             return -1;
1559         }
1560     }
1561 
1562     /*set GSC ctrls */
1563     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_ROTATE, rotate) < 0) {
1564         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed", __func__,  rotate);
1565         return -1;
1566     }
1567 
1568     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_HFLIP, hflip) < 0) {
1569         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed", __func__,  hflip);
1570         return -1;
1571     }
1572 
1573     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_VFLIP, vflip) < 0) {
1574         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed", __func__,  vflip);
1575         return -1;
1576     }
1577 
1578      if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CACHEABLE, 1) < 0) {
1579         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed", __func__);
1580         return -1;
1581     }
1582 
1583     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd,
1584         V4L2_CID_CONTENT_PROTECTION, gsc_handle->src_img.drmMode) < 0) {
1585         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail", __func__);
1586         return -1;
1587     }
1588 
1589     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CSC_RANGE,
1590             csc_range)) {
1591         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE: %d) fail", __func__,
1592                 csc_range);
1593         return -1;
1594     }
1595 
1596       /* set src format  :GSC video dev*/
1597     fmt.type  = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1598     fmt.fmt.pix_mp.width            = gsc_handle->src_img.fw;
1599     fmt.fmt.pix_mp.height           = gsc_handle->src_img.fh;
1600     fmt.fmt.pix_mp.pixelformat    = src_color_space;
1601     fmt.fmt.pix_mp.field              = V4L2_FIELD_NONE;
1602     fmt.fmt.pix_mp.num_planes   = src_planes;
1603 
1604     if (exynos_v4l2_s_fmt(gsc_handle->gsc_vd_entity->fd, &fmt) < 0) {
1605             ALOGE("%s::videodev set format failed", __func__);
1606             return -1;
1607     }
1608 
1609     /* set src crop info :GSC video dev*/
1610     crop.type     = fmt.type;
1611     crop.c.left    = gsc_handle->src_img.x;
1612     crop.c.top     = gsc_handle->src_img.y;
1613     crop.c.width  = gsc_handle->src_img.w;
1614     crop.c.height = gsc_handle->src_img.h;
1615 
1616     if (exynos_v4l2_s_crop(gsc_handle->gsc_vd_entity->fd, &crop) < 0) {
1617         ALOGE("%s::videodev set crop failed", __func__);
1618         return -1;
1619     }
1620 
1621     reqbuf.type   = fmt.type;
1622     reqbuf.memory = V4L2_MEMORY_DMABUF;
1623     reqbuf.count  = MAX_BUFFERS_GSCALER_OUT;
1624 
1625     if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) {
1626         ALOGE("%s::request buffers failed", __func__);
1627         return -1;
1628     }
1629 
1630     Exynos_gsc_Out();
1631 
1632     return 0;
1633 }
1634 
exynos_gsc_out_run(void * handle,exynos_gsc_img * src_img)1635 static int exynos_gsc_out_run(void *handle,
1636     exynos_gsc_img *src_img)
1637 {
1638     struct GSC_HANDLE *gsc_handle;
1639     struct v4l2_plane  planes[NUM_OF_GSC_PLANES];
1640     struct v4l2_buffer buf;
1641     int32_t      src_color_space;
1642     int32_t      src_planes;
1643     int             i;
1644     unsigned int plane_size[NUM_OF_GSC_PLANES];
1645 
1646     gsc_handle = (struct GSC_HANDLE *)handle;
1647     if (handle == NULL) {
1648         ALOGE("%s::handle == NULL() fail", __func__);
1649         return -1;
1650     }
1651 
1652     /* All buffers have been queued, dequeue one */
1653     if (gsc_handle->src.qbuf_cnt == MAX_BUFFERS_GSCALER_OUT) {
1654         memset(&buf, 0, sizeof(struct v4l2_buffer));
1655         for (i = 0; i < MAX_BUFFERS_GSCALER_OUT; i++)
1656             memset(&planes[i], 0, sizeof(struct v4l2_plane));
1657 
1658         buf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1659         buf.memory   = V4L2_MEMORY_DMABUF;
1660         buf.length   = src_planes;
1661         buf.m.planes = planes;
1662 
1663         if (exynos_v4l2_dqbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) {
1664             ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)", __func__,
1665                 gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT);
1666             return -1;
1667         }
1668         gsc_handle->src.qbuf_cnt--;
1669     }
1670 
1671     memset(&buf, 0, sizeof(struct v4l2_buffer));
1672     for (i = 0; i < NUM_OF_GSC_PLANES; i++)
1673         memset(&planes[i], 0, sizeof(struct v4l2_plane));
1674 
1675     src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc_handle->src_img.format);
1676     src_planes = get_yuv_planes(src_color_space);
1677     src_planes = (src_planes == -1) ? 1 : src_planes;
1678 
1679     buf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1680     buf.memory   = V4L2_MEMORY_DMABUF;
1681     buf.flags    = V4L2_BUF_FLAG_USE_SYNC;
1682     buf.length   = src_planes;
1683     buf.index    = gsc_handle->src.src_buf_idx;
1684     buf.m.planes = planes;
1685     buf.reserved = src_img->acquireFenceFd;
1686 
1687     gsc_handle->src.addr[0] = src_img->yaddr;
1688     gsc_handle->src.addr[1] = src_img->uaddr;
1689     gsc_handle->src.addr[2] = src_img->vaddr;
1690 
1691     if (get_plane_size(src_color_space, plane_size,
1692         gsc_handle->src_img.fw * gsc_handle->src_img.fh, src_planes) != true) {
1693         ALOGE("%s:get_plane_size:fail", __func__);
1694         return -1;
1695     }
1696 
1697     for (i = 0; i < buf.length; i++) {
1698         buf.m.planes[i].m.fd = (int)gsc_handle->src.addr[i];
1699         buf.m.planes[i].length    = plane_size[i];
1700         buf.m.planes[i].bytesused = plane_size[i];
1701     }
1702 
1703     /* Queue the buf */
1704     if (exynos_v4l2_qbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) {
1705         ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)", __func__,
1706             gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT);
1707         return -1;
1708     }
1709     gsc_handle->src.src_buf_idx++;
1710     gsc_handle->src.src_buf_idx = gsc_handle->src.src_buf_idx % MAX_BUFFERS_GSCALER_OUT;
1711     gsc_handle->src.qbuf_cnt++;
1712 
1713     if (gsc_handle->src.stream_on == false) {
1714         if (exynos_v4l2_streamon(gsc_handle->gsc_vd_entity->fd, buf.type) < 0) {
1715             ALOGE("%s::stream on failed", __func__);
1716             return -1;
1717         }
1718         gsc_handle->src.stream_on = true;
1719     }
1720 
1721     src_img->releaseFenceFd = buf.reserved;
1722     return 0;
1723 }
1724 
exynos_gsc_out_stop(void * handle)1725 int exynos_gsc_out_stop(void *handle)
1726 {
1727     struct GSC_HANDLE *gsc_handle;
1728     struct v4l2_requestbuffers reqbuf;
1729     struct v4l2_buffer buf;
1730     struct v4l2_plane  planes[NUM_OF_GSC_PLANES];
1731     int i;
1732 
1733     Exynos_gsc_In();
1734 
1735     gsc_handle = (struct GSC_HANDLE *)handle;
1736     if (handle == NULL) {
1737         ALOGE("%s::handle == NULL() fail", __func__);
1738         return -1;
1739     }
1740 
1741     if (gsc_handle->src.stream_on == true) {
1742         if (exynos_v4l2_streamoff(gsc_handle->gsc_vd_entity->fd,
1743                                 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
1744             ALOGE("%s::stream off failed", __func__);
1745             return -1;
1746         }
1747         gsc_handle->src.stream_on = false;
1748     }
1749 
1750     gsc_handle->src.src_buf_idx = 0;
1751     gsc_handle->src.qbuf_cnt = 0;
1752 
1753     reqbuf.type   = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1754     reqbuf.memory = V4L2_MEMORY_DMABUF;
1755     reqbuf.count  = 0;
1756 
1757     if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) {
1758         ALOGE("%s::request buffers failed", __func__);
1759         return -1;
1760     }
1761 
1762     Exynos_gsc_Out();
1763 
1764     return 0;
1765 }
1766 
exynos_gsc_m2m_run_core(void * handle)1767 static int exynos_gsc_m2m_run_core(void *handle)
1768 {
1769     struct GSC_HANDLE *gsc_handle;
1770     bool is_dirty;
1771     bool is_drm;
1772 
1773     gsc_handle = (struct GSC_HANDLE *)handle;
1774 
1775     Exynos_gsc_In();
1776 
1777     if (handle == NULL) {
1778         ALOGE("%s::handle == NULL() fail", __func__);
1779         return -1;
1780     }
1781 
1782     is_dirty = gsc_handle->src.dirty || gsc_handle->dst.dirty;
1783     is_drm = gsc_handle->src.mode_drm;
1784 
1785     if (is_dirty && (gsc_handle->src.mode_drm != gsc_handle->dst.mode_drm)) {
1786         ALOGE("%s: drm mode mismatch between src and dst, gsc%d (s=%d d=%d)",
1787               __func__, gsc_handle->gsc_id, gsc_handle->src.mode_drm,
1788               gsc_handle->dst.mode_drm);
1789         return -1;
1790     } else if (is_drm && !gsc_handle->allow_drm) {
1791         ALOGE("%s: drm mode is not supported on gsc%d", __func__,
1792               gsc_handle->gsc_id);
1793         return -1;
1794     }
1795 
1796     if (m_exynos_gsc_check_src_size(&gsc_handle->src.width, &gsc_handle->src.height,
1797                                     &gsc_handle->src.crop_left, &gsc_handle->src.crop_top,
1798                                     &gsc_handle->src.crop_width, &gsc_handle->src.crop_height,
1799                                     gsc_handle->src.v4l2_colorformat) == false) {
1800         ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__);
1801         return -1;
1802     }
1803 
1804     if (m_exynos_gsc_check_dst_size(&gsc_handle->dst.width, &gsc_handle->dst.height,
1805                                     &gsc_handle->dst.crop_left, &gsc_handle->dst.crop_top,
1806                                     &gsc_handle->dst.crop_width, &gsc_handle->dst.crop_height,
1807                                     gsc_handle->dst.v4l2_colorformat,
1808                                     gsc_handle->dst.rotation) == false) {
1809         ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__);
1810         return -1;
1811     }
1812 
1813     /* dequeue buffers from previous work if necessary */
1814     if (gsc_handle->src.stream_on == true) {
1815         if (exynos_gsc_m2m_wait_frame_done(handle) < 0) {
1816             ALOGE("%s::exynos_gsc_m2m_wait_frame_done fail", __func__);
1817             return -1;
1818         }
1819     }
1820 
1821     /*
1822      * need to set the content protection flag before doing reqbufs
1823      * in set_format
1824      */
1825     if (is_dirty && gsc_handle->allow_drm && is_drm) {
1826         if (exynos_v4l2_s_ctrl(gsc_handle->gsc_fd,
1827                                V4L2_CID_CONTENT_PROTECTION, is_drm) < 0) {
1828             ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
1829             return -1;
1830         }
1831     }
1832 
1833     /*
1834      * from this point on, we have to ensure to call stop to clean up whatever
1835      * state we have set.
1836      */
1837 
1838     if (gsc_handle->src.dirty) {
1839         if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->src) == false) {
1840             ALOGE("%s::m_exynos_gsc_set_format(src) fail", __func__);
1841             goto done;
1842         }
1843         gsc_handle->src.dirty = false;
1844     }
1845 
1846     if (gsc_handle->dst.dirty) {
1847         if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->dst) == false) {
1848             ALOGE("%s::m_exynos_gsc_set_format(dst) fail", __func__);
1849             goto done;
1850         }
1851         gsc_handle->dst.dirty = false;
1852     }
1853 
1854     /* if we are enabling drm, make sure to enable hw protection.
1855      * Need to do this before queuing buffers so that the mmu is reserved
1856      * and power domain is kept on.
1857      */
1858     if (is_dirty && gsc_handle->allow_drm && is_drm) {
1859         unsigned int protect_id = 0;
1860 
1861         if (gsc_handle->gsc_id == 0) {
1862             protect_id = CP_PROTECT_GSC0;
1863         } else if (gsc_handle->gsc_id == 3) {
1864             protect_id = CP_PROTECT_GSC3;
1865         } else {
1866             ALOGE("%s::invalid gscaler id %d for content protection", __func__,
1867                   gsc_handle->gsc_id);
1868             goto done;
1869         }
1870 
1871         if (CP_Enable_Path_Protection(protect_id) != 0) {
1872             ALOGE("%s::CP_Enable_Path_Protection failed", __func__);
1873             goto done;
1874         }
1875         gsc_handle->protection_enabled = true;
1876     }
1877 
1878     if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->src) == false) {
1879         ALOGE("%s::m_exynos_gsc_set_addr(src) fail", __func__);
1880         goto done;
1881     }
1882 
1883     if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->dst) == false) {
1884         ALOGE("%s::m_exynos_gsc_set_addr(dst) fail", __func__);
1885         goto done;
1886     }
1887 
1888     if (gsc_handle->src.stream_on == false) {
1889         if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) {
1890             ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__);
1891             goto done;
1892         }
1893         gsc_handle->src.stream_on = true;
1894     }
1895 
1896     if (gsc_handle->dst.stream_on == false) {
1897         if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) {
1898             ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__);
1899             goto done;
1900         }
1901         gsc_handle->dst.stream_on = true;
1902     }
1903 
1904     Exynos_gsc_Out();
1905 
1906     return 0;
1907 
1908 done:
1909     exynos_gsc_m2m_stop(handle);
1910     return -1;
1911 }
1912 
exynos_gsc_m2m_wait_frame_done(void * handle)1913 static int exynos_gsc_m2m_wait_frame_done(void *handle)
1914 {
1915     struct GSC_HANDLE *gsc_handle;
1916 
1917     gsc_handle = (struct GSC_HANDLE *)handle;
1918 
1919     Exynos_gsc_In();
1920 
1921     if (handle == NULL) {
1922         ALOGE("%s::handle == NULL() fail", __func__);
1923         return -1;
1924     }
1925 
1926     if ((gsc_handle->src.stream_on == false) || (gsc_handle->dst.stream_on == false)) {
1927         ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__);
1928         return -1;
1929     }
1930 
1931     if (gsc_handle->src.buffer_queued) {
1932         if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->src.buffer) < 0) {
1933             ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__);
1934             return -1;
1935         }
1936         gsc_handle->src.buffer_queued = false;
1937     }
1938 
1939     if (gsc_handle->dst.buffer_queued) {
1940         if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->dst.buffer) < 0) {
1941             ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__);
1942             return -1;
1943         }
1944         gsc_handle->dst.buffer_queued = false;
1945     }
1946 
1947     Exynos_gsc_Out();
1948 
1949     return 0;
1950 }
1951 
exynos_gsc_m2m_stop(void * handle)1952 static int exynos_gsc_m2m_stop(void *handle)
1953 {
1954     struct GSC_HANDLE *gsc_handle;
1955     struct v4l2_requestbuffers req_buf;
1956     int ret = 0;
1957 
1958     gsc_handle = (struct GSC_HANDLE *)handle;
1959 
1960     Exynos_gsc_In();
1961 
1962     if (!gsc_handle->src.stream_on && !gsc_handle->dst.stream_on) {
1963         /* wasn't streaming, return success */
1964         return 0;
1965     } else if (gsc_handle->src.stream_on != gsc_handle->dst.stream_on) {
1966         ALOGE("%s: invalid state, queue stream state doesn't match (%d != %d)",
1967               __func__, gsc_handle->src.stream_on, gsc_handle->dst.stream_on);
1968         ret = -1;
1969     }
1970 
1971     /*
1972      * we need to plow forward on errors below to make sure that if we had
1973      * turned on content protection on secure side, we turn it off.
1974      *
1975      * also, if we only failed to turn on one of the streams, we'll turn
1976      * the other one off correctly.
1977      */
1978     if (gsc_handle->src.stream_on == true) {
1979         if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) {
1980             ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__);
1981             ret = -1;
1982         }
1983         gsc_handle->src.stream_on = false;
1984     }
1985 
1986 
1987     if (gsc_handle->dst.stream_on == true) {
1988         if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) {
1989             ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__);
1990             ret = -1;
1991         }
1992         gsc_handle->dst.stream_on = false;
1993     }
1994 
1995     /* if drm is enabled */
1996     if (gsc_handle->allow_drm && gsc_handle->protection_enabled) {
1997         unsigned int protect_id = 0;
1998 
1999         if (gsc_handle->gsc_id == 0)
2000             protect_id = CP_PROTECT_GSC0;
2001         else if (gsc_handle->gsc_id == 3)
2002             protect_id = CP_PROTECT_GSC3;
2003 
2004         CP_Disable_Path_Protection(protect_id);
2005         gsc_handle->protection_enabled = false;
2006     }
2007 
2008     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_fd,
2009                            V4L2_CID_CONTENT_PROTECTION, 0) < 0) {
2010         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
2011               __func__);
2012         ret = -1;
2013     }
2014 
2015     /* src: clear_buf */
2016     req_buf.count  = 0;
2017     req_buf.type   = gsc_handle->src.buf_type;
2018     req_buf.memory = V4L2_MEMORY_DMABUF;
2019     if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) {
2020         ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__);
2021         ret = -1;
2022     }
2023 
2024     /* dst: clear_buf */
2025     req_buf.count  = 0;
2026     req_buf.type   = gsc_handle->dst.buf_type;
2027     req_buf.memory = V4L2_MEMORY_DMABUF;
2028     if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) {
2029         ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__);
2030         ret = -1;
2031     }
2032 
2033     Exynos_gsc_Out();
2034 
2035     return ret;
2036 }
2037 
exynos_gsc_convert(void * handle)2038 int exynos_gsc_convert(
2039     void *handle)
2040 {
2041     struct GSC_HANDLE *gsc_handle;
2042     int ret    = -1;
2043     gsc_handle = (struct GSC_HANDLE *)handle;
2044 
2045     Exynos_gsc_In();
2046 
2047     if (handle == NULL) {
2048         ALOGE("%s::handle == NULL() fail", __func__);
2049         return -1;
2050     }
2051 
2052     exynos_mutex_lock(gsc_handle->op_mutex);
2053 
2054     if (gsc_handle->flag_local_path == true) {
2055         ALOGE("%s::this exynos_gsc is connected by another hw internaly. So, don't call exynos_gsc_convert()", __func__);
2056             goto done;
2057         }
2058 
2059     if (exynos_gsc_m2m_run_core(handle) < 0) {
2060         ALOGE("%s::exynos_gsc_run_core fail", __func__);
2061             goto done;
2062         }
2063 
2064     if (exynos_gsc_m2m_wait_frame_done(handle) < 0) {
2065         ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__);
2066         goto done;
2067     }
2068 
2069     if (gsc_handle->src.releaseFenceFd >= 0) {
2070         close(gsc_handle->src.releaseFenceFd);
2071         gsc_handle->src.releaseFenceFd = -1;
2072     }
2073 
2074     if (gsc_handle->dst.releaseFenceFd >= 0) {
2075         close(gsc_handle->dst.releaseFenceFd);
2076         gsc_handle->dst.releaseFenceFd = -1;
2077     }
2078 
2079     if (exynos_gsc_m2m_stop(handle) < 0) {
2080         ALOGE("%s::exynos_gsc_m2m_stop", __func__);
2081         goto done;
2082     }
2083 
2084     ret = 0;
2085 
2086 done:
2087     if (gsc_handle->flag_exclusive_open == false) {
2088         if (gsc_handle->flag_local_path == false)
2089             exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
2090     }
2091 
2092     exynos_mutex_unlock(gsc_handle->op_mutex);
2093 
2094     Exynos_gsc_Out();
2095 
2096     return ret;
2097 }
2098 
exynos_gsc_m2m_run(void * handle,exynos_gsc_img * src_img,exynos_gsc_img * dst_img)2099 int exynos_gsc_m2m_run(void *handle,
2100     exynos_gsc_img *src_img,
2101     exynos_gsc_img *dst_img)
2102 {
2103     struct GSC_HANDLE *gsc_handle = handle;
2104     void *addr[3] = {NULL, NULL, NULL};
2105     int ret = 0;
2106 
2107     Exynos_gsc_In();
2108 
2109     addr[0] = (void *)src_img->yaddr;
2110     addr[1] = (void *)src_img->uaddr;
2111     addr[2] = (void *)src_img->vaddr;
2112     ret = exynos_gsc_set_src_addr(handle, addr, src_img->acquireFenceFd);
2113     if (ret < 0) {
2114         ALOGE("%s::fail: exynos_gsc_set_src_addr[%x %x %x]", __func__,
2115             (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]);
2116         return -1;
2117     }
2118 
2119     addr[0] = (void *)dst_img->yaddr;
2120     addr[1] = (void *)dst_img->uaddr;
2121     addr[2] = (void *)dst_img->vaddr;
2122     ret = exynos_gsc_set_dst_addr(handle, addr, dst_img->acquireFenceFd);
2123     if (ret < 0) {
2124         ALOGE("%s::fail: exynos_gsc_set_dst_addr[%x %x %x]", __func__,
2125             (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]);
2126         return -1;
2127     }
2128 
2129     ret = exynos_gsc_m2m_run_core(handle);
2130      if (ret < 0) {
2131         ALOGE("%s::fail: exynos_gsc_m2m_run_core", __func__);
2132         return -1;
2133     }
2134 
2135     if (src_img->acquireFenceFd >= 0) {
2136         close(src_img->acquireFenceFd);
2137         src_img->acquireFenceFd = -1;
2138     }
2139 
2140     if (dst_img->acquireFenceFd >= 0) {
2141         close(dst_img->acquireFenceFd);
2142         dst_img->acquireFenceFd = -1;
2143     }
2144 
2145     src_img->releaseFenceFd = gsc_handle->src.releaseFenceFd;
2146     dst_img->releaseFenceFd = gsc_handle->dst.releaseFenceFd;
2147 
2148     Exynos_gsc_Out();
2149 
2150     return 0;
2151 }
2152 
exynos_gsc_config_exclusive(void * handle,exynos_gsc_img * src_img,exynos_gsc_img * dst_img)2153 int exynos_gsc_config_exclusive(void *handle,
2154     exynos_gsc_img *src_img,
2155     exynos_gsc_img *dst_img)
2156 {
2157 
2158     Exynos_gsc_In();
2159 
2160      struct GSC_HANDLE *gsc_handle;
2161     int ret = 0;
2162     gsc_handle = (struct GSC_HANDLE *)handle;
2163     if (handle == NULL) {
2164         ALOGE("%s::handle == NULL() fail", __func__);
2165         return -1;
2166     }
2167 
2168     switch (gsc_handle->gsc_mode) {
2169     case GSC_M2M_MODE:
2170         ret = exynos_gsc_m2m_config(handle, src_img, dst_img);
2171         break;
2172     case GSC_OUTPUT_MODE:
2173         ret = exynos_gsc_out_config(handle, src_img, dst_img);
2174         break;
2175     case  GSC_CAPTURE_MODE:
2176         //to do
2177         break;
2178     default:
2179         break;
2180     }
2181 
2182     Exynos_gsc_Out();
2183 
2184     return ret;
2185 
2186 }
2187 
exynos_gsc_run_exclusive(void * handle,exynos_gsc_img * src_img,exynos_gsc_img * dst_img)2188 int exynos_gsc_run_exclusive(void *handle,
2189     exynos_gsc_img *src_img,
2190     exynos_gsc_img *dst_img)
2191 {
2192     struct GSC_HANDLE *gsc_handle;
2193     int ret = 0;
2194 
2195     Exynos_gsc_In();
2196 
2197     gsc_handle = (struct GSC_HANDLE *)handle;
2198     if (handle == NULL) {
2199         ALOGE("%s::handle == NULL() fail", __func__);
2200         return -1;
2201     }
2202 
2203     switch (gsc_handle->gsc_mode) {
2204     case GSC_M2M_MODE:
2205         ret = exynos_gsc_m2m_run(handle, src_img, dst_img);
2206         break;
2207     case GSC_OUTPUT_MODE:
2208         ret = exynos_gsc_out_run(handle, src_img);
2209         break;
2210     case  GSC_CAPTURE_MODE:
2211         //to do
2212         break;
2213     default:
2214         break;
2215     }
2216 
2217     Exynos_gsc_Out();
2218 
2219     return ret;
2220 }
2221 
exynos_gsc_wait_frame_done_exclusive(void * handle)2222 int exynos_gsc_wait_frame_done_exclusive(void *handle)
2223 {
2224     struct GSC_HANDLE *gsc_handle;
2225     int ret = 0;
2226     gsc_handle = (struct GSC_HANDLE *)handle;
2227 
2228     Exynos_gsc_In();
2229 
2230     if (handle == NULL) {
2231         ALOGE("%s::handle == NULL() fail", __func__);
2232         return -1;
2233     }
2234 
2235     if (gsc_handle->gsc_mode == GSC_M2M_MODE)
2236         ret = exynos_gsc_m2m_wait_frame_done(handle);
2237 
2238     Exynos_gsc_Out();
2239 
2240     return ret;
2241 }
2242 
exynos_gsc_stop_exclusive(void * handle)2243 int exynos_gsc_stop_exclusive(void *handle)
2244 {
2245     struct GSC_HANDLE *gsc_handle;
2246     int ret = 0;
2247     gsc_handle = (struct GSC_HANDLE *)handle;
2248 
2249     Exynos_gsc_In();
2250 
2251     if (handle == NULL) {
2252         ALOGE("%s::handle == NULL() fail", __func__);
2253         return -1;
2254     }
2255 
2256     switch (gsc_handle->gsc_mode) {
2257     case GSC_M2M_MODE:
2258         ret = exynos_gsc_m2m_stop(handle);
2259         break;
2260     case GSC_OUTPUT_MODE:
2261         ret = exynos_gsc_out_stop(handle);
2262         break;
2263     case  GSC_CAPTURE_MODE:
2264         //to do
2265         break;
2266     default:
2267         break;
2268     }
2269 
2270     Exynos_gsc_Out();
2271 
2272     return ret;
2273 }
2274 
exynos_gsc_connect(void * handle,void * hw)2275 int exynos_gsc_connect(
2276     void *handle,
2277     void *hw)
2278 {
2279     struct GSC_HANDLE *gsc_handle;
2280     int ret    = -1;
2281     gsc_handle = (struct GSC_HANDLE *)handle;
2282 
2283     Exynos_gsc_In();
2284 
2285     if (handle == NULL) {
2286         ALOGE("%s::handle == NULL() fail", __func__);
2287         return -1;
2288     }
2289 
2290     exynos_mutex_lock(gsc_handle->op_mutex);
2291 
2292     gsc_handle->flag_local_path = true;
2293 
2294     if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == false) {
2295         if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) {
2296             ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__);
2297             goto done;
2298         }
2299     }
2300 
2301     ret = 0;
2302 
2303     Exynos_gsc_Out();
2304 
2305 done:
2306     exynos_mutex_unlock(gsc_handle->op_mutex);
2307 
2308     return ret;
2309 }
2310 
exynos_gsc_disconnect(void * handle,void * hw)2311 int exynos_gsc_disconnect(
2312     void *handle,
2313     void *hw)
2314 {
2315     struct GSC_HANDLE *gsc_handle;
2316     gsc_handle = (struct GSC_HANDLE *)handle;
2317 
2318     Exynos_gsc_In();
2319 
2320     if (handle == NULL) {
2321         ALOGE("%s::handle == NULL() fail", __func__);
2322         return -1;
2323     }
2324 
2325     exynos_mutex_lock(gsc_handle->op_mutex);
2326 
2327     gsc_handle->flag_local_path = false;
2328 
2329     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
2330 
2331     exynos_mutex_unlock(gsc_handle->op_mutex);
2332 
2333     Exynos_gsc_Out();
2334 
2335     return 0;
2336 }
2337