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