blob: 2b3f09feecf04408c171627368eb2fd172b43dba [file] [log] [blame]
Chirayu Desai0a336cc2012-07-12 14:37:05 +05301/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 *
19 * @author Rama, Meka(v.meka@samsung.com)
20 Sangwoo, Park(sw5771.park@samsung.com)
21 Jamie Oh (jung-min.oh@samsung.com)
22 * @date 2011-07-28
23 *
24 */
25
26#include "SecHWCUtils.h"
27
28int window_open(struct hwc_win_info_t *win, int id)
29{
30 char name[64];
31
32 char const * const device_template = "/dev/graphics/fb%u";
33 /* window & FB maping
34 fb0 -> win-id : 2
35 fb1 -> win-id : 3
36 fb2 -> win-id : 4
37 fb3 -> win-id : 0
38 fb4 -> win_id : 1
39 it is pre assumed that ...win0 or win1 is used here..
40 */
41 switch (id) {
42 case 0:
43 case 1:
44 case 2:
45 break;
46 default:
47 ALOGE("%s::id(%d) is weird", __func__, id);
48 goto error;
49 }
50
51 snprintf(name, 64, device_template, (id + 3)%5);
52
53 win->fd = open(name, O_RDWR);
54 if (win->fd < 0) {
55 ALOGE("%s::Failed to open window device (%s) : %s",
56 __func__, strerror(errno), device_template);
57 goto error;
58 }
59
60 return 0;
61
62error:
63 if (0 <= win->fd)
64 close(win->fd);
65 win->fd = -1;
66
67 return -1;
68}
69
70int window_close(struct hwc_win_info_t *win)
71{
72 int ret = 0;
73
74 if (0 <= win->fd)
75 ret = close(win->fd);
76 win->fd = -1;
77
78 return ret;
79}
80
81int window_set_pos(struct hwc_win_info_t *win)
82{
83 struct secfb_user_window window;
84
85 /* before changing the screen configuration...powerdown the window */
86 if(window_hide(win) != 0)
87 return -1;
88
89 win->var_info.xres = win->rect_info.w;
90 win->var_info.yres = win->rect_info.h;
91
92 win->var_info.activate &= ~FB_ACTIVATE_MASK;
93 win->var_info.activate |= FB_ACTIVATE_FORCE;
94
95 if (ioctl(win->fd, FBIOPUT_VSCREENINFO, &(win->var_info)) < 0) {
96 ALOGE("%s::FBIOPUT_VSCREENINFO(%d, %d) fail",
97 __func__, win->rect_info.w, win->rect_info.h);
98 return -1;
99 }
100
101 window.x = win->rect_info.x;
102 window.y = win->rect_info.y;
103
104 if (ioctl(win->fd, SECFB_WIN_POSITION, &window) < 0) {
105 ALOGE("%s::S3CFB_WIN_POSITION(%d, %d) fail",
106 __func__, window.x, window.y);
107 return -1;
108 }
109
110 return 0;
111}
112
113int window_get_info(struct hwc_win_info_t *win)
114{
115 if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) {
116 ALOGE("FBIOGET_FSCREENINFO failed : %s", strerror(errno));
117 goto error;
118 }
119
120 return 0;
121
122error:
123 win->fix_info.smem_start = 0;
124
125 return -1;
126}
127
128int window_pan_display(struct hwc_win_info_t *win)
129{
130 struct fb_var_screeninfo *lcd_info = &(win->lcd_info);
131
132 lcd_info->yoffset = lcd_info->yres * win->buf_index;
133
134 if (ioctl(win->fd, FBIOPAN_DISPLAY, lcd_info) < 0) {
135 ALOGE("%s::FBIOPAN_DISPLAY(%d / %d / %d) fail(%s)",
136 __func__, lcd_info->yres, win->buf_index, lcd_info->yres_virtual,
137 strerror(errno));
138 return -1;
139 }
140 return 0;
141}
142
143int window_show(struct hwc_win_info_t *win)
144{
145 if(win->power_state == 0) {
146 if (ioctl(win->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
147 ALOGE("%s: FBIOBLANK failed : (%d:%s)", __func__, win->fd,
148 strerror(errno));
149 return -1;
150 }
151 win->power_state = 1;
152 }
153 return 0;
154}
155
156int window_hide(struct hwc_win_info_t *win)
157{
158 if (win->power_state == 1) {
159 if (ioctl(win->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
160 ALOGE("%s::FBIOBLANK failed : (%d:%s)",
161 __func__, win->fd, strerror(errno));
162 return -1;
163 }
164 win->power_state = 0;
165 }
166 return 0;
167}
168
169int window_get_global_lcd_info(struct hwc_context_t *ctx)
170{
171 struct hwc_win_info_t win;
172 int ret = 0;
173
174 if (ioctl(ctx->global_lcd_win.fd, FBIOGET_VSCREENINFO, &ctx->lcd_info) < 0) {
175 ALOGE("FBIOGET_VSCREENINFO failed : %s", strerror(errno));
176 return -1;
177 }
178
179 if (ctx->lcd_info.xres == 0) {
180 ctx->lcd_info.xres = DEFAULT_LCD_WIDTH;
181 ctx->lcd_info.xres_virtual = DEFAULT_LCD_WIDTH;
182 }
183
184 if (ctx->lcd_info.yres == 0) {
185 ctx->lcd_info.yres = DEFAULT_LCD_HEIGHT;
186 ctx->lcd_info.yres_virtual = DEFAULT_LCD_HEIGHT * NUM_OF_WIN_BUF;
187 }
188
189 if (ctx->lcd_info.bits_per_pixel == 0)
190 ctx->lcd_info.bits_per_pixel = DEFAULT_LCD_BPP;
191
192 return 0;
193}
194
195int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src)
196{
197 struct v4l2_format fmt;
198 struct v4l2_cropcap cropcap;
199 struct v4l2_crop crop;
200 struct v4l2_requestbuffers req;
201
202 /*
203 * To set size & format for source image (DMA-INPUT)
204 */
205 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
206 fmt.fmt.pix.width = src->full_width;
207 fmt.fmt.pix.height = src->full_height;
208 fmt.fmt.pix.pixelformat = src->color_space;
209 fmt.fmt.pix.field = V4L2_FIELD_NONE;
210
211 if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0) {
212 ALOGE("VIDIOC_S_FMT failed : errno=%d (%s) : fd=%d", errno,
213 strerror(errno), fd);
214 return -1;
215 }
216
217 /*
218 * crop input size
219 */
220 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
221 if (0x50 == hw_ver) {
222 crop.c.left = src->start_x;
223 crop.c.top = src->start_y;
224 } else {
225 crop.c.left = 0;
226 crop.c.top = 0;
227 }
228 crop.c.width = src->width;
229 crop.c.height = src->height;
230 if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
231 ALOGE("Error in video VIDIOC_S_CROP (%d, %d, %d, %d)",
232 crop.c.left, crop.c.top, crop.c.width, crop.c.height);
233 return -1;
234 }
235
236 /*
237 * input buffer type
238 */
239 req.count = 1;
240 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
241 req.memory = V4L2_MEMORY_USERPTR;
242
243 if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
244 ALOGE("Error in VIDIOC_REQBUFS");
245 return -1;
246 }
247
248 return 0;
249}
250
251int fimc_v4l2_set_dst(int fd,
252 s5p_fimc_img_info *dst,
253 int rotation,
254 int flag_h_flip,
255 int flag_v_flip,
256 unsigned int addr)
257{
258 struct v4l2_format sFormat;
259 struct v4l2_control vc;
260 struct v4l2_framebuffer fbuf;
261
262 /*
263 * set rotation configuration
264 */
265 vc.id = V4L2_CID_HFLIP;
266 vc.value = flag_h_flip;
267 if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
268 ALOGE("Error in video VIDIOC_S_CTRL - flag_h_flip (%d)", flag_h_flip);
269 return -1;
270 }
271
272 vc.id = V4L2_CID_VFLIP;
273 vc.value = flag_v_flip;
274 if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
275 ALOGE("Error in video VIDIOC_S_CTRL - flag_v_flip (%d)", flag_v_flip);
276 return -1;
277 }
278
279 vc.id = V4L2_CID_ROTATION;
280 vc.value = rotation;
281 if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
282 ALOGE("Error in video VIDIOC_S_CTRL - rotation (%d)", rotation);
283 return -1;
284 }
285
286 /*
287 * set size, format & address for destination image (DMA-OUTPUT)
288 */
289 if (ioctl (fd, VIDIOC_G_FBUF, &fbuf) < 0) {
290 ALOGE("Error in video VIDIOC_G_FBUF");
291 return -1;
292 }
293
294 fbuf.base = (void *)addr;
295 fbuf.fmt.width = dst->full_width;
296 fbuf.fmt.height = dst->full_height;
297 fbuf.fmt.pixelformat = dst->color_space;
298 if (ioctl (fd, VIDIOC_S_FBUF, &fbuf) < 0) {
299 ALOGE("Error in video VIDIOC_S_FBUF 0x%x %d %d %d",
300 (void *)addr, dst->full_width, dst->full_height,
301 dst->color_space);
302 return -1;
303 }
304
305 /*
306 * set destination window
307 */
308 sFormat.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
309 sFormat.fmt.win.w.left = dst->start_x;
310 sFormat.fmt.win.w.top = dst->start_y;
311 sFormat.fmt.win.w.width = dst->width;
312 sFormat.fmt.win.w.height = dst->height;
313 if (ioctl(fd, VIDIOC_S_FMT, &sFormat) < 0) {
314 ALOGE("Error in video VIDIOC_S_FMT %d %d %d %d",
315 dst->start_x, dst->start_y, dst->width, dst->height);
316 return -1;
317 }
318
319 return 0;
320}
321
322int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type)
323{
324 if (ioctl (fd, VIDIOC_STREAMON, &type) < 0) {
325 ALOGE("Error in VIDIOC_STREAMON");
326 return -1;
327 }
328
329 return 0;
330}
331
332int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf)
333{
334 struct v4l2_buffer buf;
335
336 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
337 buf.memory = V4L2_MEMORY_USERPTR;
338 buf.m.userptr = (unsigned long)fimc_buf;
339 buf.length = 0;
340 buf.index = 0;
341
342 if (ioctl (fd, VIDIOC_QBUF, &buf) < 0) {
343 ALOGE("Error in VIDIOC_QBUF");
344 return -1;
345 }
346
347 return 0;
348}
349
350int fimc_v4l2_dequeue(int fd)
351{
352 struct v4l2_buffer buf;
353
354 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
355 buf.memory = V4L2_MEMORY_USERPTR;
356
357 if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0) {
358 ALOGE("Error in VIDIOC_DQBUF");
359 return -1;
360 }
361
362 return buf.index;
363}
364
365int fimc_v4l2_stream_off(int fd)
366{
367 enum v4l2_buf_type type;
368 type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
369
370 if (ioctl (fd, VIDIOC_STREAMOFF, &type) < 0) {
371 ALOGE("Error in VIDIOC_STREAMOFF");
372 return -1;
373 }
374
375 return 0;
376}
377
378int fimc_v4l2_clr_buf(int fd)
379{
380 struct v4l2_requestbuffers req;
381
382 req.count = 0;
383 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
384 req.memory = V4L2_MEMORY_USERPTR;
385
386 if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
387 ALOGE("Error in VIDIOC_REQBUFS");
388 }
389
390 return 0;
391}
392
393int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_buf)
394{
395 int ret =0;
396
397 if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT) < 0) {
398 ALOGE("Fail : v4l2_stream_on()");
399 return -1;
400 }
401
402 if (fimc_v4l2_queue(fd, fimc_buf) < 0) {
403 ALOGE("Fail : v4l2_queue()");
404 ret = -1;
405 goto stream_off;
406 }
407
408 if (fimc_v4l2_dequeue(fd) < 0) {
409 ALOGE("Fail : v4l2_dequeue()");
410 ret = -1;
411 goto stream_off;
412 }
413
414stream_off:
415 if (fimc_v4l2_stream_off(fd) < 0) {
416 ALOGE("Fail : v4l2_stream_off()");
417 return -1;
418 }
419
420 if (fimc_v4l2_clr_buf(fd) < 0) {
421 ALOGE("Fail : v4l2_clr_buf()");
422 return -1;
423 }
424
425 return ret;
426}
427
428static int get_src_phys_addr(struct hwc_context_t *ctx,
429 sec_img *src_img,
430 unsigned int *phyAddr)
431{
432 s5p_fimc_t *fimc = &ctx->fimc;
433
434 if(src_img->mem_type == HWC_PHYS_MEM_TYPE) {
435 switch(src_img->format) {
436 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
437 fimc->params.src.buf_addr_phy_rgb_y = phyAddr[0];
438 fimc->params.src.buf_addr_phy_cb = phyAddr[1];
439 break;
440 default:
441 ALOGE("%s format error (format=0x%x)", __func__,
442 src_img->format);
443 return -1;
444 }
445 } else {
446 ALOGE("%s mem_type error (mem_type=%d)", __func__, src_img->mem_type);
447 return -1;
448 }
449
450 return 0;
451}
452
453static int get_dst_phys_addr(struct hwc_context_t *ctx,
454 sec_img *dst_img)
455{
456 unsigned int dst_phys_addr = 0;
457
458 if (HWC_PHYS_MEM_TYPE == dst_img->mem_type && 0 != dst_img->base)
459 dst_phys_addr = dst_img->base;
460 else {
461 ALOGE("%s::get_dst_phys_addr fail ", __func__);
462 dst_phys_addr = 0;
463 }
464 return dst_phys_addr;
465}
466
467static inline int rotateValueHAL2PP(unsigned char transform,
468 int *flag_h_flip,
469 int *flag_v_flip)
470{
471 int rotate_result = 0;
472 int rotate_flag = transform & 0x7;
473
474 switch (rotate_flag) {
475 case HAL_TRANSFORM_ROT_90:
476 rotate_result = 90;
477 break;
478 case HAL_TRANSFORM_ROT_180:
479 rotate_result = 180;
480 break;
481 case HAL_TRANSFORM_ROT_270:
482 rotate_result = 270;
483 break;
484 }
485
486 switch (rotate_flag) {
487 case HAL_TRANSFORM_FLIP_H:
488 *flag_h_flip = 1;
489 *flag_v_flip = 0;
490 break;
491 case HAL_TRANSFORM_FLIP_V:
492 *flag_h_flip = 0;
493 *flag_v_flip = 1;
494 break;
495 default:
496 *flag_h_flip = 0;
497 *flag_v_flip = 0;
498 break;
499 }
500
501 return rotate_result;
502}
503
504static inline int multipleOfN(int number, int N)
505{
506 int result = number;
507 switch (N) {
508 case 1:
509 case 2:
510 case 4:
511 case 8:
512 case 16:
513 case 32:
514 case 64:
515 case 128:
516 case 256:
517 result = (number - (number & (N-1)));
518 break;
519 default:
520 result = number - (number % N);
521 break;
522 }
523 return result;
524}
525
526static inline int widthOfPP(unsigned int ver,
527 int pp_color_format,
528 int number)
529{
530 if (0x50 == ver) {
531 switch(pp_color_format) {
532 /* 422 1/2/3 plane */
533 case V4L2_PIX_FMT_YUYV:
534 case V4L2_PIX_FMT_UYVY:
535 case V4L2_PIX_FMT_NV61:
536 case V4L2_PIX_FMT_NV16:
537 case V4L2_PIX_FMT_YUV422P:
538
539 /* 420 2/3 plane */
540 case V4L2_PIX_FMT_NV21:
541 case V4L2_PIX_FMT_NV12:
542 case V4L2_PIX_FMT_NV12T:
543 case V4L2_PIX_FMT_YUV420:
544 return multipleOfN(number, 2);
545
546 default :
547 return number;
548 }
549 } else {
550 switch(pp_color_format) {
551 case V4L2_PIX_FMT_RGB565:
552 return multipleOfN(number, 8);
553
554 case V4L2_PIX_FMT_RGB32:
555 return multipleOfN(number, 4);
556
557 case V4L2_PIX_FMT_YUYV:
558 case V4L2_PIX_FMT_UYVY:
559 return multipleOfN(number, 4);
560
561 case V4L2_PIX_FMT_NV61:
562 case V4L2_PIX_FMT_NV16:
563 return multipleOfN(number, 8);
564
565 case V4L2_PIX_FMT_YUV422P:
566 return multipleOfN(number, 16);
567
568 case V4L2_PIX_FMT_NV21:
569 case V4L2_PIX_FMT_NV12:
570 case V4L2_PIX_FMT_NV12T:
571 return multipleOfN(number, 8);
572
573 case V4L2_PIX_FMT_YUV420:
574 return multipleOfN(number, 16);
575
576 default :
577 return number;
578 }
579 }
580 return number;
581}
582
583static inline int heightOfPP(int pp_color_format,
584 int number)
585{
586 switch(pp_color_format) {
587 case V4L2_PIX_FMT_NV21:
588 case V4L2_PIX_FMT_NV12:
589 case V4L2_PIX_FMT_NV12T:
590 case V4L2_PIX_FMT_YUV420:
591 return multipleOfN(number, 2);
592
593 default :
594 return number;
595 }
596 return number;
597}
598
599static int runcFimcCore(struct hwc_context_t *ctx,
600 sec_img *src_img,
601 sec_rect *src_rect,
602 uint32_t src_color_space,
603 unsigned int dst_phys_addr,
604 sec_img *dst_img,
605 sec_rect *dst_rect,
606 uint32_t dst_color_space,
607 int transform)
608{
609 s5p_fimc_t * fimc = &ctx->fimc;
610 s5p_fimc_params_t * params = &(fimc->params);
611
612 unsigned int frame_size = 0;
613 struct fimc_buf fimc_src_buf;
614
615 int src_bpp, src_planes;
616 int flag_h_flip = 0;
617 int flag_v_flip = 0;
618 int rotate_value = rotateValueHAL2PP(transform, &flag_h_flip, &flag_v_flip);
619
620 /* set post processor configuration */
621 params->src.full_width = src_img->w;
622 params->src.full_height = src_img->h;
623 params->src.start_x = src_rect->x;
624 params->src.start_y = src_rect->y;
625 params->src.width = widthOfPP(fimc->hw_ver, src_color_space, src_rect->w);
626 params->src.height = heightOfPP(src_color_space, src_rect->h);
627 params->src.color_space = src_color_space;
628
629
630 /* check minimum */
631 if (src_rect->w < 16 || src_rect->h < 8) {
632 ALOGE("%s src size is not supported by fimc : f_w=%d f_h=%d x=%d y=%d \
633 w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__,
634 params->src.full_width, params->src.full_height,
635 params->src.start_x, params->src.start_y, params->src.width,
636 params->src.height, src_rect->w, src_rect->h,
637 params->src.color_space);
638 return -1;
639 }
640
641switch (rotate_value) {
642 case 0:
643 params->dst.full_width = dst_img->w;
644 params->dst.full_height = dst_img->h;
645
646 params->dst.start_x = dst_rect->x;
647 params->dst.start_y = dst_rect->y;
648
649 params->dst.width =
650 widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
651 params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
652 break;
653 case 90:
654 params->dst.full_width = dst_img->h;
655 params->dst.full_height = dst_img->w;
656
657 params->dst.start_x = dst_rect->y;
658 params->dst.start_y = dst_img->w - (dst_rect->x + dst_rect->w);
659
660 params->dst.width =
661 widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
662 params->dst.height =
663 widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
664
665 if (0x50 > fimc->hw_ver)
666 params->dst.start_y += (dst_rect->w - params->dst.height);
667 break;
668 case 180:
669 params->dst.full_width = dst_img->w;
670 params->dst.full_height = dst_img->h;
671
672 params->dst.start_x = dst_img->w - (dst_rect->x + dst_rect->w);
673 params->dst.start_y = dst_img->h - (dst_rect->y + dst_rect->h);
674
675 params->dst.width =
676 widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
677 params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
678 break;
679 case 270:
680 params->dst.full_width = dst_img->h;
681 params->dst.full_height = dst_img->w;
682
683 params->dst.start_x = dst_img->h - (dst_rect->y + dst_rect->h);
684 params->dst.start_y = dst_rect->x;
685
686 params->dst.width =
687 widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
688 params->dst.height =
689 widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
690
691 if (0x50 > fimc->hw_ver)
692 params->dst.start_y += (dst_rect->w - params->dst.height);
693 break;
694 }
695
696
697 params->dst.color_space = dst_color_space;
698
699 /* check minimum */
700 if (dst_rect->w < 8 || dst_rect->h < 4) {
701 ALOGE("%s dst size is not supported by fimc : \
702 f_w=%d f_h=%d x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x",
703 __func__, params->dst.full_width, params->dst.full_height,
704 params->dst.start_x, params->dst.start_y, params->dst.width,
705 params->dst.height, dst_rect->w, dst_rect->h,
706 params->dst.color_space);
707 return -1;
708 }
709
710 /* check scaling limit
711 * the scaling limie must not be more than MAX_RESIZING_RATIO_LIMIT
712 */
713 if (((src_rect->w > dst_rect->w) &&
714 ((src_rect->w / dst_rect->w) > MAX_RESIZING_RATIO_LIMIT)) ||
715 ((dst_rect->w > src_rect->w) &&
716 ((dst_rect->w / src_rect->w) > MAX_RESIZING_RATIO_LIMIT))) {
717 ALOGE("%s over scaling limit : src.w=%d dst.w=%d (limit=%d)",
718 __func__, src_rect->w, dst_rect->w, MAX_RESIZING_RATIO_LIMIT);
719 return -1;
720 }
721
722
723 /* set configuration related to destination (DMA-OUT)
724 * - set input format & size
725 * - crop input size
726 * - set input buffer
727 * - set buffer type (V4L2_MEMORY_USERPTR)
728 */
729 if (fimc_v4l2_set_dst(fimc->dev_fd,
730 &params->dst,
731 rotate_value,
732 flag_h_flip,
733 flag_v_flip,
734 dst_phys_addr) < 0) {
735 return -1;
736 }
737
738 /* set configuration related to source (DMA-INPUT)
739 * - set input format & size
740 * - crop input size
741 * - set input buffer
742 * - set buffer type (V4L2_MEMORY_USERPTR)
743 */
744 if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, &params->src) < 0)
745 return -1;
746
747 /* set input dma address (Y/RGB, Cb, Cr) */
748 switch (src_img->format) {
749 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
750 /* for video display zero copy case */
751 fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
752 fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
753 break;
754
755 default:
756 /* set source image */
757 fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
758 break;
759 }
760
761 if (fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf) < 0) {
762 fimc_v4l2_clr_buf(fimc->dev_fd);
763 return -1;
764 }
765
766 return 0;
767}
768
769int createFimc(s5p_fimc_t *fimc)
770{
771 struct v4l2_capability cap;
772 struct v4l2_format fmt;
773 struct v4l2_control vc;
774
775 #define PP_DEVICE_DEV_NAME "/dev/video1"
776
777 /* open device file */
778 if(fimc->dev_fd < 0) {
779 fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR);
780
781 if (fimc->dev_fd < 0) {
782 ALOGE("%s::Post processor open error (%d)", __func__, errno);
783 goto err;
784 }
785 }
786
787 /* check capability */
788 if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) {
789 ALOGE("VIDIOC_QUERYCAP failed");
790 goto err;
791 }
792
793 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
794 ALOGE("%d has no streaming support", fimc->dev_fd);
795 goto err;
796 }
797
798 if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
799 ALOGE("%d is no video output", fimc->dev_fd);
800 goto err;
801 }
802
803 /*
804 * malloc fimc_outinfo structure
805 */
806 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
807 if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) {
808 ALOGE("%s::Error in video VIDIOC_G_FMT", __func__);
809 goto err;
810 }
811
812 vc.id = V4L2_CID_FIMC_VERSION;
813 vc.value = 0;
814
815 if (ioctl(fimc->dev_fd, VIDIOC_G_CTRL, &vc) < 0) {
816 ALOGE("%s::Error in video VIDIOC_G_CTRL", __func__);
817 goto err;
818 }
819 fimc->hw_ver = vc.value;
820
821 return 0;
822
823err:
824 if (0 <= fimc->dev_fd)
825 close(fimc->dev_fd);
826 fimc->dev_fd = -1;
827
828 return -1;
829}
830
831int destroyFimc(s5p_fimc_t *fimc)
832{
833 if (fimc->out_buf.virt_addr != NULL) {
834 fimc->out_buf.virt_addr = NULL;
835 fimc->out_buf.length = 0;
836 }
837
838 /* close */
839 if (0 <= fimc->dev_fd)
840 close(fimc->dev_fd);
841 fimc->dev_fd = -1;
842
843 return 0;
844}
845
846int runFimc(struct hwc_context_t *ctx,
847 struct sec_img *src_img,
848 struct sec_rect *src_rect,
849 struct sec_img *dst_img,
850 struct sec_rect *dst_rect,
851 unsigned int *phyAddr,
852 uint32_t transform)
853{
854 s5p_fimc_t *fimc = &ctx->fimc;
855 unsigned int dst_phys_addr = 0;
856 int32_t src_color_space;
857 int32_t dst_color_space;
858
859 /* 1 : source address and size */
860
861 if(0 > get_src_phys_addr(ctx, src_img, phyAddr))
862 return -1;
863
864 /* 2 : destination address and size */
865 if(0 == (dst_phys_addr = get_dst_phys_addr(ctx, dst_img)))
866 return -2;
867
868 /* check whether fimc supports the src format */
869 if (0 > (src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format)))
870 return -3;
871
872 if (0 > (dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format)))
873 return -4;
874
875 if(runcFimcCore(ctx, src_img, src_rect, (uint32_t)src_color_space,
876 dst_phys_addr, dst_img, dst_rect, (uint32_t)dst_color_space, transform) < 0)
877 return -5;
878
879 return 0;
880}