exynos_gscaler.c revision 7b062be72289de0209a8d44e4a9f638539cc6e62
170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang/*
270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * Copyright (C) 2008 The Android Open Source Project
370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * Copyright@ Samsung Electronics Co. LTD
470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * Licensed under the Apache License, Version 2.0 (the "License");
670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * you may not use this file except in compliance with the License.
770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * You may obtain a copy of the License at
870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *      http://www.apache.org/licenses/LICENSE-2.0
1070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
1170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * Unless required by applicable law or agreed to in writing, software
1270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * distributed under the License is distributed on an "AS IS" BASIS,
1370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * See the License for the specific language governing permissions and
1570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * limitations under the License.
1670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang */
1770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang/*!
1970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * \file      exynos_gscaler.c
2070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * \brief     header file for Gscaler HAL
2170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * \author    ShinWon Lee (shinwon.lee@samsung.com)
2270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * \date      2012/01/09
2370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
2470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * <b>Revision History: </b>
2570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * - 2012.01.09 : ShinWon Lee(shinwon.lee@samsung.com) \n
2670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *   Create
2770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
2870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * - 2012.02.07 : ShinWon Lee(shinwon.lee@samsung.com) \n
2970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *   Change file name to exynos_gscaler.h
3070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
3170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * - 2012.02.09 : Sangwoo, Parkk(sw5771.park@samsung.com) \n
3270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *   Use Multiple Gscaler by Multiple Process
3370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
3470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * - 2012.02.20 : Sangwoo, Park(sw5771.park@samsung.com) \n
3570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *   Add exynos_gsc_set_rotation() API
3670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
3770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang * - 2012.02.20 : ShinWon Lee(shinwon.lee@samsung.com) \n
3870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *   Add size constrain
3970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang *
4070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang */
4170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
4270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang//#define LOG_NDEBUG 0
4370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang#include "exynos_gsc_utils.h"
4470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
4570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic unsigned int m_gsc_get_plane_count(
4670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int v4l_pixel_format)
4770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
4870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int plane_count = 0;
4970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
5070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (v4l_pixel_format) {
5170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB32:
5270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_BGR32:
5370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB24:
5470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB565:
5570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB555X:
5670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB444:
5770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUYV:
5870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_UYVY:
5923dac69caf127d309df8157099f7a8a21102c830Sungjoong Kang    case V4L2_PIX_FMT_NV16:
6023dac69caf127d309df8157099f7a8a21102c830Sungjoong Kang    case V4L2_PIX_FMT_NV61:
6170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_count = 1;
6270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
6370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12M:
6470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12MT_16X16:
6570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV21:
6666e91991f45bf7c56f4993a2c5c2356421017368Sungjoong Kang    case V4L2_PIX_FMT_NV21M:
6770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_count = 2;
6870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
6970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YVU420M:
7070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUV422P:
7170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_count = 3;
7270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
7370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
746134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
7570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang             __func__, v4l_pixel_format);
7670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_count = -1;
7770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
7870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
7970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
8070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return plane_count;
8170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
8270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
8370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic unsigned int m_gsc_get_plane_size(
8470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *plane_size,
8570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int  width,
8670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int  height,
8770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int           v4l_pixel_format)
8870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
8970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (v4l_pixel_format) {
9070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* 1 plane */
9170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB32:
9270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_BGR32:
9370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[0] = width * height * 4;
9470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[1] = 0;
9570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[2] = 0;
9670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
9770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB24:
9870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[0] = width * height * 3;
9970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[1] = 0;
10070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[2] = 0;
10170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
10270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB565:
10370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB555X:
10470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB444:
10570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUYV:
10670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_UYVY:
10770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[0] = width * height * 2;
10870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[1] = 0;
10970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[2] = 0;
11070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
11170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* 2 planes */
11270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12M:
11370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV21:
11466e91991f45bf7c56f4993a2c5c2356421017368Sungjoong Kang    case V4L2_PIX_FMT_NV21M:
115e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        plane_size[0] = width * height;
116e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        plane_size[1] = width * (height / 2);
117e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        plane_size[2] = 0;
118e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        break;
11970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV16:
12070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV61:
12135b3cc218cb21f5d003e39cf15bb4c5bb01fe114Jiyoung Shin        plane_size[0] = width * height * 2;
12235b3cc218cb21f5d003e39cf15bb4c5bb01fe114Jiyoung Shin        plane_size[1] = 0;
12370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[2] = 0;
12470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
12570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12MT_16X16:
12670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[0] = ALIGN(width, 16) * ALIGN(height, 16);
12770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[1] = ALIGN(width, 16) * ALIGN(height / 2, 8);
12870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[2] = 0;
12970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
13070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* 3 planes */
13170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YVU420M:
13270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUV422P:
13370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[0] = width * height;
13470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[1] = (width / 2) * (height / 2);
13570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        plane_size[2] = (width / 2) * (height / 2);
13670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
13770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
1386134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
13970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang             __func__, v4l_pixel_format);
14070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
14170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
14270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
14370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
14470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
14570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
14670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
14770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic int m_exynos_gsc_multiple_of_n(
14870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int number, int N)
14970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
15070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int result = number;
15170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (N) {
15270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 1:
15370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 2:
15470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 4:
15570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 8:
15670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 16:
15770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 32:
15870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 64:
15970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 128:
16070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 256:
16170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        result = (number - (number & (N-1)));
16270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
16370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
16470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        result = number - (number % N);
16570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
16670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
16770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return result;
16870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
16970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
17070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic bool m_exynos_gsc_check_src_size(
17170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *w,      unsigned int *h,
17270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *crop_x, unsigned int *crop_y,
17370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *crop_w, unsigned int *crop_h,
17470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int v4l2_colorformat)
17570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
17670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) {
1776134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
17870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h);
17970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
18070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
18170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
18270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) {
1836134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
18470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h);
18570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
18670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
18770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
18870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (v4l2_colorformat) {
18970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    // YUV420
19070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUV420M:
19170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YVU420M:
19270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12M:
19370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12MT:
19470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV21:
19570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV21M:
19670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *w = (*w + 15) & ~15;
19770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *h = (*h + 15) & ~15;
19870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        //*w      = m_exynos_gsc_multiple_of_n(*w, 16);
19970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        //*h      = m_exynos_gsc_multiple_of_n(*h, 16);
20070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4);
20170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 4);
20270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
20370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    // YUV422
20470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUYV:
20570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUV422P:
20670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_UYVY:
20770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV16:
20870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YVYU:
20970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_VYUY:
21070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *h = (*h + 7) & ~7;
21170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        //*h      = m_exynos_gsc_multiple_of_n(*h, 8);
21270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4);
21370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2);
21470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
21570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    // RGB
21670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB32:
21770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB24:
21870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB565:
21970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_BGR32:
22070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB555X:
22170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB444:
22270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
22370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *h = (*h + 7) & ~7;
22470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        //*h      = m_exynos_gsc_multiple_of_n(*h, 8);
22570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 2);
22670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2);
22770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
22870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
22970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
23070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return true;
23170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
23270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
23370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic bool m_exynos_gsc_check_dst_size(
23470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *w,      unsigned int *h,
23570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *crop_x, unsigned int *crop_y,
23670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *crop_w, unsigned int *crop_h,
23770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int v4l2_colorformat,
23870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int rotation)
23970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
24070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *new_w;
24170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *new_h;
24270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *new_crop_w;
24370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *new_crop_h;
24470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
24570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        new_w = w;
24670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        new_h = h;
24770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        new_crop_w = crop_w;
24870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        new_crop_h = crop_h;
24970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
25070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) {
2516134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
25270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h);
25370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
25470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
25570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
25670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) {
2576134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
25870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h);
25970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
26070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
26170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
26270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (v4l2_colorformat) {
26370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    // YUV420
26470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12M:
26570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV12MT:
26670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV21:
26766e91991f45bf7c56f4993a2c5c2356421017368Sungjoong Kang    case V4L2_PIX_FMT_NV21M:
26870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUV420M:
26970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YVU420M:
27070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2);
27170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *new_h = m_exynos_gsc_multiple_of_n(*new_h, 2);
27270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
27370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    // YUV422
27470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUYV:
27570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YUV422P:
27670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_UYVY:
27770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_NV16:
27870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_YVYU:
27970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_VYUY:
28070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2);
28170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
28270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    // RGB
28370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB32:
28470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB24:
28570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB565:
28670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_BGR32:
28770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB555X:
28870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case V4L2_PIX_FMT_RGB444:
28970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
29070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
29170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
29270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
29370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return true;
29470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
29570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
29670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic int m_exynos_gsc_output_create(
29770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle,
29870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int dev_num,
29970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int out_mode)
30070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
301e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    struct media_device *media0;
30270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct media_entity *gsc_sd_entity;
30370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct media_entity *gsc_vd_entity;
30470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct media_entity *sink_sd_entity;
30570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct media_link *links;
30670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    char node[32];
30770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    char devname[32];
30870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int cap;
30970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int         i;
31070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int         fd = 0;
311e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
312e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
313e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
31470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if ((out_mode != GSC_OUT_FIMD) &&
31570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        (out_mode != GSC_OUT_TV))
31670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
31770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
31870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->out_mode = out_mode;
31970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* GSCX => FIMD_WINX : arbitrary linking is not allowed */
32070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if ((out_mode == GSC_OUT_FIMD) &&
32152cf3b06437639812b555d7a552ead7882bbddfcGreg Hackmann        (dev_num > 2))
32270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
32370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
32470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* media0 */
32570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0);
32670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    media0 = exynos_media_open(node);
32770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (media0 == NULL) {
3286134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
32970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
33070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
33170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
33270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* Get the sink subdev entity by name and make the node of sink subdev*/
33370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (out_mode == GSC_OUT_FIMD)
33470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        sprintf(devname, PFX_FIMD_ENTITY, dev_num);
33570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    else
33670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        sprintf(devname, PFX_MXR_ENTITY, 0);
33770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
338e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    sink_sd_entity = exynos_media_get_entity_by_name(media0, devname, strlen(devname));
33970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
34070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if ( sink_sd_entity->fd < 0) {
3416134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s:: failed to open sink subdev node", __func__);
34270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto gsc_output_err;
34370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
34470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
34570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* get GSC video dev & sub dev entity by name*/
34670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num);
34770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_vd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname));
34870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
34970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num);
35070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_sd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname));
35170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
35270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* gsc sub-dev open */
35370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num);
35470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
35570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
35670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* setup link : GSC : video device --> sub device */
35770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < (int) gsc_vd_entity->num_links; i++) {
35870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        links = &gsc_vd_entity->links[i];
35970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
36070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (links == NULL ||
36170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            links->source->entity != gsc_vd_entity ||
36270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            links->sink->entity   != gsc_sd_entity) {
36370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            continue;
36470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        } else if (exynos_media_setup_link(media0,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
3656134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed",
36670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                  __func__, links->source->entity->info.id, links->sink->entity->info.id);
36770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
36870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
36970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
37070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
37170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* setup link : GSC: sub device --> sink device */
37270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < (int) gsc_sd_entity->num_links; i++) {
37370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        links = &gsc_sd_entity->links[i];
37470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
37570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (links == NULL || links->source->entity != gsc_sd_entity ||
37670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                             links->sink->entity   != sink_sd_entity) {
37770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            continue;
37870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        } else if (exynos_media_setup_link(media0,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
3796134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed",
38070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                  __func__, links->source->entity->info.id, links->sink->entity->info.id);
38170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
38270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
38370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
38470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
38570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* gsc video-dev open */
38670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num);
38770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR);
38870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    cap = V4L2_CAP_STREAMING |
38970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang          V4L2_CAP_VIDEO_OUTPUT_MPLANE;
39070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
39170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
3926134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
39370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto gsc_output_err;
39470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
39570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->gsc_sd_entity = gsc_sd_entity;
39670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->gsc_vd_entity = gsc_vd_entity;
39770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->sink_sd_entity = sink_sd_entity;
398e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    gsc_handle->media0 = media0;
399e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
400e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
401e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
40270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
40370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
40470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changgsc_output_err:
40570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* to do */
40670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return -1;
40770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
40870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
40970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
410e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Changstatic int m_exynos_gsc_m2m_create(
41170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int dev)
41270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
41370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int          fd = 0;
41470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int          video_node_num;
41570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int cap;
41670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    char         node[32];
41770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
418e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
419e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
42070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch(dev) {
42170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 0:
42270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        video_node_num = NODE_NUM_GSC_0;
42370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
42470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 1:
42570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        video_node_num = NODE_NUM_GSC_1;
42670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
42770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 2:
42870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        video_node_num = NODE_NUM_GSC_2;
42970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
43070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 3:
43170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        video_node_num = NODE_NUM_GSC_3;
43270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
43370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
4346134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::unexpected dev(%d) fail", __func__, dev);
43570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
43670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
43770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
43870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
43970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(node, "%s%d", PFX_NODE_GSC, video_node_num);
44070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    fd = exynos_v4l2_open(node, O_RDWR);
44170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (fd < 0) {
4426134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_open(%s) fail", __func__, node);
44370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
44470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
44570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
44670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    cap = V4L2_CAP_STREAMING |
44770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang          V4L2_CAP_VIDEO_OUTPUT_MPLANE |
44870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang          V4L2_CAP_VIDEO_CAPTURE_MPLANE;
44970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
45070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_querycap(fd, cap) == false) {
4516134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
45270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (0 < fd)
45370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            close(fd);
45470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        fd = 0;
45570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
45670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
457e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
458e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
459e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
46070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return fd;
46170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
46270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
46370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
464e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Changstatic bool m_exynos_gsc_out_destroy(struct GSC_HANDLE *gsc_handle)
46570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
46670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct media_link * links;
46770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int i;
46870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
469e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
470e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
47170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle == NULL) {
4726134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::gsc_handle is NULL", __func__);
47370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
47470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
47570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
47670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->src.stream_on == true) {
47770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_gsc_out_stop((void *)gsc_handle) < 0)
4786134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_gsc_out_stop() fail", __func__);
47970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
48070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            gsc_handle->src.stream_on = false;
48170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
48270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
483e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    /* unlink : gscaler-out --> fimd */
48470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        for (i = 0; i < (int) gsc_handle->gsc_sd_entity->num_links; i++) {
48570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            links = &gsc_handle->gsc_sd_entity->links[i];
48670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
48770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if (links == NULL || links->source->entity != gsc_handle->gsc_sd_entity ||
48870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                 links->sink->entity   != gsc_handle->sink_sd_entity) {
48970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                continue;
49070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            } else if (exynos_media_setup_link(gsc_handle->media0,  links->source,
49170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                                                        links->sink, 0) < 0) {
4926134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin                ALOGE("%s::exynos_media_setup_unlink [src.entity=%d->sink.entity=%d] failed",
49370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                      __func__, links->source->entity->info.id, links->sink->entity->info.id);
49470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            }
49570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
49670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
49770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        close(gsc_handle->gsc_vd_entity->fd);
49870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        close(gsc_handle->gsc_sd_entity->fd);
49970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->gsc_vd_entity->fd = -1;
50070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->gsc_vd_entity->fd = -1;
50170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
502e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        Exynos_gsc_Out();
503e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
50470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return true;
50570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
50670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
50770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
50870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic bool m_exynos_gsc_destroy(
50970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle)
51070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
511e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
512e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
51370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->src.stream_on == true) {
51470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0)
5156134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_streamoff() fail", __func__);
51670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
51770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->src.stream_on = false;
51870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
51970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
52070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->dst.stream_on == true) {
52170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0)
5226134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_streamoff() fail", __func__);
52370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
52470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->dst.stream_on = false;
52570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
52670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
52770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (0 < gsc_handle->gsc_fd)
52870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        close(gsc_handle->gsc_fd);
52970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->gsc_fd = 0;
53070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
531e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
532e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
53370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return true;
53470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
53570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
53670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changbool m_exynos_gsc_find_and_trylock_and_create(
53770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle)
53870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
53970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int          i                 = 0;
54070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    bool         flag_find_new_gsc = false;
54170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int total_sleep_time  = 0;
54270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
543e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
544e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
54570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    do {
54670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        for (i = 0; i < NUM_OF_GSC_HW; i++) {
54770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            // HACK : HWComposer, HDMI uses gscaler with their own code.
54870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            //        So, This obj_mutex cannot defense their open()
549e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            if (i == 0 || i == 3)
55070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                continue;
55170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
55270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if (exynos_mutex_trylock(gsc_handle->obj_mutex[i]) == true) {
55370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
55470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                // destroy old one.
55570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                m_exynos_gsc_destroy(gsc_handle);
55670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
55770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                // create new one.
558e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(i);
55970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                if (gsc_handle->gsc_fd < 0) {
56070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                    gsc_handle->gsc_fd = 0;
56170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                    exynos_mutex_unlock(gsc_handle->obj_mutex[i]);
56270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                    continue;
56370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                }
56470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
56570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                if (gsc_handle->cur_obj_mutex)
56670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                    exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
56770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
56870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                gsc_handle->cur_obj_mutex = gsc_handle->obj_mutex[i];
56970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
57070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                flag_find_new_gsc = true;
57170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                break;
57270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            }
57370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
57470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
57570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        // waiting for another process doesn't use gscaler.
57670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        // we need to make decision how to do.
57770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (flag_find_new_gsc == false) {
57870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
57970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
5806134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGV("%s::waiting for anthere process doens't use gscaler", __func__);
58170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
58270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
58370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    } while(   flag_find_new_gsc == false
58470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
58570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
58670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (flag_find_new_gsc == false)
5876134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::we don't have no available gsc.. fail", __func__);
58870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
589e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
590e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
59170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return flag_find_new_gsc;
59270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
59370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
59470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic bool m_exynos_gsc_set_format(
59570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int              fd,
59670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct gsc_info *info,
59770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    bool             force)
59870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
599e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
600e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
60170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_requestbuffers req_buf;
60270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int                        plane_count;
60370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
60470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    plane_count = m_gsc_get_plane_count(info->v4l2_colorformat);
60570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (plane_count < 0) {
6066134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::not supported v4l2_colorformat", __func__);
60770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
60870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
60970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
61070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (force == false) {
61170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        // format
61270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        info->format.type = info->buf_type;
61370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_g_fmt(fd, &info->format) < 0) {
6146134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_g_fmt() fail type=%d", __func__, info->buf_type);
61570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return false;
61670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
61770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
61870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (info->width            != info->format.fmt.pix_mp.width ||
61970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            info->height           != info->format.fmt.pix_mp.height ||
62070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            info->v4l2_colorformat != info->format.fmt.pix_mp.pixelformat) {
6216134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGV("%s::info is different..)", __func__);
62270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto set_hw;
62370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
62470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
62570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        // crop
62670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        info->crop.type = info->buf_type;
62770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_g_crop(fd, &info->crop) < 0) {
6286134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_g_crop() fail", __func__);
62970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return false;
63070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
63170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
63270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (info->crop_left   != info->crop.c.left ||
63370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            info->crop_top    != info->crop.c.top ||
63470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            info->crop_width  != info->crop.c.width ||
63570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            info->crop_height != info->crop.c.height) {
6366134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGV("%s::crop is different..", __func__);
63770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto set_hw;
63870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
63970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
64070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        // rotation value;
64170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        int value = 0;
64270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
64370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_g_ctrl(fd, V4L2_CID_ROTATE, &value) < 0) {
6446134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_g_ctrl(V4L2_CID_ROTATE) fail", __func__);
64570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return false;
64670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
64770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
64870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (info->rotation != value) {
6496134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGV("%s::rotation is different..", __func__);
65070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto set_hw;
65170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
65270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
65370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_g_ctrl(fd, V4L2_CID_VFLIP, &value) < 0) {
6546134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_g_ctrl(V4L2_CID_ROTATE) fail", __func__);
65570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return false;
65670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
65770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
65870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (info->flip_horizontal != value) {
6596134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGV("%s::flip_horizontal is different..", __func__);
66070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto set_hw;
66170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
66270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
66370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_g_ctrl(fd, V4L2_CID_HFLIP, &value) < 0) {
6646134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_g_ctrl(V4L2_CID_ROTATE) fail", __func__);
66570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return false;
66670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
66770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
66870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (info->flip_vertical != value) {
6696134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGV("%s::flip_vertical is different..", __func__);
67070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto set_hw;
67170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
67270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
67370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        // skip s_fmt
6746134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGV("%s::fmt, crop is same with old-one, so skip s_fmt crop..", __func__);
67570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return true;
67670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
67770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
67870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changset_hw:
67970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
68070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (info->stream_on == true) {
68170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_streamoff(fd, info->buf_type) < 0) {
6826134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_streamoff() fail", __func__);
68370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return false;
68470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
68570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        info->stream_on = false;
68670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
68770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
68870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) {
6896134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__);
69070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
69170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
69270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
69370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) {
6946134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__);
69570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
69670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
69770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
69870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) {
6996134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__);
70070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
70170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
702e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    info->format.type = info->buf_type;
70370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->format.fmt.pix_mp.width       = info->width;
70470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->format.fmt.pix_mp.height      = info->height;
70570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat;
70670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->format.fmt.pix_mp.field       = V4L2_FIELD_ANY;
70770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->format.fmt.pix_mp.num_planes  = plane_count;
70870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
70970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_fmt(fd, &info->format) < 0) {
7106134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__);
71170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
71270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
71370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
71470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->crop.type     = info->buf_type;
71570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->crop.c.left   = info->crop_left;
71670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->crop.c.top    = info->crop_top;
71770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->crop.c.width  = info->crop_width;
71870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->crop.c.height = info->crop_height;
71970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
72070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_crop(fd, &info->crop) < 0) {
7216134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_s_crop() fail", __func__);
72270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
72370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
72470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
72570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) {
7266134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
72770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
72870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
72970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
73070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    req_buf.count  = 1;
73170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    req_buf.type   = info->buf_type;
732776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby    req_buf.memory = V4L2_MEMORY_DMABUF;
73370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) {
7346134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__);
73570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
73670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
73770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
738e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
739e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
74070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return true;
74170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
74270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
74370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic bool m_exynos_gsc_set_addr(
74470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int              fd,
74570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct gsc_info *info)
74670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
74770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int i;
74870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int plane_size[NUM_OF_GSC_PLANES];
74970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
75070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    m_gsc_get_plane_size(plane_size,
75170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                         info->width,
75270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                         info->height,
75370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                         info->v4l2_colorformat);
75470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
75570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->buffer.index    = 0;
75670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->buffer.type     = info->buf_type;
757776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby    info->buffer.memory   = V4L2_MEMORY_DMABUF;
75870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->buffer.m.planes = info->planes;
75970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    info->buffer.length   = info->format.fmt.pix_mp.num_planes;
76070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
76170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) {
762776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby        info->buffer.m.planes[i].m.fd = (int)info->addr[i];
76370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        info->buffer.m.planes[i].length    = plane_size[i];
76470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        info->buffer.m.planes[i].bytesused = 0;
76570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
76670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
76770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_qbuf(fd, &info->buffer) < 0) {
7686134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_qbuf() fail", __func__);
76970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
77070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
77170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
77270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return true;
77370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
77470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
77570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changvoid *exynos_gsc_create(
77670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void)
77770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
77870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int i     = 0;
77970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int op_id = 0;
78070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    char mutex_name[32];
78170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
782e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
783e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
78470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
78570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle == NULL) {
7866134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
78770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
78870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
78970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
79070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->gsc_fd = 0;
79170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    memset(&gsc_handle->src, 0, sizeof(struct gsc_info));
79270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    memset(&gsc_handle->dst, 0, sizeof(struct gsc_info));
79370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
79470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
79570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
79670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
79770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->op_mutex = NULL;
79870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < NUM_OF_GSC_HW; i++)
79970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->obj_mutex[i] = NULL;
80070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
80170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->cur_obj_mutex = NULL;
80270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->flag_local_path = false;
80370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->flag_exclusive_open = false;
80470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
80570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    srand(time(NULL));
80670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    op_id = rand() % 1000000; // just make random id
80770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id);
80870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name);
80970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->op_mutex == NULL) {
8106134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
81170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
81270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
81370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
81470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
81570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
81670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    // check if it is available
81770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < NUM_OF_GSC_HW; i++) {
81870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        sprintf(mutex_name, "%sObject%d", LOG_TAG, i);
81970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
82070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->obj_mutex[i] = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
82170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (gsc_handle->obj_mutex[i] == NULL) {
8226134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
82370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto err;
82470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
82570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
82670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
82770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) {
8286134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__);
82970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
83070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
83170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
83270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
83370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
83470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
83570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return (void *)gsc_handle;
83670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
83770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changerr:
83870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle) {
83970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        m_exynos_gsc_destroy(gsc_handle);
84070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
84170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (gsc_handle->cur_obj_mutex)
84270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
84370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
84470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        for (i = 0; i < NUM_OF_GSC_HW; i++) {
84570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if ((gsc_handle->obj_mutex[i] != NULL) &&
846e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
84770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
8486134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin                    ALOGE("%s::exynos_mutex_destroy() fail", __func__);
84970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            }
85070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
85170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
85270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (gsc_handle->op_mutex)
85370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            exynos_mutex_unlock(gsc_handle->op_mutex);
85470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
85570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
8566134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
85770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
85870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        free(gsc_handle);
85970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
86070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
861e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
862e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
86370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return NULL;
86470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
86570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
86670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changvoid *exynos_gsc_reserve(int dev_num)
86770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
86870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    char mutex_name[32];
86970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int total_sleep_time  = 0;
87070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    bool    gsc_flag = false;
87170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
87270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) {
8736134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
87470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return NULL;
87570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
87670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
87770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
87870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle == NULL) {
8796134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
88070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
88170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
88270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
88370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->gsc_fd = -1;
88470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->op_mutex = NULL;
88570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->cur_obj_mutex = NULL;
88670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
88770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num);
88870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
88970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->cur_obj_mutex == NULL) {
8906134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
89170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
89270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
89370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
89470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    do {
89570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) {
89670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            gsc_flag = true;
89770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            break;
89870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
89970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
90070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
9016134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGV("%s::waiting for another process to release the requested gscaler", __func__);
90270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
90370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
90470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_flag == true)
90570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang         return (void *)gsc_handle;
90670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
90770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changerr:
90870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle) {
90970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        free(gsc_handle);
91070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
91170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
91270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return NULL;
91370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
91470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
91570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changvoid exynos_gsc_release(void *handle)
91670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
91770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle;
91870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
91970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
9206134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
92170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return;
92270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
92370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
92470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
92570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_destroy(gsc_handle->cur_obj_mutex);
92670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    free(gsc_handle);
92770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return;
92870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
92970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
93070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changvoid *exynos_gsc_create_exclusive(
93170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int dev_num,
93270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int mode,
93370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int out_mode)
93470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
93570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int i     = 0;
93670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int op_id = 0;
93770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    char mutex_name[32];
93870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int total_sleep_time  = 0;
93970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    bool    gsc_flag = false;
94070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int ret = 0;
941e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
942e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
943e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
94470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) {
9456134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
94670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return NULL;
94770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
94870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
94970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) {
9506134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode);
95170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return NULL;
95270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
95370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
95470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
95570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle == NULL) {
9566134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
95770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
95870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
95970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    memset(gsc_handle, 0, sizeof(struct GSC_HANDLE));
960e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    gsc_handle->gsc_fd = -1;
96170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->gsc_mode = mode;
96270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
96370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
96470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
96570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
96670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->op_mutex = NULL;
96770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < NUM_OF_GSC_HW; i++)
96870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->obj_mutex[i] = NULL;
96970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
97070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->cur_obj_mutex = NULL;
97170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->flag_local_path = false;
97270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->flag_exclusive_open = true;
97370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
97470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    srand(time(NULL));
97570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    op_id = rand() % 1000000; // just make random id
97670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id);
97770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name);
97870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->op_mutex == NULL) {
9796134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
98070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
98170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
98270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
98370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
98470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
98570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num);
98670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
98770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->cur_obj_mutex == NULL) {
9886134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
98970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto err;
99070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
99170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
99270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    do {
99370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) {
99470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if (mode == GSC_M2M_MODE) {
995e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(dev_num);
996e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                if (gsc_handle->gsc_fd < 0) {
997e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                    ALOGE("%s::m_exynos_gsc_m2m_create(%i) fail", __func__, dev_num);
998e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                    goto err;
999e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                }
100070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            } else if (mode == GSC_OUTPUT_MODE) {
100170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                ret = m_exynos_gsc_output_create(gsc_handle, dev_num, out_mode);
100270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                if (ret < 0) {
10036134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin                    ALOGE("%s::m_exynos_gsc_output_create(%i) fail", __func__, dev_num);
100470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                    goto err;
100570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                }
100670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            }
100770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            /*else
100870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                gsc_handle->gsc_fd = m_exynos_gsc_capture_create(dev_num);*/
1009e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
101070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            gsc_flag = true;
101170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            break;
101270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
101370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
101470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
10156134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGV("%s::waiting for anthere process doens't use gscaler", __func__);
101670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
101770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
101870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
1019e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (gsc_flag == true) {
1020e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        Exynos_gsc_Out();
1021e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        return (void *)gsc_handle;
1022e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        }
102370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
102470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changerr:
102570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle) {
102670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        m_exynos_gsc_destroy(gsc_handle);
102770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
102870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (gsc_handle->cur_obj_mutex)
102970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
103070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
103170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        for (i = 0; i < NUM_OF_GSC_HW; i++) {
103270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if ((gsc_handle->obj_mutex[i] != NULL) &&
1033e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
103470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
10356134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin                    ALOGE("%s::exynos_mutex_destroy() fail", __func__);
103670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            }
103770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
103870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
103970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (gsc_handle->op_mutex)
104070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            exynos_mutex_unlock(gsc_handle->op_mutex);
104170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
104270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
10436134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
104470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
104570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        free(gsc_handle);
104670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
104770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1048e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1049e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
105070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return NULL;
105170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
105270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
105370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changvoid exynos_gsc_destroy(
105470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *handle)
105570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
105670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int i = 0;
105770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle;
105870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1059e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1060e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
106170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
10626134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
106370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return;
106470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
106570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
106670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
106770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
106870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->flag_exclusive_open == false)
106970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        exynos_mutex_lock(gsc_handle->cur_obj_mutex);
107070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
107170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->gsc_mode == GSC_OUTPUT_MODE)
1072e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        m_exynos_gsc_out_destroy(gsc_handle);
1073e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    else
1074e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        m_exynos_gsc_destroy(gsc_handle);
107570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
107670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
107770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
107870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < NUM_OF_GSC_HW; i++) {
107970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if ((gsc_handle->obj_mutex[i] != NULL) &&
1080e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
108170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
10826134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin                ALOGE("%s::exynos_mutex_destroy(obj_mutex) fail", __func__);
108370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
108470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
108570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
108670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
108770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
108870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
10896134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
109070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
109170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle)
109270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        free(gsc_handle);
1093e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1094e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1095e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
109670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
109770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
109870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_set_src_format(
109970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void        *handle,
110070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int width,
110170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int height,
110270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_left,
110370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_top,
110470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_width,
110570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_height,
110670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int v4l2_colorformat,
1107e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int cacheable,
1108e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int mode_drm)
110970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
1110e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1111e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
111270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
111370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
111470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
111570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
11166134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
111770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
111870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
111970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
112070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
112170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
112270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.width            = width;
112370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.height           = height;
112470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.crop_left        = crop_left;
112570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.crop_top         = crop_top;
112670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.crop_width       = crop_width;
112770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.crop_height      = crop_height;
112870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.v4l2_colorformat = v4l2_colorformat;
112970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.cacheable        = cacheable;
1130e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    gsc_handle->src.mode_drm         = mode_drm;
113170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
113270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->flag_exclusive_open == true) {
113370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->src, false) == false) {
11346134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_format(src) fail", __func__);
113570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
113670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
113770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
113870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
113970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1140e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1141e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
114270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
114370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
114470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
114570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_set_dst_format(
114670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void        *handle,
114770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int width,
114870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int height,
114970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_left,
115070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_top,
115170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_width,
115270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int crop_height,
115370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int v4l2_colorformat,
1154e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int cacheable,
1155e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int mode_drm)
115670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
1157e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1158e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
115970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
116070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
116170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
116270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
11636134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
116470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
116570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
116670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
116770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
116870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
116970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.width            = width;
117070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.height           = height;
117170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.crop_left        = crop_left;
117270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.crop_top         = crop_top;
117370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.crop_width       = crop_width;
117470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.crop_height      = crop_height;
117570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.v4l2_colorformat = v4l2_colorformat;
117670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.cacheable        = cacheable;
1177e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    gsc_handle->dst.mode_drm         = mode_drm;
117870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
117970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->flag_exclusive_open == true) {
118070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->dst, false) == false) {
11816134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_format(dst) fail", __func__);
118270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
118370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
118470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
118570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
118670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1187e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1188e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    return 0;
1189e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang}
1190e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1191e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Changstatic int exynos_gsc_ctrl_sysmmu(
1192e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int fd,
1193e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int flag)
1194e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang{
1195e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int sys_mmu_flag = flag ^ 1;
1196e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1197e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang#if 0 //it will be enabled later
1198e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (exynos_v4l2_s_ctrl(fd, V4L2_CID_USE_SYSMMU, sys_mmu_flag) < 0) {
1199e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_USE_SYSMMU) fail", __func__);
1200e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        return -1;
1201e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    }
1202e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang#endif
120370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
120470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
120570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
120670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_set_rotation(
120770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *handle,
120870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int   rotation,
120970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int   flip_horizontal,
121070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int   flip_vertical)
121170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
121270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int ret = -1;
121370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
121470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
121570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
121670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
12176134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
121870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return ret;
121970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
122070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
122170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
122270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
122370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int new_rotation = rotation % 360;
122470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
122570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (new_rotation % 90 != 0) {
12266134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__, rotation);
122770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto done;
122870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
122970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
123070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if(new_rotation < 0)
123170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        new_rotation = -new_rotation;
123270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
123370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.rotation        = new_rotation;
123470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.flip_horizontal = flip_horizontal;
123570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.flip_vertical   = flip_vertical;
123670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
123770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    ret = 0;
123870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changdone:
123970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
124070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
124170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return ret;
124270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
124370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
124470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_set_src_addr(
124570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *handle,
124670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *addr[3])
124770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
124870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
124970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
125070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1251e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1252e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
125370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
12546134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
125570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
125670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
125770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
125870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
125970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
126070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.addr[0] = addr[0];
126170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.addr[1] = addr[1];
126270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.addr[2] = addr[2];
126370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
126470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->flag_exclusive_open == true) {
126570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->src) == false) {
12666134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_addr(src) fail", __func__);
126770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
126870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
126970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
127070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
127170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1272e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1273e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
127470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
127570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
127670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
127770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_set_dst_addr(
127870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *handle,
127970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *addr[3])
128070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
128170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
128270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
128370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1284e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1285e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
128670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
12876134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
128870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
128970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
129070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
129170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
129270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
129370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.addr[0] = addr[0];
129470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.addr[1] = addr[1];
129570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->dst.addr[2] = addr[2];
129670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
129770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->flag_exclusive_open == true) {
129870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->dst) == false) {
12996134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_addr(dst) fail", __func__);
130070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
130170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
130270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
130370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
130470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1305e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1306e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
130770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
130870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
130970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
131070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic void rotateValueHAL2GSC(unsigned int transform,
131170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *rotate,
131270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *hflip,
131370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int *vflip)
131470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
131570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int rotate_flag = transform & 0x7;
131670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    *rotate = 0;
131770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    *hflip = 0;
131870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    *vflip = 0;
131970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
132070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (rotate_flag) {
132170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case HAL_TRANSFORM_ROT_90:
132270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *rotate = 90;
132370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
132470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case HAL_TRANSFORM_ROT_180:
132570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *rotate = 180;
132670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
132770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case HAL_TRANSFORM_ROT_270:
132870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *rotate = 270;
132970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
133070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
133170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *rotate = 90;
133270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *vflip = 1; /* set vflip to compensate the rot & flip order. */
133370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
133470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
133570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *rotate = 90;
133670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *hflip = 1; /* set hflip to compensate the rot & flip order. */
133770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
133870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case HAL_TRANSFORM_FLIP_H:
133970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *hflip = 1;
134070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang         break;
134170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case HAL_TRANSFORM_FLIP_V:
134270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        *vflip = 1;
134370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang         break;
134470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
134570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
134670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
134770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
134870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
134970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changstatic bool get_plane_size(int V4L2_PIX,
135070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int * size,
135170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int frame_size,
1352e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int src_planes)
135370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
1354e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int frame_ratio = 1;
135570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int src_bpp    = get_yuv_bpp(V4L2_PIX);
135670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
135770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    src_planes = (src_planes == -1) ? 1 : src_planes;
135870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    frame_ratio = 8 * (src_planes -1) / (src_bpp - 8);
135970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
136070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (src_planes) {
136170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 1:
136270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        switch (V4L2_PIX) {
136370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_BGR32:
136470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_RGB32:
136570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            size[0] = frame_size << 2;
136670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            break;
136770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_RGB565X:
136870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_NV16:
136970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_NV61:
137070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_YUYV:
137170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_UYVY:
137270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_VYUY:
137370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_YVYU:
137470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            size[0] = frame_size << 1;
137570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            break;
137670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_YUV420:
137770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_NV12:
137870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        case V4L2_PIX_FMT_NV21:
137966e91991f45bf7c56f4993a2c5c2356421017368Sungjoong Kang        case V4L2_PIX_FMT_NV21M:
138070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            size[0] = (frame_size * 3) >> 1;
138170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            break;
138270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        default:
13836134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::invalid color type", __func__);
138470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return false;
138570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            break;
138670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
138770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[1] = 0;
138870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[2] = 0;
138970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
139070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 2:
139170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[0] = frame_size;
139270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[1] = frame_size / frame_ratio;
139370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[2] = 0;
139470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
139570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case 3:
139670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[0] = frame_size;
139770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[1] = frame_size / frame_ratio;
139870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        size[2] = frame_size / frame_ratio;
139970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
140070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
14016134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::invalid color foarmt", __func__);
140270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return false;
140370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
140470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
140570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
140670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return true;
140770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
140870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1409e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Changint exynos_gsc_m2m_config(void *handle,
1410e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *src_img,
1411e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *dst_img)
1412e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang{
1413e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    struct GSC_HANDLE *gsc_handle;
1414e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int32_t      src_color_space;
1415e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int32_t      dst_color_space;
1416e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int ret;
1417e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int rotate;
1418e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int hflip;
1419e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    unsigned int vflip;
1420e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1421e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1422e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1423e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
1424e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang     if (gsc_handle == NULL) {
1425e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ALOGE("%s::gsc_handle == NULL() fail", __func__);
1426e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        return -1;
1427e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    }
1428e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1429e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
1430e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
1431e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
1432e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_set_rotation(gsc_handle, rotate, hflip, vflip);
1433e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1434e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    ret = exynos_gsc_set_src_format(gsc_handle,  src_img->fw, src_img->fh,
1435e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                                  src_img->x, src_img->y, src_img->w, src_img->h,
1436e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                                  src_color_space, src_img->cacheable, src_img->drmMode);
1437e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (ret < 0) {
1438e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ALOGE("%s: fail: exynos_gsc_set_src_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1439e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            __func__, src_img->fw, src_img->fh, src_img->x, src_img->y, src_img->w, src_img->h,
1440e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            src_color_space, src_img->rot);
1441e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        return -1;
1442e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    }
1443e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1444e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    ret = exynos_gsc_set_dst_format(gsc_handle, dst_img->fw, dst_img->fh,
1445e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                                  dst_img->x, dst_img->y, dst_img->w, dst_img->h,
1446e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang                                  dst_color_space, dst_img->cacheable, src_img->drmMode);
1447e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (ret < 0) {
1448e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ALOGE("%s: fail: exynos_gsc_set_dst_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
1449e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y, dst_img->w, dst_img->h,
1450e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            src_color_space, dst_img->rot);
1451e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        return -1;
1452e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    }
1453e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1454e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1455e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1456e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    return 0;
1457e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang}
1458e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
145970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_out_config(void *handle,
1460e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *src_img,
1461e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *dst_img)
146270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
146370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
146470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_format  fmt;
146570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_crop    crop;
146670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_requestbuffers reqbuf;
146770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_subdev_format sd_fmt;
146870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_subdev_crop   sd_crop;
146970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int i;
147070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int rotate;
147170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int hflip;
147270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int vflip;
147370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int plane_size[NUM_OF_GSC_PLANES];
1474cd63257f03af96d2efa5baaa0b97d9672a79f307Greg Hackmann    bool rgb;
147570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
147670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_rect dst_rect;
147770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int32_t      src_color_space;
147870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int32_t      dst_color_space;
147970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int32_t      src_planes;
1480e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
148170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
148270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang     if (gsc_handle == NULL) {
14836134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::gsc_handle == NULL() fail", __func__);
148470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
148570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
148670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1487e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1488e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
148970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang     if (gsc_handle->src.stream_on != false) {
14906134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("Error: Src is already streamed on !!!!");
149170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
149270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang     }
149370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1494e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    memcpy(&gsc_handle->src_img, src_img, sizeof(exynos_gsc_img));
1495e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    memcpy(&gsc_handle->dst_img, dst_img, sizeof(exynos_gsc_img));
149670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
149770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
149870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    src_planes = get_yuv_planes(src_color_space);
1499ba718a434c6a2ed414752043c933a4abcc821fc0Benoit Goby    src_planes = (src_planes == -1) ? 1 : src_planes;
1500ba718a434c6a2ed414752043c933a4abcc821fc0Benoit Goby    rgb = get_yuv_planes(dst_color_space) == -1;
150170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
150270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
150370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (m_exynos_gsc_check_src_size(&gsc_handle->src_img.fw, &gsc_handle->src_img.fh,
150470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->src_img.x, &gsc_handle->src_img.y,
150570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->src_img.w, &gsc_handle->src_img.h,
150670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        src_color_space) == false) {
15076134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__);
150870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
150970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
151070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
151170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (m_exynos_gsc_check_dst_size(&gsc_handle->dst_img.fw, &gsc_handle->dst_img.fh,
151270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->dst_img.x, &gsc_handle->dst_img.y,
151370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->dst_img.w, &gsc_handle->dst_img.h,
151470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        dst_color_space,
151570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        rotate) == false) {
15166134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__);
151770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
151870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
151970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
152070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /*set: src v4l2_buffer*/
152170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.src_buf_idx = 0;
152270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.qbuf_cnt = 0;
152370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* set format: src pad of GSC sub-dev*/
152470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_fmt.pad   = GSCALER_SUBDEV_PAD_SOURCE;
152570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
152670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_fmt.format.width  = gsc_handle->dst_img.fw;
152770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_fmt.format.height = gsc_handle->dst_img.fh;
1528cd63257f03af96d2efa5baaa0b97d9672a79f307Greg Hackmann    sd_fmt.format.code   = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
1529cd63257f03af96d2efa5baaa0b97d9672a79f307Greg Hackmann                                    V4L2_MBUS_FMT_YUV8_1X24;
153070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_subdev_s_fmt(gsc_handle->gsc_sd_entity->fd, &sd_fmt) < 0) {
15316134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::GSC subdev set format failed", __func__);
153270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
153370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
153470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
153570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* set crop: src crop of GSC sub-dev*/
153670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.pad   = GSCALER_SUBDEV_PAD_SOURCE;
153770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
153870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.left   = gsc_handle->dst_img.x;
153970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.top    = gsc_handle->dst_img.y;
154070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.width  = gsc_handle->dst_img.w;
154170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.height = gsc_handle->dst_img.h;
154270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_subdev_s_crop(gsc_handle->gsc_sd_entity->fd, &sd_crop) < 0) {
15436134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::GSC subdev set crop failed", __func__);
154470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
154570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
154670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
154770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* sink pad is connected to GSC out */
154870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /*  set format: sink sub-dev */
154970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->out_mode == GSC_OUT_FIMD)
155070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        sd_fmt.pad   = FIMD_SUBDEV_PAD_SINK;
155170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    else
155270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        sd_fmt.pad   = MIXER_V_SUBDEV_PAD_SINK;
1553e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
155470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1555e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    sd_fmt.format.width  = gsc_handle->dst_img.w;
1556e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    sd_fmt.format.height = gsc_handle->dst_img.h;
1557cd63257f03af96d2efa5baaa0b97d9672a79f307Greg Hackmann    sd_fmt.format.code   = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
1558cd63257f03af96d2efa5baaa0b97d9672a79f307Greg Hackmann                                    V4L2_MBUS_FMT_YUV8_1X24;
155970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) {
15606134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad);
156170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
156270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
156370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
156470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /*  set crop: sink sub-dev */
156570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->out_mode == GSC_OUT_FIMD)
156670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        sd_crop.pad   = FIMD_SUBDEV_PAD_SINK;
156770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    else
156870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        sd_crop.pad   = MIXER_V_SUBDEV_PAD_SINK;
156970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
157070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
157170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.left   = gsc_handle->dst_img.x;
157270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.top    = gsc_handle->dst_img.y;
157370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.width  = gsc_handle->dst_img.w;
157470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    sd_crop.rect.height = gsc_handle->dst_img.h;
157570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) {
15766134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad);
157770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
157870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
157970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
158070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /*set GSC ctrls */
1581e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_ROTATE, rotate) < 0) {
15826134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed", __func__,  rotate);
158370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
158470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
158570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1586e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_HFLIP, hflip) < 0) {
15876134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed", __func__,  hflip);
158870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
158970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
159070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1591e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_VFLIP, vflip) < 0) {
15926134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed", __func__,  vflip);
159370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
159470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
159570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1596e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CACHEABLE, 1) < 0) {
15976134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed", __func__);
159870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
159970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
160070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
160170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang      /* set src format  :GSC video dev*/
160270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    fmt.type  = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
160370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    fmt.fmt.pix_mp.width            = gsc_handle->src_img.fw;
160470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    fmt.fmt.pix_mp.height           = gsc_handle->src_img.fh;
160570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    fmt.fmt.pix_mp.pixelformat    = src_color_space;
160670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    fmt.fmt.pix_mp.field              = V4L2_FIELD_NONE;
160770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    fmt.fmt.pix_mp.num_planes   = src_planes;
1608e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
160970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_fmt(gsc_handle->gsc_vd_entity->fd, &fmt) < 0) {
16106134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::videodev set format failed", __func__);
161170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            return -1;
161270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
161370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
161470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* set src crop info :GSC video dev*/
161570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    crop.type     = fmt.type;
161670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    crop.c.left    = gsc_handle->src_img.x;
161770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    crop.c.top     = gsc_handle->src_img.y;
161870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    crop.c.width  = gsc_handle->src_img.w;
161970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    crop.c.height = gsc_handle->src_img.h;
162070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
162170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_s_crop(gsc_handle->gsc_vd_entity->fd, &crop) < 0) {
16226134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::videodev set crop failed", __func__);
162370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
162470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
1625e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
162670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    reqbuf.type   = fmt.type;
1627776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby    reqbuf.memory = V4L2_MEMORY_DMABUF;
162870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    reqbuf.count  = MAX_BUFFERS_GSCALER_OUT;
162970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
163070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) {
16316134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::request buffers failed", __func__);
163270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
163370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
1634e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1635e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1636e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
163770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
163870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
163970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
164070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_out_run(void *handle,
164170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int yAddr,
164270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int uAddr,
164370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int vAddr)
164470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
164570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
164670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_plane  planes[NUM_OF_GSC_PLANES];
164770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_buffer buf;
164870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int32_t      src_color_space;
164970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int32_t      src_planes;
165070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int             i;
165170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    unsigned int plane_size[NUM_OF_GSC_PLANES];
165270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
165370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
165470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
16556134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
165670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
165770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
165870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
165970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    memset(&buf, 0, sizeof(struct v4l2_buffer));
166070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < NUM_OF_GSC_PLANES; i++)
166170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        memset(&planes[i], 0, sizeof(struct v4l2_plane));
166270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
166370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc_handle->src_img.format);
166470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    src_planes = get_yuv_planes(src_color_space);
166570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    src_planes = (src_planes == -1) ? 1 : src_planes;
166670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
166770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    buf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1668776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby    buf.memory   = V4L2_MEMORY_DMABUF;
166970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    buf.length   = src_planes;
167070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    buf.index    = gsc_handle->src.src_buf_idx;
167170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    buf.m.planes = planes;
167270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
167370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.addr[0] = (void *)yAddr;
167470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.addr[1] = (void *)uAddr;
167570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.addr[2] = (void *)vAddr;
167670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
167770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (get_plane_size(src_color_space, plane_size,
167870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->src_img.fw * gsc_handle->src_img.fh, src_planes) != true) {
16796134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s:get_plane_size:fail", __func__);
168070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
168170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
168270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
168370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < buf.length; i++) {
1684776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby        buf.m.planes[i].m.fd = (int)gsc_handle->src.addr[i];
168570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        buf.m.planes[i].length    = plane_size[i];
168670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        buf.m.planes[i].bytesused = plane_size[i];
168770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
168870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
168970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* Queue the buf */
169070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_qbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) {
16916134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)", __func__,
169270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT);
169370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
169470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
169570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.src_buf_idx++;
169670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.qbuf_cnt++;
169770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
169870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->src.stream_on == false) {
1699e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        /* stream on after queing the second buffer
1700e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            to do: below logic should be changed to handle the single frame videos */
1701e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang#ifndef GSC_OUT_DELAYED_STREAMON
1702e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        if (gsc_handle->src.src_buf_idx == (MAX_BUFFERS_GSCALER_OUT - 2)) {
1703e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang#else
170470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (gsc_handle->src.src_buf_idx == (MAX_BUFFERS_GSCALER_OUT - 1)) {
1705e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang#endif
170670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if (exynos_v4l2_streamon(gsc_handle->gsc_vd_entity->fd, buf.type) < 0) {
17076134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin                ALOGE("%s::stream on failed", __func__);
170870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                return -1;
170970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            }
171070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            gsc_handle->src.stream_on = true;
171170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
171270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->src.src_buf_idx = gsc_handle->src.src_buf_idx % MAX_BUFFERS_GSCALER_OUT;
1713e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang#ifndef GSC_OUT_DMA_BLOCKING
171470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return 0;
1715e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang#endif
171670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
1717e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1718e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (gsc_handle->src.qbuf_cnt < MAX_BUFFERS_GSCALER_OUT)
1719e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        return 0;
1720e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
172170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.src_buf_idx = gsc_handle->src.src_buf_idx % MAX_BUFFERS_GSCALER_OUT;
172270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    for (i = 0; i < MAX_BUFFERS_GSCALER_OUT; i++)
172370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        memset(&planes[i], 0, sizeof(struct v4l2_plane));
172470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
172570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    buf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1726776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby    buf.memory   = V4L2_MEMORY_DMABUF;
172770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    buf.length   = src_planes;
172870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    buf.m.planes = planes;
172970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
173070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang     /* DeQueue a buf */
173170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang     if (exynos_v4l2_dqbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) {
17326134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)", __func__,
173370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT);
173470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
173570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang     }
1736e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang     return 0;
173770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
173870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
173970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_out_stop(void *handle)
174070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
174170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
174270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_requestbuffers reqbuf;
174370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_buffer buf;
174470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct v4l2_plane  planes[NUM_OF_GSC_PLANES];
174570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int i;
174670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1747e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1748e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
174970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
175070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
17516134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
175270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
175370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
1754e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
175570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->src.stream_on == false) {
175670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        /* to handle special scenario.*/
175770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            gsc_handle->src.src_buf_idx = 0;
1758e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        gsc_handle->src.qbuf_cnt = 0;
17596134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGD("%s::GSC is already stopped", __func__);
1760e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        goto SKIP_STREAMOFF;
176170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
176270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.src_buf_idx = 0;
176370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->src.qbuf_cnt = 0;
1764e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    gsc_handle->src.stream_on = false;
176570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
176670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_streamoff(gsc_handle->gsc_vd_entity->fd,
176770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
17686134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::stream off failed", __func__);
176970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
177070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
1771e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho ChangSKIP_STREAMOFF:
177270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /* Clear Buffer */
177370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    /*todo: support for other buffer type & memory */
177470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    reqbuf.type   = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1775776bd695a6ab0be71a3765a40f9dcec99b0f7f51Benoit Goby    reqbuf.memory = V4L2_MEMORY_DMABUF;
177670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    reqbuf.count  = 0;
177770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
177870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) {
17796134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::request buffers failed", __func__);
178070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
178170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
1782e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1783e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1784e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
178570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
178670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
178770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
17887b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Songstatic int exynos_gsc_m2m_run_core(void *handle)
178970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
179070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
17917b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
179270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
179370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1794e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1795e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
179670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
17976134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
179870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
179970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
180070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
180170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    bool flag_new_gsc = false;
180270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
180370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->flag_exclusive_open == false) {
180470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == false) {
180570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) {
18066134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin                ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__);
180770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                goto done;
180870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            }
180970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            flag_new_gsc = true;
181070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
181170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
181270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_check_src_size(&gsc_handle->src.width, &gsc_handle->src.height,
181370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->src.crop_left, &gsc_handle->src.crop_top,
181470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->src.crop_width, &gsc_handle->src.crop_height,
181570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        gsc_handle->src.v4l2_colorformat) == false) {
18166134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__);
181770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
181870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
181970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
182070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_check_dst_size(&gsc_handle->dst.width, &gsc_handle->dst.height,
182170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->dst.crop_left, &gsc_handle->dst.crop_top,
182270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        &gsc_handle->dst.crop_width, &gsc_handle->dst.crop_height,
182370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        gsc_handle->dst.v4l2_colorformat,
182470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                        gsc_handle->dst.rotation) == false) {
18256134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__);
182670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
182770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
182870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
182970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->src, flag_new_gsc) == false) {
18306134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_format(src) fail", __func__);
183170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
183270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
183370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
183470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->dst, flag_new_gsc) == false) {
18356134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_format(dst) fail", __func__);
183670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
183770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
183870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
183970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->src) == false) {
18406134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_addr(src) fail", __func__);
184170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
184270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
184370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
184470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->dst) == false) {
18456134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_set_addr(dst) fail", __func__);
184670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
184770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
184870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
184970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
185070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->src.stream_on == false) {
185170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) {
18526134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__);
185370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
185470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
185570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->src.stream_on = true;
185670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
185770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
185870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->dst.stream_on == false) {
185970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) {
18606134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__);
186170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
186270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
186370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        gsc_handle->dst.stream_on = true;
186470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
186570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
18667b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    Exynos_gsc_Out();
18677b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
18687b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    return 0;
18697b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
18707b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Songdone:
18717b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    return -1;
18727b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song}
18737b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
18747b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Songstatic int exynos_gsc_m2m_wait_frame_done(void *handle)
18757b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song{
18767b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    struct GSC_HANDLE *gsc_handle;
18777b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    struct v4l2_requestbuffers req_buf;
18787b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
18797b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    gsc_handle = (struct GSC_HANDLE *)handle;
18807b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
18817b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    Exynos_gsc_In();
18827b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
18837b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (handle == NULL) {
18847b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::handle == NULL() fail", __func__);
18857b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
18867b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
18877b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
18887b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if ((gsc_handle->src.stream_on == false) || (gsc_handle->dst.stream_on == false)) {
18897b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__);
18907b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
18917b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
18927b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
189370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->src.buffer) < 0) {
18946134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__);
18957b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
189670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
189770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
189870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->dst.buffer) < 0) {
18996134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__);
19007b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
19017b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
19027b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19037b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) {
19047b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__);
19057b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
19067b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
19077b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    gsc_handle->src.stream_on = false;
19087b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19097b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) {
19107b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__);
19117b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
19127b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
19137b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    gsc_handle->dst.stream_on = false;
19147b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19157b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    /* src: clear_buf */
19167b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    req_buf.count  = 0;
19177b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    req_buf.type   = gsc_handle->src.buf_type;
19187b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    req_buf.memory = V4L2_MEMORY_DMABUF;
19197b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) {
19207b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__);
19217b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
19227b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
19237b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19247b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    /* dst: clear_buf */
19257b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    req_buf.count  = 0;
19267b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    req_buf.type   = gsc_handle->dst.buf_type;
19277b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    req_buf.memory = V4L2_MEMORY_DMABUF;
19287b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) {
19297b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__);
19307b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
19317b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
19327b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19337b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    Exynos_gsc_Out();
19347b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19357b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song     return 0;
19367b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song}
19377b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19387b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Songint exynos_gsc_convert(
19397b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    void *handle)
19407b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song{
19417b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    struct GSC_HANDLE *gsc_handle;
19427b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    int ret    = -1;
19437b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    gsc_handle = (struct GSC_HANDLE *)handle;
19447b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19457b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    Exynos_gsc_In();
19467b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19477b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (handle == NULL) {
19487b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::handle == NULL() fail", __func__);
19497b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
19507b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    }
19517b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19527b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    exynos_mutex_lock(gsc_handle->op_mutex);
19537b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19547b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (gsc_handle->flag_local_path == true) {
19557b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::this exynos_gsc is connected by another hw internaly. So, don't call exynos_gsc_convert()", __func__);
19567b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song            goto done;
19577b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        }
19587b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19597b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (exynos_gsc_m2m_run_core(handle) < 0) {
19607b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::exynos_gsc_run_core fail", __func__);
19617b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song            goto done;
19627b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        }
19637b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
19647b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    if (exynos_gsc_m2m_wait_frame_done(handle) < 0) {
19657b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__);
196670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        goto done;
196770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
196870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
196970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    ret = 0;
197070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
197170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changdone:
197270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (gsc_handle->flag_exclusive_open == false) {
197370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (gsc_handle->flag_local_path == false)
197470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
197570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
197670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
197770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
197870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1979e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
1980e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
198170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return ret;
198270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
198370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
1984e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Changint exynos_gsc_m2m_run(void *handle,
1985e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *src_img,
1986e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *dst_img)
1987e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang{
1988e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    void *addr[3] = {NULL, NULL, NULL};
1989e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    int ret = 0;
1990e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1991e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
1992e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1993e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    addr[0] = (void *)src_img->yaddr;
1994e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    addr[1] = (void *)src_img->uaddr;
1995e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    addr[2] = (void *)src_img->vaddr;
1996e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
1997e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    ret = exynos_gsc_set_src_addr(handle, addr);
1998e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (ret < 0) {
1999e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ALOGE("%s::fail: exynos_gsc_set_src_addr[%x %x %x]", __func__,
2000e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]);
20017b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
2002e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    }
2003e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
2004e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    addr[0] = (void *)dst_img->yaddr;
2005e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    addr[1] = (void *)dst_img->uaddr;
2006e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    addr[2] = (void *)dst_img->vaddr;
2007e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    ret = exynos_gsc_set_dst_addr(handle, addr);
2008e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    if (ret < 0) {
2009e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ALOGE("%s::fail: exynos_gsc_set_dst_addr[%x %x %x]", __func__,
2010e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang            (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]);
20117b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
2012e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    }
2013e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
20147b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    ret = exynos_gsc_m2m_run_core(handle);
2015e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang     if (ret < 0) {
20167b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ALOGE("%s::fail: exynos_gsc_m2m_run_core", __func__);
20177b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        return -1;
2018e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    }
2019e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
2020e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
2021e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
2022e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    return 0;
2023e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang}
2024e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
202570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_config_exclusive(void *handle,
2026e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *src_img,
2027e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *dst_img)
202870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
2029e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
2030e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
2031e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
203270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang     struct GSC_HANDLE *gsc_handle;
203370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int ret = 0;
203470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
203570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
20366134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
203770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
203870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
203970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
204070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (gsc_handle->gsc_mode) {
204170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case GSC_M2M_MODE:
2042e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ret = exynos_gsc_m2m_config(handle, src_img, dst_img);
204370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
204470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case GSC_OUTPUT_MODE:
204570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        ret = exynos_gsc_out_config(handle, src_img, dst_img);
204670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
204770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case  GSC_CAPTURE_MODE:
204870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        //to do
204970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
205070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
205170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
205270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
2053e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
2054e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
2055e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
205670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return ret;
205770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
205870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
205970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
206070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_run_exclusive(void *handle,
2061e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *src_img,
2062e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    exynos_gsc_img *dst_img)
206370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
206470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
206570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int ret = 0;
20667b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
20677b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    Exynos_gsc_In();
20687b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
206970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
207070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
20716134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
207270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
207370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
207470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
207570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (gsc_handle->gsc_mode) {
207670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case GSC_M2M_MODE:
2077e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        ret = exynos_gsc_m2m_run(handle, src_img, dst_img);
207870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
207970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case GSC_OUTPUT_MODE:
208070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        ret = exynos_gsc_out_run(handle, src_img->yaddr,
208170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang                                                src_img->uaddr, src_img->vaddr);
208270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
208370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case  GSC_CAPTURE_MODE:
208470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        //to do
208570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
208670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
208770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
208870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
20897b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
20907b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song    Exynos_gsc_Out();
20917b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song
209270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return ret;
209370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
209470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
209570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_stop_exclusive(void *handle)
209670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
209770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
209870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int ret = 0;
209970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
2100e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
2101e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
2102e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
210370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
21046134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
210570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
210670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
210770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
210870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    switch (gsc_handle->gsc_mode) {
210970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case GSC_M2M_MODE:
21107b062be72289de0209a8d44e4a9f638539cc6e62Yongbae Song        ret = exynos_gsc_m2m_wait_frame_done(handle);
211170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
211270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case GSC_OUTPUT_MODE:
211370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        ret = exynos_gsc_out_stop(handle);
211470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
211570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    case  GSC_CAPTURE_MODE:
211670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        //to do
211770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        break;
211870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    default:
2119e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang        break;
212070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
2121e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
2122e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
2123e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
212470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return ret;
212570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
212670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
212770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_connect(
212870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *handle,
212970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *hw)
213070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
213170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
213270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    int ret    = -1;
213370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
213470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
2135e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
2136e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
213770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
21386134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
213970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
214070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
214170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
214270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
214370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
214470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->flag_local_path = true;
214570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
214670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == false) {
214770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) {
21486134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin            ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__);
214970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang            goto done;
215070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        }
215170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
215270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
215370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    ret = 0;
215470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
2155e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
2156e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
215770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changdone:
215870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
215970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
216070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return ret;
216170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
216270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
216370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Changint exynos_gsc_disconnect(
216470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *handle,
216570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    void *hw)
216670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang{
216770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    struct GSC_HANDLE *gsc_handle;
216870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle = (struct GSC_HANDLE *)handle;
216970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
2170e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_In();
2171e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
217270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    if (handle == NULL) {
21736134b8bbccf63f722120ad2ff24b5ab629b8e269Dima Zavin        ALOGE("%s::handle == NULL() fail", __func__);
217470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang        return -1;
217570007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    }
217670007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
217770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_lock(gsc_handle->op_mutex);
217870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
217970007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    gsc_handle->flag_local_path = false;
218070007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
218170007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
218270007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
218370007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    exynos_mutex_unlock(gsc_handle->op_mutex);
218470007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang
2185e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang    Exynos_gsc_Out();
2186e6a0625be3962fd12a9fbdb9f6dfb2c40a46b902Jiho Chang
218770007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang    return 0;
218870007c4e11bff0d255cdaddb753fddf8508ce08aJiho Chang}
2189