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