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