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