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