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