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 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 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 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 113 int 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 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 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 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 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 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 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 169 int 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 195 int 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 251 int 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 322 int 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 332 int 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 350 int 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 365 int 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 378 int 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 393 int 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 414 stream_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 428 static 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 453 static 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 467 static 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 504 static 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 526 static 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 583 static 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 599 static 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 641 switch (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 ¶ms->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, ¶ms->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 769 int 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 823 err: 824 if (0 <= fimc->dev_fd) 825 close(fimc->dev_fd); 826 fimc->dev_fd = -1; 827 828 return -1; 829 } 830 831 int 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 846 int 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 } 881