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