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