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