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 /* Trade temporary object for one in the pool */ 565 if (gsc_handle->cur_obj_mutex) { 566 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 567 if (gsc_handle->destroy_cur_obj_mutex) 568 exynos_mutex_destroy(gsc_handle->cur_obj_mutex); 569 } 570 571 gsc_handle->destroy_cur_obj_mutex = false; 572 gsc_handle->cur_obj_mutex = gsc_handle->obj_mutex[i]; 573 574 flag_find_new_gsc = true; 575 break; 576 } 577 } 578 579 // waiting for another process doesn't use gscaler. 580 // we need to make decision how to do. 581 if (flag_find_new_gsc == false) { 582 usleep(GSC_WAITING_TIME_FOR_TRYLOCK); 583 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK; 584 ALOGV("%s::waiting for anthere process doens't use gscaler", __func__); 585 } 586 587 } while( flag_find_new_gsc == false 588 && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK); 589 590 if (flag_find_new_gsc == false) 591 ALOGE("%s::we don't have no available gsc.. fail", __func__); 592 593 Exynos_gsc_Out(); 594 595 return flag_find_new_gsc; 596 } 597 598 static bool m_exynos_gsc_set_format( 599 int fd, 600 struct gsc_info *info) 601 { 602 Exynos_gsc_In(); 603 604 struct v4l2_requestbuffers req_buf; 605 int plane_count; 606 607 plane_count = m_gsc_get_plane_count(info->v4l2_colorformat); 608 if (plane_count < 0) { 609 ALOGE("%s::not supported v4l2_colorformat", __func__); 610 return false; 611 } 612 613 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) { 614 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__); 615 return false; 616 } 617 618 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) { 619 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__); 620 return false; 621 } 622 623 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) { 624 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__); 625 return false; 626 } 627 628 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CSC_RANGE, info->csc_range) < 0) { 629 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__); 630 return false; 631 } 632 info->format.type = info->buf_type; 633 info->format.fmt.pix_mp.width = info->width; 634 info->format.fmt.pix_mp.height = info->height; 635 info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat; 636 info->format.fmt.pix_mp.field = V4L2_FIELD_ANY; 637 info->format.fmt.pix_mp.num_planes = plane_count; 638 639 if (exynos_v4l2_s_fmt(fd, &info->format) < 0) { 640 ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__); 641 return false; 642 } 643 644 info->crop.type = info->buf_type; 645 info->crop.c.left = info->crop_left; 646 info->crop.c.top = info->crop_top; 647 info->crop.c.width = info->crop_width; 648 info->crop.c.height = info->crop_height; 649 650 if (exynos_v4l2_s_crop(fd, &info->crop) < 0) { 651 ALOGE("%s::exynos_v4l2_s_crop() fail", __func__); 652 return false; 653 } 654 655 if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) { 656 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__); 657 return false; 658 } 659 660 req_buf.count = 1; 661 req_buf.type = info->buf_type; 662 req_buf.memory = V4L2_MEMORY_DMABUF; 663 if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) { 664 ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__); 665 return false; 666 } 667 668 Exynos_gsc_Out(); 669 670 return true; 671 } 672 673 static bool m_exynos_gsc_set_addr( 674 int fd, 675 struct gsc_info *info) 676 { 677 unsigned int i; 678 unsigned int plane_size[NUM_OF_GSC_PLANES]; 679 680 m_gsc_get_plane_size(plane_size, 681 info->width, 682 info->height, 683 info->v4l2_colorformat); 684 685 info->buffer.index = 0; 686 info->buffer.flags = V4L2_BUF_FLAG_USE_SYNC; 687 info->buffer.type = info->buf_type; 688 info->buffer.memory = V4L2_MEMORY_DMABUF; 689 info->buffer.m.planes = info->planes; 690 info->buffer.length = info->format.fmt.pix_mp.num_planes; 691 info->buffer.reserved = info->acquireFenceFd; 692 693 for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) { 694 info->buffer.m.planes[i].m.fd = (int)info->addr[i]; 695 info->buffer.m.planes[i].length = plane_size[i]; 696 info->buffer.m.planes[i].bytesused = 0; 697 } 698 699 if (exynos_v4l2_qbuf(fd, &info->buffer) < 0) { 700 ALOGE("%s::exynos_v4l2_qbuf() fail", __func__); 701 return false; 702 } 703 info->buffer_queued = true; 704 705 info->releaseFenceFd = info->buffer.reserved; 706 707 return true; 708 } 709 710 void *exynos_gsc_create( 711 void) 712 { 713 int i = 0; 714 int op_id = 0; 715 char mutex_name[32]; 716 717 Exynos_gsc_In(); 718 719 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE)); 720 if (gsc_handle == NULL) { 721 ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__); 722 goto err; 723 } 724 725 gsc_handle->gsc_fd = 0; 726 memset(&gsc_handle->src, 0, sizeof(struct gsc_info)); 727 memset(&gsc_handle->dst, 0, sizeof(struct gsc_info)); 728 729 gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 730 gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 731 732 gsc_handle->op_mutex = NULL; 733 for (i = 0; i < NUM_OF_GSC_HW; i++) 734 gsc_handle->obj_mutex[i] = NULL; 735 736 gsc_handle->cur_obj_mutex = NULL; 737 gsc_handle->destroy_cur_obj_mutex = false; 738 gsc_handle->flag_local_path = false; 739 gsc_handle->flag_exclusive_open = false; 740 741 srand(time(NULL)); 742 op_id = rand() % 1000000; // just make random id 743 sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id); 744 gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name); 745 if (gsc_handle->op_mutex == NULL) { 746 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 747 goto err; 748 } 749 750 exynos_mutex_lock(gsc_handle->op_mutex); 751 752 // check if it is available 753 for (i = 0; i < NUM_OF_GSC_HW; i++) { 754 sprintf(mutex_name, "%sObject%d", LOG_TAG, i); 755 756 gsc_handle->obj_mutex[i] = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name); 757 if (gsc_handle->obj_mutex[i] == NULL) { 758 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 759 goto err; 760 } 761 } 762 763 if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) { 764 ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__); 765 goto err; 766 } 767 768 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 769 exynos_mutex_unlock(gsc_handle->op_mutex); 770 771 return (void *)gsc_handle; 772 773 err: 774 if (gsc_handle) { 775 m_exynos_gsc_destroy(gsc_handle); 776 777 if (gsc_handle->cur_obj_mutex) 778 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 779 780 for (i = 0; i < NUM_OF_GSC_HW; i++) { 781 if ((gsc_handle->obj_mutex[i] != NULL) && 782 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) { 783 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false) 784 ALOGE("%s::exynos_mutex_destroy() fail", __func__); 785 } 786 } 787 788 if (gsc_handle->op_mutex) 789 exynos_mutex_unlock(gsc_handle->op_mutex); 790 791 if (exynos_mutex_destroy(gsc_handle->op_mutex) == false) 792 ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__); 793 794 free(gsc_handle); 795 } 796 797 Exynos_gsc_Out(); 798 799 return NULL; 800 } 801 802 void *exynos_gsc_reserve(int dev_num) 803 { 804 char mutex_name[32]; 805 unsigned int total_sleep_time = 0; 806 bool gsc_flag = false; 807 808 if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) { 809 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num); 810 return NULL; 811 } 812 813 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE)); 814 if (gsc_handle == NULL) { 815 ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__); 816 goto err; 817 } 818 819 gsc_handle->gsc_fd = -1; 820 gsc_handle->op_mutex = NULL; 821 gsc_handle->cur_obj_mutex = NULL; 822 gsc_handle->destroy_cur_obj_mutex = true; 823 824 sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num); 825 gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name); 826 if (gsc_handle->cur_obj_mutex == NULL) { 827 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 828 goto err; 829 } 830 831 do { 832 if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) { 833 gsc_flag = true; 834 break; 835 } 836 usleep(GSC_WAITING_TIME_FOR_TRYLOCK); 837 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK; 838 ALOGV("%s::waiting for another process to release the requested gscaler", __func__); 839 } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK); 840 841 if (gsc_flag == true) 842 return (void *)gsc_handle; 843 844 err: 845 if (gsc_handle) { 846 free(gsc_handle); 847 } 848 849 return NULL; 850 } 851 852 void exynos_gsc_release(void *handle) 853 { 854 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle; 855 856 if (handle == NULL) { 857 ALOGE("%s::handle == NULL() fail", __func__); 858 return; 859 } 860 861 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 862 exynos_mutex_destroy(gsc_handle->cur_obj_mutex); 863 free(gsc_handle); 864 return; 865 } 866 867 void *exynos_gsc_create_exclusive( 868 int dev_num, 869 int mode, 870 int out_mode, 871 int allow_drm) 872 { 873 int i = 0; 874 int op_id = 0; 875 char mutex_name[32]; 876 unsigned int total_sleep_time = 0; 877 bool gsc_flag = false; 878 int ret = 0; 879 880 Exynos_gsc_In(); 881 882 if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) { 883 ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num); 884 return NULL; 885 } 886 887 if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) { 888 ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode); 889 return NULL; 890 } 891 892 /* currently only gscalers 0 and 3 are DRM capable */ 893 if (allow_drm && (dev_num != 0 && dev_num != 3)) { 894 ALOGE("%s::fail:: gscaler %d does not support drm\n", __func__, 895 dev_num); 896 return NULL; 897 } 898 899 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE)); 900 if (gsc_handle == NULL) { 901 ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__); 902 goto err; 903 } 904 memset(gsc_handle, 0, sizeof(struct GSC_HANDLE)); 905 gsc_handle->gsc_fd = -1; 906 gsc_handle->gsc_mode = mode; 907 gsc_handle->gsc_id = dev_num; 908 gsc_handle->allow_drm = allow_drm; 909 910 gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 911 gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 912 913 gsc_handle->op_mutex = NULL; 914 for (i = 0; i < NUM_OF_GSC_HW; i++) 915 gsc_handle->obj_mutex[i] = NULL; 916 917 gsc_handle->cur_obj_mutex = NULL; 918 gsc_handle->destroy_cur_obj_mutex = false; 919 gsc_handle->flag_local_path = false; 920 gsc_handle->flag_exclusive_open = true; 921 922 srand(time(NULL)); 923 op_id = rand() % 1000000; // just make random id 924 sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id); 925 gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name); 926 if (gsc_handle->op_mutex == NULL) { 927 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 928 goto err; 929 } 930 931 exynos_mutex_lock(gsc_handle->op_mutex); 932 933 sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num); 934 gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name); 935 if (gsc_handle->cur_obj_mutex == NULL) { 936 ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name); 937 goto err; 938 } 939 gsc_handle->destroy_cur_obj_mutex = true; 940 941 do { 942 if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) { 943 if (mode == GSC_M2M_MODE) { 944 gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(dev_num); 945 if (gsc_handle->gsc_fd < 0) { 946 ALOGE("%s::m_exynos_gsc_m2m_create(%i) fail", __func__, dev_num); 947 goto err; 948 } 949 } else if (mode == GSC_OUTPUT_MODE) { 950 ret = m_exynos_gsc_output_create(gsc_handle, dev_num, out_mode); 951 if (ret < 0) { 952 ALOGE("%s::m_exynos_gsc_output_create(%i) fail", __func__, dev_num); 953 goto err; 954 } 955 } 956 /*else 957 gsc_handle->gsc_fd = m_exynos_gsc_capture_create(dev_num);*/ 958 959 gsc_flag = true; 960 break; 961 } 962 usleep(GSC_WAITING_TIME_FOR_TRYLOCK); 963 total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK; 964 ALOGV("%s::waiting for anthere process doens't use gscaler", __func__); 965 } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK); 966 967 exynos_mutex_unlock(gsc_handle->op_mutex); 968 if (gsc_flag == true) { 969 Exynos_gsc_Out(); 970 return (void *)gsc_handle; 971 } 972 973 err: 974 if (gsc_handle) { 975 m_exynos_gsc_destroy(gsc_handle); 976 977 if (gsc_handle->cur_obj_mutex) { 978 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 979 if (gsc_handle->destroy_cur_obj_mutex) 980 exynos_mutex_destroy(gsc_handle->cur_obj_mutex); 981 } 982 983 for (i = 0; i < NUM_OF_GSC_HW; i++) { 984 if ((gsc_handle->obj_mutex[i] != NULL) && 985 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) { 986 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false) 987 ALOGE("%s::exynos_mutex_destroy() fail", __func__); 988 } 989 } 990 991 if (gsc_handle->op_mutex) 992 exynos_mutex_unlock(gsc_handle->op_mutex); 993 994 if (exynos_mutex_destroy(gsc_handle->op_mutex) == false) 995 ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__); 996 997 free(gsc_handle); 998 } 999 1000 Exynos_gsc_Out(); 1001 1002 return NULL; 1003 } 1004 1005 void exynos_gsc_destroy( 1006 void *handle) 1007 { 1008 int i = 0; 1009 struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle; 1010 1011 Exynos_gsc_In(); 1012 1013 if (handle == NULL) { 1014 ALOGE("%s::handle == NULL() fail", __func__); 1015 return; 1016 } 1017 1018 exynos_mutex_lock(gsc_handle->op_mutex); 1019 1020 if (gsc_handle->flag_exclusive_open == false) 1021 exynos_mutex_lock(gsc_handle->cur_obj_mutex); 1022 1023 if (gsc_handle->gsc_mode == GSC_OUTPUT_MODE) 1024 m_exynos_gsc_out_destroy(gsc_handle); 1025 else 1026 m_exynos_gsc_destroy(gsc_handle); 1027 1028 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 1029 1030 for (i = 0; i < NUM_OF_GSC_HW; i++) { 1031 if ((gsc_handle->obj_mutex[i] != NULL) && 1032 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) { 1033 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false) 1034 ALOGE("%s::exynos_mutex_destroy(obj_mutex) fail", __func__); 1035 } 1036 } 1037 1038 if (gsc_handle->destroy_cur_obj_mutex) 1039 exynos_mutex_destroy(gsc_handle->cur_obj_mutex); 1040 1041 exynos_mutex_unlock(gsc_handle->op_mutex); 1042 1043 if (exynos_mutex_destroy(gsc_handle->op_mutex) == false) 1044 ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__); 1045 1046 if (gsc_handle) 1047 free(gsc_handle); 1048 1049 Exynos_gsc_Out(); 1050 1051 } 1052 1053 int exynos_gsc_set_src_format( 1054 void *handle, 1055 unsigned int width, 1056 unsigned int height, 1057 unsigned int crop_left, 1058 unsigned int crop_top, 1059 unsigned int crop_width, 1060 unsigned int crop_height, 1061 unsigned int v4l2_colorformat, 1062 unsigned int cacheable, 1063 unsigned int mode_drm) 1064 { 1065 Exynos_gsc_In(); 1066 1067 struct GSC_HANDLE *gsc_handle; 1068 gsc_handle = (struct GSC_HANDLE *)handle; 1069 1070 if (handle == NULL) { 1071 ALOGE("%s::handle == NULL() fail", __func__); 1072 return -1; 1073 } 1074 1075 exynos_mutex_lock(gsc_handle->op_mutex); 1076 1077 gsc_handle->src.width = width; 1078 gsc_handle->src.height = height; 1079 gsc_handle->src.crop_left = crop_left; 1080 gsc_handle->src.crop_top = crop_top; 1081 gsc_handle->src.crop_width = crop_width; 1082 gsc_handle->src.crop_height = crop_height; 1083 gsc_handle->src.v4l2_colorformat = v4l2_colorformat; 1084 gsc_handle->src.cacheable = cacheable; 1085 gsc_handle->src.mode_drm = mode_drm; 1086 gsc_handle->src.dirty = true; 1087 1088 1089 exynos_mutex_unlock(gsc_handle->op_mutex); 1090 1091 Exynos_gsc_Out(); 1092 1093 return 0; 1094 } 1095 1096 int exynos_gsc_set_dst_format( 1097 void *handle, 1098 unsigned int width, 1099 unsigned int height, 1100 unsigned int crop_left, 1101 unsigned int crop_top, 1102 unsigned int crop_width, 1103 unsigned int crop_height, 1104 unsigned int v4l2_colorformat, 1105 unsigned int cacheable, 1106 unsigned int mode_drm, 1107 unsigned int narrowRgb) 1108 { 1109 Exynos_gsc_In(); 1110 1111 struct GSC_HANDLE *gsc_handle; 1112 gsc_handle = (struct GSC_HANDLE *)handle; 1113 1114 if (handle == NULL) { 1115 ALOGE("%s::handle == NULL() fail", __func__); 1116 return -1; 1117 } 1118 1119 exynos_mutex_lock(gsc_handle->op_mutex); 1120 1121 gsc_handle->dst.width = width; 1122 gsc_handle->dst.height = height; 1123 gsc_handle->dst.crop_left = crop_left; 1124 gsc_handle->dst.crop_top = crop_top; 1125 gsc_handle->dst.crop_width = crop_width; 1126 gsc_handle->dst.crop_height = crop_height; 1127 gsc_handle->dst.v4l2_colorformat = v4l2_colorformat; 1128 gsc_handle->dst.cacheable = cacheable; 1129 gsc_handle->dst.mode_drm = mode_drm; 1130 gsc_handle->dst.dirty = true; 1131 gsc_handle->dst.csc_range = !narrowRgb; 1132 1133 exynos_mutex_unlock(gsc_handle->op_mutex); 1134 1135 Exynos_gsc_Out(); 1136 return 0; 1137 } 1138 1139 int exynos_gsc_set_rotation( 1140 void *handle, 1141 int rotation, 1142 int flip_horizontal, 1143 int flip_vertical) 1144 { 1145 int ret = -1; 1146 struct GSC_HANDLE *gsc_handle; 1147 gsc_handle = (struct GSC_HANDLE *)handle; 1148 1149 if (handle == NULL) { 1150 ALOGE("%s::handle == NULL() fail", __func__); 1151 return ret; 1152 } 1153 1154 exynos_mutex_lock(gsc_handle->op_mutex); 1155 1156 int new_rotation = rotation % 360; 1157 1158 if (new_rotation % 90 != 0) { 1159 ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__, rotation); 1160 goto done; 1161 } 1162 1163 if(new_rotation < 0) 1164 new_rotation = -new_rotation; 1165 1166 gsc_handle->dst.rotation = new_rotation; 1167 gsc_handle->dst.flip_horizontal = flip_horizontal; 1168 gsc_handle->dst.flip_vertical = flip_vertical; 1169 1170 ret = 0; 1171 done: 1172 exynos_mutex_unlock(gsc_handle->op_mutex); 1173 1174 return ret; 1175 } 1176 1177 int exynos_gsc_set_src_addr( 1178 void *handle, 1179 void *addr[3], 1180 int acquireFenceFd) 1181 { 1182 struct GSC_HANDLE *gsc_handle; 1183 gsc_handle = (struct GSC_HANDLE *)handle; 1184 1185 Exynos_gsc_In(); 1186 1187 if (handle == NULL) { 1188 ALOGE("%s::handle == NULL() fail", __func__); 1189 return -1; 1190 } 1191 1192 exynos_mutex_lock(gsc_handle->op_mutex); 1193 1194 gsc_handle->src.addr[0] = addr[0]; 1195 gsc_handle->src.addr[1] = addr[1]; 1196 gsc_handle->src.addr[2] = addr[2]; 1197 gsc_handle->src.acquireFenceFd = acquireFenceFd; 1198 1199 exynos_mutex_unlock(gsc_handle->op_mutex); 1200 1201 Exynos_gsc_Out(); 1202 1203 return 0; 1204 } 1205 1206 int exynos_gsc_set_dst_addr( 1207 void *handle, 1208 void *addr[3], 1209 int acquireFenceFd) 1210 { 1211 struct GSC_HANDLE *gsc_handle; 1212 gsc_handle = (struct GSC_HANDLE *)handle; 1213 int ret = 0; 1214 1215 Exynos_gsc_In(); 1216 1217 if (handle == NULL) { 1218 ALOGE("%s::handle == NULL() fail", __func__); 1219 return -1; 1220 } 1221 1222 exynos_mutex_lock(gsc_handle->op_mutex); 1223 1224 gsc_handle->dst.addr[0] = addr[0]; 1225 gsc_handle->dst.addr[1] = addr[1]; 1226 gsc_handle->dst.addr[2] = addr[2]; 1227 gsc_handle->dst.acquireFenceFd = acquireFenceFd; 1228 1229 1230 exynos_mutex_unlock(gsc_handle->op_mutex); 1231 1232 Exynos_gsc_Out(); 1233 1234 return ret; 1235 } 1236 1237 static void rotateValueHAL2GSC(unsigned int transform, 1238 unsigned int *rotate, 1239 unsigned int *hflip, 1240 unsigned int *vflip) 1241 { 1242 int rotate_flag = transform & 0x7; 1243 *rotate = 0; 1244 *hflip = 0; 1245 *vflip = 0; 1246 1247 switch (rotate_flag) { 1248 case HAL_TRANSFORM_ROT_90: 1249 *rotate = 90; 1250 break; 1251 case HAL_TRANSFORM_ROT_180: 1252 *rotate = 180; 1253 break; 1254 case HAL_TRANSFORM_ROT_270: 1255 *rotate = 270; 1256 break; 1257 case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90: 1258 *rotate = 90; 1259 *vflip = 1; /* set vflip to compensate the rot & flip order. */ 1260 break; 1261 case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90: 1262 *rotate = 90; 1263 *hflip = 1; /* set hflip to compensate the rot & flip order. */ 1264 break; 1265 case HAL_TRANSFORM_FLIP_H: 1266 *hflip = 1; 1267 break; 1268 case HAL_TRANSFORM_FLIP_V: 1269 *vflip = 1; 1270 break; 1271 default: 1272 break; 1273 } 1274 } 1275 1276 static bool get_plane_size(int V4L2_PIX, 1277 unsigned int * size, 1278 unsigned int frame_size, 1279 int src_planes) 1280 { 1281 unsigned int frame_ratio = 1; 1282 int src_bpp = get_yuv_bpp(V4L2_PIX); 1283 1284 src_planes = (src_planes == -1) ? 1 : src_planes; 1285 frame_ratio = 8 * (src_planes -1) / (src_bpp - 8); 1286 1287 switch (src_planes) { 1288 case 1: 1289 switch (V4L2_PIX) { 1290 case V4L2_PIX_FMT_BGR32: 1291 case V4L2_PIX_FMT_RGB32: 1292 size[0] = frame_size << 2; 1293 break; 1294 case V4L2_PIX_FMT_RGB565X: 1295 case V4L2_PIX_FMT_NV16: 1296 case V4L2_PIX_FMT_NV61: 1297 case V4L2_PIX_FMT_YUYV: 1298 case V4L2_PIX_FMT_UYVY: 1299 case V4L2_PIX_FMT_VYUY: 1300 case V4L2_PIX_FMT_YVYU: 1301 size[0] = frame_size << 1; 1302 break; 1303 case V4L2_PIX_FMT_YUV420: 1304 case V4L2_PIX_FMT_NV12: 1305 case V4L2_PIX_FMT_NV21: 1306 case V4L2_PIX_FMT_NV21M: 1307 size[0] = (frame_size * 3) >> 1; 1308 break; 1309 default: 1310 ALOGE("%s::invalid color type", __func__); 1311 return false; 1312 break; 1313 } 1314 size[1] = 0; 1315 size[2] = 0; 1316 break; 1317 case 2: 1318 size[0] = frame_size; 1319 size[1] = frame_size / frame_ratio; 1320 size[2] = 0; 1321 break; 1322 case 3: 1323 size[0] = frame_size; 1324 size[1] = frame_size / frame_ratio; 1325 size[2] = frame_size / frame_ratio; 1326 break; 1327 default: 1328 ALOGE("%s::invalid color foarmt", __func__); 1329 return false; 1330 break; 1331 } 1332 1333 return true; 1334 } 1335 1336 int exynos_gsc_m2m_config(void *handle, 1337 exynos_gsc_img *src_img, 1338 exynos_gsc_img *dst_img) 1339 { 1340 struct GSC_HANDLE *gsc_handle; 1341 int32_t src_color_space; 1342 int32_t dst_color_space; 1343 int ret; 1344 unsigned int rotate; 1345 unsigned int hflip; 1346 unsigned int vflip; 1347 1348 Exynos_gsc_In(); 1349 1350 gsc_handle = (struct GSC_HANDLE *)handle; 1351 if (gsc_handle == NULL) { 1352 ALOGE("%s::gsc_handle == NULL() fail", __func__); 1353 return -1; 1354 } 1355 1356 if ((src_img->drmMode && !gsc_handle->allow_drm) || 1357 (src_img->drmMode != dst_img->drmMode)) { 1358 ALOGE("%s::invalid drm state request for gsc%d (s=%d d=%d)", 1359 __func__, gsc_handle->gsc_id, 1360 src_img->drmMode, dst_img->drmMode); 1361 return -1; 1362 } 1363 1364 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format); 1365 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format); 1366 rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip); 1367 exynos_gsc_set_rotation(gsc_handle, rotate, hflip, vflip); 1368 1369 ret = exynos_gsc_set_src_format(gsc_handle, src_img->fw, src_img->fh, 1370 src_img->x, src_img->y, src_img->w, src_img->h, 1371 src_color_space, src_img->cacheable, src_img->drmMode); 1372 if (ret < 0) { 1373 ALOGE("%s: fail: exynos_gsc_set_src_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]", 1374 __func__, src_img->fw, src_img->fh, src_img->x, src_img->y, src_img->w, src_img->h, 1375 src_color_space, src_img->rot); 1376 return -1; 1377 } 1378 1379 ret = exynos_gsc_set_dst_format(gsc_handle, dst_img->fw, dst_img->fh, 1380 dst_img->x, dst_img->y, dst_img->w, dst_img->h, 1381 dst_color_space, dst_img->cacheable, dst_img->drmMode, 1382 dst_img->narrowRgb); 1383 if (ret < 0) { 1384 ALOGE("%s: fail: exynos_gsc_set_dst_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]", 1385 __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y, dst_img->w, dst_img->h, 1386 src_color_space, dst_img->rot); 1387 return -1; 1388 } 1389 1390 Exynos_gsc_Out(); 1391 1392 return 0; 1393 } 1394 1395 int exynos_gsc_out_config(void *handle, 1396 exynos_gsc_img *src_img, 1397 exynos_gsc_img *dst_img) 1398 { 1399 struct GSC_HANDLE *gsc_handle; 1400 struct v4l2_format fmt; 1401 struct v4l2_crop crop; 1402 struct v4l2_requestbuffers reqbuf; 1403 struct v4l2_subdev_format sd_fmt; 1404 struct v4l2_subdev_crop sd_crop; 1405 int i; 1406 unsigned int rotate; 1407 unsigned int hflip; 1408 unsigned int vflip; 1409 unsigned int plane_size[NUM_OF_GSC_PLANES]; 1410 bool rgb; 1411 int csc_range = !dst_img->narrowRgb; 1412 1413 struct v4l2_rect dst_rect; 1414 int32_t src_color_space; 1415 int32_t dst_color_space; 1416 int32_t src_planes; 1417 1418 gsc_handle = (struct GSC_HANDLE *)handle; 1419 if (gsc_handle == NULL) { 1420 ALOGE("%s::gsc_handle == NULL() fail", __func__); 1421 return -1; 1422 } 1423 1424 Exynos_gsc_In(); 1425 1426 if (gsc_handle->src.stream_on != false) { 1427 ALOGE("Error: Src is already streamed on !!!!"); 1428 return -1; 1429 } 1430 1431 memcpy(&gsc_handle->src_img, src_img, sizeof(exynos_gsc_img)); 1432 memcpy(&gsc_handle->dst_img, dst_img, sizeof(exynos_gsc_img)); 1433 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format); 1434 dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format); 1435 src_planes = get_yuv_planes(src_color_space); 1436 src_planes = (src_planes == -1) ? 1 : src_planes; 1437 rgb = get_yuv_planes(dst_color_space) == -1; 1438 rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip); 1439 1440 if (m_exynos_gsc_check_src_size(&gsc_handle->src_img.fw, &gsc_handle->src_img.fh, 1441 &gsc_handle->src_img.x, &gsc_handle->src_img.y, 1442 &gsc_handle->src_img.w, &gsc_handle->src_img.h, 1443 src_color_space) == false) { 1444 ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__); 1445 return -1; 1446 } 1447 1448 if (m_exynos_gsc_check_dst_size(&gsc_handle->dst_img.fw, &gsc_handle->dst_img.fh, 1449 &gsc_handle->dst_img.x, &gsc_handle->dst_img.y, 1450 &gsc_handle->dst_img.w, &gsc_handle->dst_img.h, 1451 dst_color_space, 1452 rotate) == false) { 1453 ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__); 1454 return -1; 1455 } 1456 1457 /*set: src v4l2_buffer*/ 1458 gsc_handle->src.src_buf_idx = 0; 1459 gsc_handle->src.qbuf_cnt = 0; 1460 /* set format: src pad of GSC sub-dev*/ 1461 sd_fmt.pad = GSCALER_SUBDEV_PAD_SOURCE; 1462 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1463 if (gsc_handle->out_mode == GSC_OUT_FIMD) { 1464 sd_fmt.format.width = gsc_handle->dst_img.fw; 1465 sd_fmt.format.height = gsc_handle->dst_img.fh; 1466 } else { 1467 sd_fmt.format.width = gsc_handle->dst_img.w; 1468 sd_fmt.format.height = gsc_handle->dst_img.h; 1469 } 1470 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE : 1471 V4L2_MBUS_FMT_YUV8_1X24; 1472 if (exynos_subdev_s_fmt(gsc_handle->gsc_sd_entity->fd, &sd_fmt) < 0) { 1473 ALOGE("%s::GSC subdev set format failed", __func__); 1474 return -1; 1475 } 1476 1477 /* set crop: src crop of GSC sub-dev*/ 1478 sd_crop.pad = GSCALER_SUBDEV_PAD_SOURCE; 1479 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1480 if (gsc_handle->out_mode == GSC_OUT_FIMD) { 1481 sd_crop.rect.left = gsc_handle->dst_img.x; 1482 sd_crop.rect.top = gsc_handle->dst_img.y; 1483 sd_crop.rect.width = gsc_handle->dst_img.w; 1484 sd_crop.rect.height = gsc_handle->dst_img.h; 1485 } else { 1486 sd_crop.rect.left = 0; 1487 sd_crop.rect.top = 0; 1488 sd_crop.rect.width = gsc_handle->dst_img.w; 1489 sd_crop.rect.height = gsc_handle->dst_img.h; 1490 } 1491 if (exynos_subdev_s_crop(gsc_handle->gsc_sd_entity->fd, &sd_crop) < 0) { 1492 ALOGE("%s::GSC subdev set crop failed", __func__); 1493 return -1; 1494 } 1495 1496 /* sink pad is connected to GSC out */ 1497 /* set format: sink sub-dev */ 1498 if (gsc_handle->out_mode == GSC_OUT_FIMD) { 1499 sd_fmt.pad = FIMD_SUBDEV_PAD_SINK; 1500 sd_fmt.format.width = gsc_handle->dst_img.w; 1501 sd_fmt.format.height = gsc_handle->dst_img.h; 1502 } else { 1503 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SINK; 1504 sd_fmt.format.width = gsc_handle->dst_img.w + gsc_handle->dst_img.x*2; 1505 sd_fmt.format.height = gsc_handle->dst_img.h + gsc_handle->dst_img.y*2; 1506 } 1507 1508 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1509 sd_fmt.format.code = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE : 1510 V4L2_MBUS_FMT_YUV8_1X24; 1511 if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) { 1512 ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad); 1513 return -1; 1514 } 1515 1516 /* set crop: sink sub-dev */ 1517 if (gsc_handle->out_mode == GSC_OUT_FIMD) 1518 sd_crop.pad = FIMD_SUBDEV_PAD_SINK; 1519 else 1520 sd_crop.pad = MIXER_V_SUBDEV_PAD_SINK; 1521 1522 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1523 if (gsc_handle->out_mode == GSC_OUT_FIMD) { 1524 sd_crop.rect.left = gsc_handle->dst_img.x; 1525 sd_crop.rect.top = gsc_handle->dst_img.y; 1526 sd_crop.rect.width = gsc_handle->dst_img.w; 1527 sd_crop.rect.height = gsc_handle->dst_img.h; 1528 } else { 1529 sd_crop.rect.left = 0; 1530 sd_crop.rect.top = 0; 1531 sd_crop.rect.width = gsc_handle->dst_img.w; 1532 sd_crop.rect.height = gsc_handle->dst_img.h; 1533 } 1534 if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) { 1535 ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad); 1536 return -1; 1537 } 1538 1539 if (gsc_handle->out_mode != GSC_OUT_FIMD) { 1540 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE; 1541 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1542 sd_fmt.format.width = gsc_handle->dst_img.w + gsc_handle->dst_img.x*2; 1543 sd_fmt.format.height = gsc_handle->dst_img.h + gsc_handle->dst_img.y*2; 1544 sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE; 1545 if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) { 1546 ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad); 1547 return -1; 1548 } 1549 1550 sd_fmt.pad = MIXER_V_SUBDEV_PAD_SOURCE; 1551 sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1552 sd_crop.rect.left = gsc_handle->dst_img.x; 1553 sd_crop.rect.top = gsc_handle->dst_img.y; 1554 sd_crop.rect.width = gsc_handle->dst_img.w; 1555 sd_crop.rect.height = gsc_handle->dst_img.h; 1556 if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) { 1557 ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad); 1558 return -1; 1559 } 1560 } 1561 1562 /*set GSC ctrls */ 1563 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_ROTATE, rotate) < 0) { 1564 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed", __func__, rotate); 1565 return -1; 1566 } 1567 1568 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_HFLIP, hflip) < 0) { 1569 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed", __func__, hflip); 1570 return -1; 1571 } 1572 1573 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_VFLIP, vflip) < 0) { 1574 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed", __func__, vflip); 1575 return -1; 1576 } 1577 1578 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CACHEABLE, 1) < 0) { 1579 ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed", __func__); 1580 return -1; 1581 } 1582 1583 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, 1584 V4L2_CID_CONTENT_PROTECTION, gsc_handle->src_img.drmMode) < 0) { 1585 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail", __func__); 1586 return -1; 1587 } 1588 1589 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CSC_RANGE, 1590 csc_range)) { 1591 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE: %d) fail", __func__, 1592 csc_range); 1593 return -1; 1594 } 1595 1596 /* set src format :GSC video dev*/ 1597 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1598 fmt.fmt.pix_mp.width = gsc_handle->src_img.fw; 1599 fmt.fmt.pix_mp.height = gsc_handle->src_img.fh; 1600 fmt.fmt.pix_mp.pixelformat = src_color_space; 1601 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE; 1602 fmt.fmt.pix_mp.num_planes = src_planes; 1603 1604 if (exynos_v4l2_s_fmt(gsc_handle->gsc_vd_entity->fd, &fmt) < 0) { 1605 ALOGE("%s::videodev set format failed", __func__); 1606 return -1; 1607 } 1608 1609 /* set src crop info :GSC video dev*/ 1610 crop.type = fmt.type; 1611 crop.c.left = gsc_handle->src_img.x; 1612 crop.c.top = gsc_handle->src_img.y; 1613 crop.c.width = gsc_handle->src_img.w; 1614 crop.c.height = gsc_handle->src_img.h; 1615 1616 if (exynos_v4l2_s_crop(gsc_handle->gsc_vd_entity->fd, &crop) < 0) { 1617 ALOGE("%s::videodev set crop failed", __func__); 1618 return -1; 1619 } 1620 1621 reqbuf.type = fmt.type; 1622 reqbuf.memory = V4L2_MEMORY_DMABUF; 1623 reqbuf.count = MAX_BUFFERS_GSCALER_OUT; 1624 1625 if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) { 1626 ALOGE("%s::request buffers failed", __func__); 1627 return -1; 1628 } 1629 1630 Exynos_gsc_Out(); 1631 1632 return 0; 1633 } 1634 1635 static int exynos_gsc_out_run(void *handle, 1636 exynos_gsc_img *src_img) 1637 { 1638 struct GSC_HANDLE *gsc_handle; 1639 struct v4l2_plane planes[NUM_OF_GSC_PLANES]; 1640 struct v4l2_buffer buf; 1641 int32_t src_color_space; 1642 int32_t src_planes; 1643 int i; 1644 unsigned int plane_size[NUM_OF_GSC_PLANES]; 1645 1646 gsc_handle = (struct GSC_HANDLE *)handle; 1647 if (handle == NULL) { 1648 ALOGE("%s::handle == NULL() fail", __func__); 1649 return -1; 1650 } 1651 1652 /* All buffers have been queued, dequeue one */ 1653 if (gsc_handle->src.qbuf_cnt == MAX_BUFFERS_GSCALER_OUT) { 1654 memset(&buf, 0, sizeof(struct v4l2_buffer)); 1655 for (i = 0; i < MAX_BUFFERS_GSCALER_OUT; i++) 1656 memset(&planes[i], 0, sizeof(struct v4l2_plane)); 1657 1658 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1659 buf.memory = V4L2_MEMORY_DMABUF; 1660 buf.length = src_planes; 1661 buf.m.planes = planes; 1662 1663 if (exynos_v4l2_dqbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) { 1664 ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)", __func__, 1665 gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT); 1666 return -1; 1667 } 1668 gsc_handle->src.qbuf_cnt--; 1669 } 1670 1671 memset(&buf, 0, sizeof(struct v4l2_buffer)); 1672 for (i = 0; i < NUM_OF_GSC_PLANES; i++) 1673 memset(&planes[i], 0, sizeof(struct v4l2_plane)); 1674 1675 src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc_handle->src_img.format); 1676 src_planes = get_yuv_planes(src_color_space); 1677 src_planes = (src_planes == -1) ? 1 : src_planes; 1678 1679 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1680 buf.memory = V4L2_MEMORY_DMABUF; 1681 buf.flags = V4L2_BUF_FLAG_USE_SYNC; 1682 buf.length = src_planes; 1683 buf.index = gsc_handle->src.src_buf_idx; 1684 buf.m.planes = planes; 1685 buf.reserved = src_img->acquireFenceFd; 1686 1687 gsc_handle->src.addr[0] = src_img->yaddr; 1688 gsc_handle->src.addr[1] = src_img->uaddr; 1689 gsc_handle->src.addr[2] = src_img->vaddr; 1690 1691 if (get_plane_size(src_color_space, plane_size, 1692 gsc_handle->src_img.fw * gsc_handle->src_img.fh, src_planes) != true) { 1693 ALOGE("%s:get_plane_size:fail", __func__); 1694 return -1; 1695 } 1696 1697 for (i = 0; i < buf.length; i++) { 1698 buf.m.planes[i].m.fd = (int)gsc_handle->src.addr[i]; 1699 buf.m.planes[i].length = plane_size[i]; 1700 buf.m.planes[i].bytesused = plane_size[i]; 1701 } 1702 1703 /* Queue the buf */ 1704 if (exynos_v4l2_qbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) { 1705 ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)", __func__, 1706 gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT); 1707 return -1; 1708 } 1709 gsc_handle->src.src_buf_idx++; 1710 gsc_handle->src.src_buf_idx = gsc_handle->src.src_buf_idx % MAX_BUFFERS_GSCALER_OUT; 1711 gsc_handle->src.qbuf_cnt++; 1712 1713 if (gsc_handle->src.stream_on == false) { 1714 if (exynos_v4l2_streamon(gsc_handle->gsc_vd_entity->fd, buf.type) < 0) { 1715 ALOGE("%s::stream on failed", __func__); 1716 return -1; 1717 } 1718 gsc_handle->src.stream_on = true; 1719 } 1720 1721 src_img->releaseFenceFd = buf.reserved; 1722 return 0; 1723 } 1724 1725 int exynos_gsc_out_stop(void *handle) 1726 { 1727 struct GSC_HANDLE *gsc_handle; 1728 struct v4l2_requestbuffers reqbuf; 1729 struct v4l2_buffer buf; 1730 struct v4l2_plane planes[NUM_OF_GSC_PLANES]; 1731 int i; 1732 1733 Exynos_gsc_In(); 1734 1735 gsc_handle = (struct GSC_HANDLE *)handle; 1736 if (handle == NULL) { 1737 ALOGE("%s::handle == NULL() fail", __func__); 1738 return -1; 1739 } 1740 1741 if (gsc_handle->src.stream_on == true) { 1742 if (exynos_v4l2_streamoff(gsc_handle->gsc_vd_entity->fd, 1743 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { 1744 ALOGE("%s::stream off failed", __func__); 1745 return -1; 1746 } 1747 gsc_handle->src.stream_on = false; 1748 } 1749 1750 gsc_handle->src.src_buf_idx = 0; 1751 gsc_handle->src.qbuf_cnt = 0; 1752 1753 reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1754 reqbuf.memory = V4L2_MEMORY_DMABUF; 1755 reqbuf.count = 0; 1756 1757 if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) { 1758 ALOGE("%s::request buffers failed", __func__); 1759 return -1; 1760 } 1761 1762 Exynos_gsc_Out(); 1763 1764 return 0; 1765 } 1766 1767 static int exynos_gsc_m2m_run_core(void *handle) 1768 { 1769 struct GSC_HANDLE *gsc_handle; 1770 bool is_dirty; 1771 bool is_drm; 1772 1773 gsc_handle = (struct GSC_HANDLE *)handle; 1774 1775 Exynos_gsc_In(); 1776 1777 if (handle == NULL) { 1778 ALOGE("%s::handle == NULL() fail", __func__); 1779 return -1; 1780 } 1781 1782 is_dirty = gsc_handle->src.dirty || gsc_handle->dst.dirty; 1783 is_drm = gsc_handle->src.mode_drm; 1784 1785 if (is_dirty && (gsc_handle->src.mode_drm != gsc_handle->dst.mode_drm)) { 1786 ALOGE("%s: drm mode mismatch between src and dst, gsc%d (s=%d d=%d)", 1787 __func__, gsc_handle->gsc_id, gsc_handle->src.mode_drm, 1788 gsc_handle->dst.mode_drm); 1789 return -1; 1790 } else if (is_drm && !gsc_handle->allow_drm) { 1791 ALOGE("%s: drm mode is not supported on gsc%d", __func__, 1792 gsc_handle->gsc_id); 1793 return -1; 1794 } 1795 1796 if (m_exynos_gsc_check_src_size(&gsc_handle->src.width, &gsc_handle->src.height, 1797 &gsc_handle->src.crop_left, &gsc_handle->src.crop_top, 1798 &gsc_handle->src.crop_width, &gsc_handle->src.crop_height, 1799 gsc_handle->src.v4l2_colorformat) == false) { 1800 ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__); 1801 return -1; 1802 } 1803 1804 if (m_exynos_gsc_check_dst_size(&gsc_handle->dst.width, &gsc_handle->dst.height, 1805 &gsc_handle->dst.crop_left, &gsc_handle->dst.crop_top, 1806 &gsc_handle->dst.crop_width, &gsc_handle->dst.crop_height, 1807 gsc_handle->dst.v4l2_colorformat, 1808 gsc_handle->dst.rotation) == false) { 1809 ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__); 1810 return -1; 1811 } 1812 1813 /* dequeue buffers from previous work if necessary */ 1814 if (gsc_handle->src.stream_on == true) { 1815 if (exynos_gsc_m2m_wait_frame_done(handle) < 0) { 1816 ALOGE("%s::exynos_gsc_m2m_wait_frame_done fail", __func__); 1817 return -1; 1818 } 1819 } 1820 1821 /* 1822 * need to set the content protection flag before doing reqbufs 1823 * in set_format 1824 */ 1825 if (is_dirty && gsc_handle->allow_drm && is_drm) { 1826 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_fd, 1827 V4L2_CID_CONTENT_PROTECTION, is_drm) < 0) { 1828 ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__); 1829 return -1; 1830 } 1831 } 1832 1833 /* 1834 * from this point on, we have to ensure to call stop to clean up whatever 1835 * state we have set. 1836 */ 1837 1838 if (gsc_handle->src.dirty) { 1839 if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->src) == false) { 1840 ALOGE("%s::m_exynos_gsc_set_format(src) fail", __func__); 1841 goto done; 1842 } 1843 gsc_handle->src.dirty = false; 1844 } 1845 1846 if (gsc_handle->dst.dirty) { 1847 if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->dst) == false) { 1848 ALOGE("%s::m_exynos_gsc_set_format(dst) fail", __func__); 1849 goto done; 1850 } 1851 gsc_handle->dst.dirty = false; 1852 } 1853 1854 /* if we are enabling drm, make sure to enable hw protection. 1855 * Need to do this before queuing buffers so that the mmu is reserved 1856 * and power domain is kept on. 1857 */ 1858 if (is_dirty && gsc_handle->allow_drm && is_drm) { 1859 unsigned int protect_id = 0; 1860 1861 if (gsc_handle->gsc_id == 0) { 1862 protect_id = CP_PROTECT_GSC0; 1863 } else if (gsc_handle->gsc_id == 3) { 1864 protect_id = CP_PROTECT_GSC3; 1865 } else { 1866 ALOGE("%s::invalid gscaler id %d for content protection", __func__, 1867 gsc_handle->gsc_id); 1868 goto done; 1869 } 1870 1871 if (CP_Enable_Path_Protection(protect_id) != 0) { 1872 ALOGE("%s::CP_Enable_Path_Protection failed", __func__); 1873 goto done; 1874 } 1875 gsc_handle->protection_enabled = true; 1876 } 1877 1878 if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->src) == false) { 1879 ALOGE("%s::m_exynos_gsc_set_addr(src) fail", __func__); 1880 goto done; 1881 } 1882 1883 if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->dst) == false) { 1884 ALOGE("%s::m_exynos_gsc_set_addr(dst) fail", __func__); 1885 goto done; 1886 } 1887 1888 if (gsc_handle->src.stream_on == false) { 1889 if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) { 1890 ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__); 1891 goto done; 1892 } 1893 gsc_handle->src.stream_on = true; 1894 } 1895 1896 if (gsc_handle->dst.stream_on == false) { 1897 if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) { 1898 ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__); 1899 goto done; 1900 } 1901 gsc_handle->dst.stream_on = true; 1902 } 1903 1904 Exynos_gsc_Out(); 1905 1906 return 0; 1907 1908 done: 1909 exynos_gsc_m2m_stop(handle); 1910 return -1; 1911 } 1912 1913 static int exynos_gsc_m2m_wait_frame_done(void *handle) 1914 { 1915 struct GSC_HANDLE *gsc_handle; 1916 1917 gsc_handle = (struct GSC_HANDLE *)handle; 1918 1919 Exynos_gsc_In(); 1920 1921 if (handle == NULL) { 1922 ALOGE("%s::handle == NULL() fail", __func__); 1923 return -1; 1924 } 1925 1926 if ((gsc_handle->src.stream_on == false) || (gsc_handle->dst.stream_on == false)) { 1927 ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__); 1928 return -1; 1929 } 1930 1931 if (gsc_handle->src.buffer_queued) { 1932 if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->src.buffer) < 0) { 1933 ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__); 1934 return -1; 1935 } 1936 gsc_handle->src.buffer_queued = false; 1937 } 1938 1939 if (gsc_handle->dst.buffer_queued) { 1940 if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->dst.buffer) < 0) { 1941 ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__); 1942 return -1; 1943 } 1944 gsc_handle->dst.buffer_queued = false; 1945 } 1946 1947 Exynos_gsc_Out(); 1948 1949 return 0; 1950 } 1951 1952 static int exynos_gsc_m2m_stop(void *handle) 1953 { 1954 struct GSC_HANDLE *gsc_handle; 1955 struct v4l2_requestbuffers req_buf; 1956 int ret = 0; 1957 1958 gsc_handle = (struct GSC_HANDLE *)handle; 1959 1960 Exynos_gsc_In(); 1961 1962 if (!gsc_handle->src.stream_on && !gsc_handle->dst.stream_on) { 1963 /* wasn't streaming, return success */ 1964 return 0; 1965 } else if (gsc_handle->src.stream_on != gsc_handle->dst.stream_on) { 1966 ALOGE("%s: invalid state, queue stream state doesn't match (%d != %d)", 1967 __func__, gsc_handle->src.stream_on, gsc_handle->dst.stream_on); 1968 ret = -1; 1969 } 1970 1971 /* 1972 * we need to plow forward on errors below to make sure that if we had 1973 * turned on content protection on secure side, we turn it off. 1974 * 1975 * also, if we only failed to turn on one of the streams, we'll turn 1976 * the other one off correctly. 1977 */ 1978 if (gsc_handle->src.stream_on == true) { 1979 if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) { 1980 ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__); 1981 ret = -1; 1982 } 1983 gsc_handle->src.stream_on = false; 1984 } 1985 1986 1987 if (gsc_handle->dst.stream_on == true) { 1988 if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) { 1989 ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__); 1990 ret = -1; 1991 } 1992 gsc_handle->dst.stream_on = false; 1993 } 1994 1995 /* if drm is enabled */ 1996 if (gsc_handle->allow_drm && gsc_handle->protection_enabled) { 1997 unsigned int protect_id = 0; 1998 1999 if (gsc_handle->gsc_id == 0) 2000 protect_id = CP_PROTECT_GSC0; 2001 else if (gsc_handle->gsc_id == 3) 2002 protect_id = CP_PROTECT_GSC3; 2003 2004 CP_Disable_Path_Protection(protect_id); 2005 gsc_handle->protection_enabled = false; 2006 } 2007 2008 if (exynos_v4l2_s_ctrl(gsc_handle->gsc_fd, 2009 V4L2_CID_CONTENT_PROTECTION, 0) < 0) { 2010 ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail", 2011 __func__); 2012 ret = -1; 2013 } 2014 2015 /* src: clear_buf */ 2016 req_buf.count = 0; 2017 req_buf.type = gsc_handle->src.buf_type; 2018 req_buf.memory = V4L2_MEMORY_DMABUF; 2019 if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) { 2020 ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__); 2021 ret = -1; 2022 } 2023 2024 /* dst: clear_buf */ 2025 req_buf.count = 0; 2026 req_buf.type = gsc_handle->dst.buf_type; 2027 req_buf.memory = V4L2_MEMORY_DMABUF; 2028 if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) { 2029 ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__); 2030 ret = -1; 2031 } 2032 2033 Exynos_gsc_Out(); 2034 2035 return ret; 2036 } 2037 2038 int exynos_gsc_convert( 2039 void *handle) 2040 { 2041 struct GSC_HANDLE *gsc_handle; 2042 int ret = -1; 2043 gsc_handle = (struct GSC_HANDLE *)handle; 2044 2045 Exynos_gsc_In(); 2046 2047 if (handle == NULL) { 2048 ALOGE("%s::handle == NULL() fail", __func__); 2049 return -1; 2050 } 2051 2052 exynos_mutex_lock(gsc_handle->op_mutex); 2053 2054 if (gsc_handle->flag_local_path == true) { 2055 ALOGE("%s::this exynos_gsc is connected by another hw internaly. So, don't call exynos_gsc_convert()", __func__); 2056 goto done; 2057 } 2058 2059 if (exynos_gsc_m2m_run_core(handle) < 0) { 2060 ALOGE("%s::exynos_gsc_run_core fail", __func__); 2061 goto done; 2062 } 2063 2064 if (exynos_gsc_m2m_wait_frame_done(handle) < 0) { 2065 ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__); 2066 goto done; 2067 } 2068 2069 if (gsc_handle->src.releaseFenceFd >= 0) { 2070 close(gsc_handle->src.releaseFenceFd); 2071 gsc_handle->src.releaseFenceFd = -1; 2072 } 2073 2074 if (gsc_handle->dst.releaseFenceFd >= 0) { 2075 close(gsc_handle->dst.releaseFenceFd); 2076 gsc_handle->dst.releaseFenceFd = -1; 2077 } 2078 2079 if (exynos_gsc_m2m_stop(handle) < 0) { 2080 ALOGE("%s::exynos_gsc_m2m_stop", __func__); 2081 goto done; 2082 } 2083 2084 ret = 0; 2085 2086 done: 2087 if (gsc_handle->flag_exclusive_open == false) { 2088 if (gsc_handle->flag_local_path == false) 2089 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 2090 } 2091 2092 exynos_mutex_unlock(gsc_handle->op_mutex); 2093 2094 Exynos_gsc_Out(); 2095 2096 return ret; 2097 } 2098 2099 int exynos_gsc_m2m_run(void *handle, 2100 exynos_gsc_img *src_img, 2101 exynos_gsc_img *dst_img) 2102 { 2103 struct GSC_HANDLE *gsc_handle = handle; 2104 void *addr[3] = {NULL, NULL, NULL}; 2105 int ret = 0; 2106 2107 Exynos_gsc_In(); 2108 2109 addr[0] = (void *)src_img->yaddr; 2110 addr[1] = (void *)src_img->uaddr; 2111 addr[2] = (void *)src_img->vaddr; 2112 ret = exynos_gsc_set_src_addr(handle, addr, src_img->acquireFenceFd); 2113 if (ret < 0) { 2114 ALOGE("%s::fail: exynos_gsc_set_src_addr[%x %x %x]", __func__, 2115 (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]); 2116 return -1; 2117 } 2118 2119 addr[0] = (void *)dst_img->yaddr; 2120 addr[1] = (void *)dst_img->uaddr; 2121 addr[2] = (void *)dst_img->vaddr; 2122 ret = exynos_gsc_set_dst_addr(handle, addr, dst_img->acquireFenceFd); 2123 if (ret < 0) { 2124 ALOGE("%s::fail: exynos_gsc_set_dst_addr[%x %x %x]", __func__, 2125 (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]); 2126 return -1; 2127 } 2128 2129 ret = exynos_gsc_m2m_run_core(handle); 2130 if (ret < 0) { 2131 ALOGE("%s::fail: exynos_gsc_m2m_run_core", __func__); 2132 return -1; 2133 } 2134 2135 if (src_img->acquireFenceFd >= 0) { 2136 close(src_img->acquireFenceFd); 2137 src_img->acquireFenceFd = -1; 2138 } 2139 2140 if (dst_img->acquireFenceFd >= 0) { 2141 close(dst_img->acquireFenceFd); 2142 dst_img->acquireFenceFd = -1; 2143 } 2144 2145 src_img->releaseFenceFd = gsc_handle->src.releaseFenceFd; 2146 dst_img->releaseFenceFd = gsc_handle->dst.releaseFenceFd; 2147 2148 Exynos_gsc_Out(); 2149 2150 return 0; 2151 } 2152 2153 int exynos_gsc_config_exclusive(void *handle, 2154 exynos_gsc_img *src_img, 2155 exynos_gsc_img *dst_img) 2156 { 2157 2158 Exynos_gsc_In(); 2159 2160 struct GSC_HANDLE *gsc_handle; 2161 int ret = 0; 2162 gsc_handle = (struct GSC_HANDLE *)handle; 2163 if (handle == NULL) { 2164 ALOGE("%s::handle == NULL() fail", __func__); 2165 return -1; 2166 } 2167 2168 switch (gsc_handle->gsc_mode) { 2169 case GSC_M2M_MODE: 2170 ret = exynos_gsc_m2m_config(handle, src_img, dst_img); 2171 break; 2172 case GSC_OUTPUT_MODE: 2173 ret = exynos_gsc_out_config(handle, src_img, dst_img); 2174 break; 2175 case GSC_CAPTURE_MODE: 2176 //to do 2177 break; 2178 default: 2179 break; 2180 } 2181 2182 Exynos_gsc_Out(); 2183 2184 return ret; 2185 2186 } 2187 2188 int exynos_gsc_run_exclusive(void *handle, 2189 exynos_gsc_img *src_img, 2190 exynos_gsc_img *dst_img) 2191 { 2192 struct GSC_HANDLE *gsc_handle; 2193 int ret = 0; 2194 2195 Exynos_gsc_In(); 2196 2197 gsc_handle = (struct GSC_HANDLE *)handle; 2198 if (handle == NULL) { 2199 ALOGE("%s::handle == NULL() fail", __func__); 2200 return -1; 2201 } 2202 2203 switch (gsc_handle->gsc_mode) { 2204 case GSC_M2M_MODE: 2205 ret = exynos_gsc_m2m_run(handle, src_img, dst_img); 2206 break; 2207 case GSC_OUTPUT_MODE: 2208 ret = exynos_gsc_out_run(handle, src_img); 2209 break; 2210 case GSC_CAPTURE_MODE: 2211 //to do 2212 break; 2213 default: 2214 break; 2215 } 2216 2217 Exynos_gsc_Out(); 2218 2219 return ret; 2220 } 2221 2222 int exynos_gsc_wait_frame_done_exclusive(void *handle) 2223 { 2224 struct GSC_HANDLE *gsc_handle; 2225 int ret = 0; 2226 gsc_handle = (struct GSC_HANDLE *)handle; 2227 2228 Exynos_gsc_In(); 2229 2230 if (handle == NULL) { 2231 ALOGE("%s::handle == NULL() fail", __func__); 2232 return -1; 2233 } 2234 2235 if (gsc_handle->gsc_mode == GSC_M2M_MODE) 2236 ret = exynos_gsc_m2m_wait_frame_done(handle); 2237 2238 Exynos_gsc_Out(); 2239 2240 return ret; 2241 } 2242 2243 int exynos_gsc_stop_exclusive(void *handle) 2244 { 2245 struct GSC_HANDLE *gsc_handle; 2246 int ret = 0; 2247 gsc_handle = (struct GSC_HANDLE *)handle; 2248 2249 Exynos_gsc_In(); 2250 2251 if (handle == NULL) { 2252 ALOGE("%s::handle == NULL() fail", __func__); 2253 return -1; 2254 } 2255 2256 switch (gsc_handle->gsc_mode) { 2257 case GSC_M2M_MODE: 2258 ret = exynos_gsc_m2m_stop(handle); 2259 break; 2260 case GSC_OUTPUT_MODE: 2261 ret = exynos_gsc_out_stop(handle); 2262 break; 2263 case GSC_CAPTURE_MODE: 2264 //to do 2265 break; 2266 default: 2267 break; 2268 } 2269 2270 Exynos_gsc_Out(); 2271 2272 return ret; 2273 } 2274 2275 int exynos_gsc_connect( 2276 void *handle, 2277 void *hw) 2278 { 2279 struct GSC_HANDLE *gsc_handle; 2280 int ret = -1; 2281 gsc_handle = (struct GSC_HANDLE *)handle; 2282 2283 Exynos_gsc_In(); 2284 2285 if (handle == NULL) { 2286 ALOGE("%s::handle == NULL() fail", __func__); 2287 return -1; 2288 } 2289 2290 exynos_mutex_lock(gsc_handle->op_mutex); 2291 2292 gsc_handle->flag_local_path = true; 2293 2294 if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == false) { 2295 if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) { 2296 ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__); 2297 goto done; 2298 } 2299 } 2300 2301 ret = 0; 2302 2303 Exynos_gsc_Out(); 2304 2305 done: 2306 exynos_mutex_unlock(gsc_handle->op_mutex); 2307 2308 return ret; 2309 } 2310 2311 int exynos_gsc_disconnect( 2312 void *handle, 2313 void *hw) 2314 { 2315 struct GSC_HANDLE *gsc_handle; 2316 gsc_handle = (struct GSC_HANDLE *)handle; 2317 2318 Exynos_gsc_In(); 2319 2320 if (handle == NULL) { 2321 ALOGE("%s::handle == NULL() fail", __func__); 2322 return -1; 2323 } 2324 2325 exynos_mutex_lock(gsc_handle->op_mutex); 2326 2327 gsc_handle->flag_local_path = false; 2328 2329 exynos_mutex_unlock(gsc_handle->cur_obj_mutex); 2330 2331 exynos_mutex_unlock(gsc_handle->op_mutex); 2332 2333 Exynos_gsc_Out(); 2334 2335 return 0; 2336 } 2337