1 /* 2 * Support for Intel Camera Imaging ISP subsystem. 3 * Copyright (c) 2010 - 2015, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 */ 14 15 #include "hmm.h" 16 17 #include "ia_css_debug.h" 18 #include "sw_event_global.h" /* encode_sw_event */ 19 #include "sp.h" /* cnd_sp_irq_enable() */ 20 #include "assert_support.h" 21 #include "sh_css_sp.h" 22 #include "ia_css_pipeline.h" 23 #include "ia_css_isp_param.h" 24 #include "ia_css_bufq.h" 25 26 #define PIPELINE_NUM_UNMAPPED (~0U) 27 #define PIPELINE_SP_THREAD_EMPTY_TOKEN (0x0) 28 #define PIPELINE_SP_THREAD_RESERVED_TOKEN (0x1) 29 30 /******************************************************* 31 *** Static variables 32 ********************************************************/ 33 static unsigned int pipeline_num_to_sp_thread_map[IA_CSS_PIPELINE_NUM_MAX]; 34 static unsigned int pipeline_sp_thread_list[SH_CSS_MAX_SP_THREADS]; 35 36 /******************************************************* 37 *** Static functions 38 ********************************************************/ 39 static void pipeline_init_sp_thread_map(void); 40 static void pipeline_map_num_to_sp_thread(unsigned int pipe_num); 41 static void pipeline_unmap_num_to_sp_thread(unsigned int pipe_num); 42 static void pipeline_init_defaults( 43 struct ia_css_pipeline *pipeline, 44 enum ia_css_pipe_id pipe_id, 45 unsigned int pipe_num, 46 unsigned int dvs_frame_delay); 47 48 static void pipeline_stage_destroy(struct ia_css_pipeline_stage *stage); 49 static enum ia_css_err pipeline_stage_create( 50 struct ia_css_pipeline_stage_desc *stage_desc, 51 struct ia_css_pipeline_stage **new_stage); 52 static void ia_css_pipeline_set_zoom_stage(struct ia_css_pipeline *pipeline); 53 static void ia_css_pipeline_configure_inout_port(struct ia_css_pipeline *me, 54 bool continuous); 55 56 /******************************************************* 57 *** Public functions 58 ********************************************************/ 59 void ia_css_pipeline_init(void) 60 { 61 pipeline_init_sp_thread_map(); 62 } 63 64 enum ia_css_err ia_css_pipeline_create( 65 struct ia_css_pipeline *pipeline, 66 enum ia_css_pipe_id pipe_id, 67 unsigned int pipe_num, 68 unsigned int dvs_frame_delay) 69 { 70 assert(pipeline); 71 IA_CSS_ENTER_PRIVATE("pipeline = %p, pipe_id = %d, pipe_num = %d, dvs_frame_delay = %d", 72 pipeline, pipe_id, pipe_num, dvs_frame_delay); 73 if (!pipeline) { 74 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS); 75 return IA_CSS_ERR_INVALID_ARGUMENTS; 76 } 77 78 pipeline_init_defaults(pipeline, pipe_id, pipe_num, dvs_frame_delay); 79 80 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS); 81 return IA_CSS_SUCCESS; 82 } 83 84 void ia_css_pipeline_map(unsigned int pipe_num, bool map) 85 { 86 assert(pipe_num < IA_CSS_PIPELINE_NUM_MAX); 87 IA_CSS_ENTER_PRIVATE("pipe_num = %d, map = %d", pipe_num, map); 88 89 if (pipe_num >= IA_CSS_PIPELINE_NUM_MAX) { 90 IA_CSS_ERROR("Invalid pipe number"); 91 IA_CSS_LEAVE_PRIVATE("void"); 92 return; 93 } 94 if (map) 95 pipeline_map_num_to_sp_thread(pipe_num); 96 else 97 pipeline_unmap_num_to_sp_thread(pipe_num); 98 IA_CSS_LEAVE_PRIVATE("void"); 99 } 100 101 /* @brief destroy a pipeline 102 * 103 * @param[in] pipeline 104 * @return None 105 * 106 */ 107 void ia_css_pipeline_destroy(struct ia_css_pipeline *pipeline) 108 { 109 assert(pipeline); 110 IA_CSS_ENTER_PRIVATE("pipeline = %p", pipeline); 111 112 if (!pipeline) { 113 IA_CSS_ERROR("NULL input parameter"); 114 IA_CSS_LEAVE_PRIVATE("void"); 115 return; 116 } 117 118 IA_CSS_LOG("pipe_num = %d", pipeline->pipe_num); 119 120 /* Free the pipeline number */ 121 ia_css_pipeline_clean(pipeline); 122 123 IA_CSS_LEAVE_PRIVATE("void"); 124 } 125 126 /* Run a pipeline and wait till it completes. */ 127 void ia_css_pipeline_start(enum ia_css_pipe_id pipe_id, 128 struct ia_css_pipeline *pipeline) 129 { 130 u8 pipe_num = 0; 131 unsigned int thread_id; 132 133 assert(pipeline); 134 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 135 "ia_css_pipeline_start() enter: pipe_id=%d, pipeline=%p\n", 136 pipe_id, pipeline); 137 pipeline->pipe_id = pipe_id; 138 sh_css_sp_init_pipeline(pipeline, pipe_id, pipe_num, 139 false, false, false, true, SH_CSS_BDS_FACTOR_1_00, 140 SH_CSS_PIPE_CONFIG_OVRD_NO_OVRD, 141 IA_CSS_INPUT_MODE_MEMORY, NULL, NULL, 142 #if !defined(HAS_NO_INPUT_SYSTEM) 143 (enum mipi_port_id)0, 144 #endif 145 NULL, NULL); 146 147 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id); 148 if (!sh_css_sp_is_running()) { 149 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 150 "ia_css_pipeline_start() error,leaving\n"); 151 /* queues are invalid*/ 152 return; 153 } 154 ia_css_bufq_enqueue_psys_event(IA_CSS_PSYS_SW_EVENT_START_STREAM, 155 (uint8_t)thread_id, 156 0, 157 0); 158 159 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 160 "ia_css_pipeline_start() leave: return_void\n"); 161 } 162 163 /* 164 * @brief Query the SP thread ID. 165 * Refer to "sh_css_internal.h" for details. 166 */ 167 bool ia_css_pipeline_get_sp_thread_id(unsigned int key, unsigned int *val) 168 { 169 IA_CSS_ENTER("key=%d, val=%p", key, val); 170 171 if ((!val) || (key >= IA_CSS_PIPELINE_NUM_MAX) || (key >= IA_CSS_PIPE_ID_NUM)) { 172 IA_CSS_LEAVE("return value = false"); 173 return false; 174 } 175 176 *val = pipeline_num_to_sp_thread_map[key]; 177 178 if (*val == (unsigned int)PIPELINE_NUM_UNMAPPED) { 179 IA_CSS_LOG("unmapped pipeline number"); 180 IA_CSS_LEAVE("return value = false"); 181 return false; 182 } 183 IA_CSS_LEAVE("return value = true"); 184 return true; 185 } 186 187 void ia_css_pipeline_dump_thread_map_info(void) 188 { 189 unsigned int i; 190 191 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 192 "pipeline_num_to_sp_thread_map:\n"); 193 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) { 194 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 195 "pipe_num: %u, tid: 0x%x\n", i, pipeline_num_to_sp_thread_map[i]); 196 } 197 } 198 199 enum ia_css_err ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline) 200 { 201 enum ia_css_err err = IA_CSS_SUCCESS; 202 unsigned int thread_id; 203 204 assert(pipeline); 205 206 if (!pipeline) 207 return IA_CSS_ERR_INVALID_ARGUMENTS; 208 209 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 210 "ia_css_pipeline_request_stop() enter: pipeline=%p\n", 211 pipeline); 212 pipeline->stop_requested = true; 213 214 /* Send stop event to the sp*/ 215 /* This needs improvement, stop on all the pipes available 216 * in the stream*/ 217 ia_css_pipeline_get_sp_thread_id(pipeline->pipe_num, &thread_id); 218 if (!sh_css_sp_is_running()) { 219 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 220 "ia_css_pipeline_request_stop() leaving\n"); 221 /* queues are invalid */ 222 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE; 223 } 224 ia_css_bufq_enqueue_psys_event(IA_CSS_PSYS_SW_EVENT_STOP_STREAM, 225 (uint8_t)thread_id, 226 0, 227 0); 228 sh_css_sp_uninit_pipeline(pipeline->pipe_num); 229 230 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 231 "ia_css_pipeline_request_stop() leave: return_err=%d\n", 232 err); 233 return err; 234 } 235 236 void ia_css_pipeline_clean(struct ia_css_pipeline *pipeline) 237 { 238 struct ia_css_pipeline_stage *s; 239 240 assert(pipeline); 241 IA_CSS_ENTER_PRIVATE("pipeline = %p", pipeline); 242 243 if (!pipeline) { 244 IA_CSS_ERROR("NULL input parameter"); 245 IA_CSS_LEAVE_PRIVATE("void"); 246 return; 247 } 248 s = pipeline->stages; 249 250 while (s) { 251 struct ia_css_pipeline_stage *next = s->next; 252 253 pipeline_stage_destroy(s); 254 s = next; 255 } 256 pipeline_init_defaults(pipeline, pipeline->pipe_id, pipeline->pipe_num, 257 pipeline->dvs_frame_delay); 258 259 IA_CSS_LEAVE_PRIVATE("void"); 260 } 261 262 /* @brief Add a stage to pipeline. 263 * 264 * @param pipeline Pointer to the pipeline to be added to. 265 * @param[in] stage_desc The description of the stage 266 * @param[out] stage The successor of the stage. 267 * @return IA_CSS_SUCCESS or error code upon error. 268 * 269 * Add a new stage to a non-NULL pipeline. 270 * The stage consists of an ISP binary or firmware and input and 271 * output arguments. 272 */ 273 enum ia_css_err ia_css_pipeline_create_and_add_stage( 274 struct ia_css_pipeline *pipeline, 275 struct ia_css_pipeline_stage_desc *stage_desc, 276 struct ia_css_pipeline_stage **stage) 277 { 278 struct ia_css_pipeline_stage *last, *new_stage = NULL; 279 enum ia_css_err err; 280 281 /* other arguments can be NULL */ 282 assert(pipeline); 283 assert(stage_desc); 284 last = pipeline->stages; 285 286 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 287 "ia_css_pipeline_create_and_add_stage() enter:\n"); 288 if (!stage_desc->binary && !stage_desc->firmware 289 && (stage_desc->sp_func == IA_CSS_PIPELINE_NO_FUNC)) { 290 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 291 "ia_css_pipeline_create_and_add_stage() done: Invalid args\n"); 292 293 return IA_CSS_ERR_INTERNAL_ERROR; 294 } 295 296 /* Find the last stage */ 297 while (last && last->next) 298 last = last->next; 299 300 /* if in_frame is not set, we use the out_frame from the previous 301 * stage, if no previous stage, it's an error. 302 */ 303 if ((stage_desc->sp_func == IA_CSS_PIPELINE_NO_FUNC) 304 && (!stage_desc->in_frame) 305 && (!stage_desc->firmware) 306 && (!stage_desc->binary->online)) { 307 /* Do this only for ISP stages*/ 308 if (last && last->args.out_frame[0]) 309 stage_desc->in_frame = last->args.out_frame[0]; 310 311 if (!stage_desc->in_frame) 312 return IA_CSS_ERR_INTERNAL_ERROR; 313 } 314 315 /* Create the new stage */ 316 err = pipeline_stage_create(stage_desc, &new_stage); 317 if (err != IA_CSS_SUCCESS) { 318 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 319 "ia_css_pipeline_create_and_add_stage() done: stage_create_failed\n"); 320 return err; 321 } 322 323 if (last) 324 last->next = new_stage; 325 else 326 pipeline->stages = new_stage; 327 328 /* Output the new stage */ 329 if (stage) 330 *stage = new_stage; 331 332 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 333 "ia_css_pipeline_create_and_add_stage() done:\n"); 334 return IA_CSS_SUCCESS; 335 } 336 337 void ia_css_pipeline_finalize_stages(struct ia_css_pipeline *pipeline, 338 bool continuous) 339 { 340 unsigned int i = 0; 341 struct ia_css_pipeline_stage *stage; 342 343 assert(pipeline); 344 for (stage = pipeline->stages; stage; stage = stage->next) { 345 stage->stage_num = i; 346 i++; 347 } 348 pipeline->num_stages = i; 349 350 ia_css_pipeline_set_zoom_stage(pipeline); 351 ia_css_pipeline_configure_inout_port(pipeline, continuous); 352 } 353 354 enum ia_css_err ia_css_pipeline_get_stage(struct ia_css_pipeline *pipeline, 355 int mode, 356 struct ia_css_pipeline_stage **stage) 357 { 358 struct ia_css_pipeline_stage *s; 359 360 assert(pipeline); 361 assert(stage); 362 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 363 "ia_css_pipeline_get_stage() enter:\n"); 364 for (s = pipeline->stages; s; s = s->next) { 365 if (s->mode == mode) { 366 *stage = s; 367 return IA_CSS_SUCCESS; 368 } 369 } 370 return IA_CSS_ERR_INTERNAL_ERROR; 371 } 372 373 enum ia_css_err ia_css_pipeline_get_stage_from_fw(struct ia_css_pipeline 374 *pipeline, 375 u32 fw_handle, 376 struct ia_css_pipeline_stage **stage) 377 { 378 struct ia_css_pipeline_stage *s; 379 380 assert(pipeline); 381 assert(stage); 382 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%s()\n", __func__); 383 for (s = pipeline->stages; s; s = s->next) { 384 if ((s->firmware) && (s->firmware->handle == fw_handle)) { 385 *stage = s; 386 return IA_CSS_SUCCESS; 387 } 388 } 389 return IA_CSS_ERR_INTERNAL_ERROR; 390 } 391 392 enum ia_css_err ia_css_pipeline_get_fw_from_stage(struct ia_css_pipeline 393 *pipeline, 394 u32 stage_num, 395 uint32_t *fw_handle) 396 { 397 struct ia_css_pipeline_stage *s; 398 399 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%s()\n", __func__); 400 if ((!pipeline) || (!fw_handle)) 401 return IA_CSS_ERR_INVALID_ARGUMENTS; 402 403 for (s = pipeline->stages; s; s = s->next) { 404 if ((s->stage_num == stage_num) && (s->firmware)) { 405 *fw_handle = s->firmware->handle; 406 return IA_CSS_SUCCESS; 407 } 408 } 409 return IA_CSS_ERR_INTERNAL_ERROR; 410 } 411 412 enum ia_css_err ia_css_pipeline_get_output_stage( 413 struct ia_css_pipeline *pipeline, 414 int mode, 415 struct ia_css_pipeline_stage **stage) 416 { 417 struct ia_css_pipeline_stage *s; 418 419 assert(pipeline); 420 assert(stage); 421 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 422 "ia_css_pipeline_get_output_stage() enter:\n"); 423 424 *stage = NULL; 425 /* First find acceleration firmware at end of pipe */ 426 for (s = pipeline->stages; s; s = s->next) { 427 if (s->firmware && s->mode == mode && 428 s->firmware->info.isp.sp.enable.output) 429 *stage = s; 430 } 431 if (*stage) 432 return IA_CSS_SUCCESS; 433 /* If no firmware, find binary in pipe */ 434 return ia_css_pipeline_get_stage(pipeline, mode, stage); 435 } 436 437 bool ia_css_pipeline_has_stopped(struct ia_css_pipeline *pipeline) 438 { 439 /* Android compilation files if made an local variable 440 stack size on android is limited to 2k and this structure 441 is around 2.5K, in place of static malloc can be done but 442 if this call is made too often it will lead to fragment memory 443 versus a fixed allocation */ 444 static struct sh_css_sp_group sp_group; 445 unsigned int thread_id; 446 const struct ia_css_fw_info *fw; 447 unsigned int HIVE_ADDR_sp_group; 448 449 fw = &sh_css_sp_fw; 450 HIVE_ADDR_sp_group = fw->info.sp.group; 451 452 ia_css_pipeline_get_sp_thread_id(pipeline->pipe_num, &thread_id); 453 sp_dmem_load(SP0_ID, 454 (unsigned int)sp_address_of(sp_group), 455 &sp_group, sizeof(struct sh_css_sp_group)); 456 return sp_group.pipe[thread_id].num_stages == 0; 457 } 458 459 #if defined(USE_INPUT_SYSTEM_VERSION_2401) 460 struct sh_css_sp_pipeline_io_status *ia_css_pipeline_get_pipe_io_status(void) 461 { 462 return(&sh_css_sp_group.pipe_io_status); 463 } 464 #endif 465 466 bool ia_css_pipeline_is_mapped(unsigned int key) 467 { 468 bool ret = false; 469 470 IA_CSS_ENTER_PRIVATE("key = %d", key); 471 472 if ((key >= IA_CSS_PIPELINE_NUM_MAX) || (key >= IA_CSS_PIPE_ID_NUM)) { 473 IA_CSS_ERROR("Invalid key!!"); 474 IA_CSS_LEAVE_PRIVATE("return = %d", false); 475 return false; 476 } 477 478 ret = (bool)(pipeline_num_to_sp_thread_map[key] != (unsigned int) 479 PIPELINE_NUM_UNMAPPED); 480 481 IA_CSS_LEAVE_PRIVATE("return = %d", ret); 482 return ret; 483 } 484 485 /******************************************************* 486 *** Static functions 487 ********************************************************/ 488 489 /* Pipeline: 490 * To organize the several different binaries for each type of mode, 491 * we use a pipeline. A pipeline contains a number of stages, each with 492 * their own binary and frame pointers. 493 * When stages are added to a pipeline, output frames that are not passed 494 * from outside are automatically allocated. 495 * When input frames are not passed from outside, each stage will use the 496 * output frame of the previous stage as input (the full resolution output, 497 * not the viewfinder output). 498 * Pipelines must be cleaned and re-created when settings of the binaries 499 * change. 500 */ 501 static void pipeline_stage_destroy(struct ia_css_pipeline_stage *stage) 502 { 503 unsigned int i; 504 505 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { 506 if (stage->out_frame_allocated[i]) { 507 ia_css_frame_free(stage->args.out_frame[i]); 508 stage->args.out_frame[i] = NULL; 509 } 510 } 511 if (stage->vf_frame_allocated) { 512 ia_css_frame_free(stage->args.out_vf_frame); 513 stage->args.out_vf_frame = NULL; 514 } 515 kvfree(stage); 516 } 517 518 static void pipeline_init_sp_thread_map(void) 519 { 520 unsigned int i; 521 522 for (i = 1; i < SH_CSS_MAX_SP_THREADS; i++) 523 pipeline_sp_thread_list[i] = PIPELINE_SP_THREAD_EMPTY_TOKEN; 524 525 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) 526 pipeline_num_to_sp_thread_map[i] = PIPELINE_NUM_UNMAPPED; 527 } 528 529 static void pipeline_map_num_to_sp_thread(unsigned int pipe_num) 530 { 531 unsigned int i; 532 bool found_sp_thread = false; 533 534 /* pipe is not mapped to any thread */ 535 assert(pipeline_num_to_sp_thread_map[pipe_num] 536 == (unsigned int)PIPELINE_NUM_UNMAPPED); 537 538 for (i = 0; i < SH_CSS_MAX_SP_THREADS; i++) { 539 if (pipeline_sp_thread_list[i] == 540 PIPELINE_SP_THREAD_EMPTY_TOKEN) { 541 pipeline_sp_thread_list[i] = 542 PIPELINE_SP_THREAD_RESERVED_TOKEN; 543 pipeline_num_to_sp_thread_map[pipe_num] = i; 544 found_sp_thread = true; 545 break; 546 } 547 } 548 549 /* Make sure a mapping is found */ 550 /* I could do: 551 assert(i < SH_CSS_MAX_SP_THREADS); 552 553 But the below is more descriptive. 554 */ 555 assert(found_sp_thread); 556 } 557 558 static void pipeline_unmap_num_to_sp_thread(unsigned int pipe_num) 559 { 560 unsigned int thread_id; 561 562 assert(pipeline_num_to_sp_thread_map[pipe_num] 563 != (unsigned int)PIPELINE_NUM_UNMAPPED); 564 565 thread_id = pipeline_num_to_sp_thread_map[pipe_num]; 566 pipeline_num_to_sp_thread_map[pipe_num] = PIPELINE_NUM_UNMAPPED; 567 pipeline_sp_thread_list[thread_id] = PIPELINE_SP_THREAD_EMPTY_TOKEN; 568 } 569 570 static enum ia_css_err pipeline_stage_create( 571 struct ia_css_pipeline_stage_desc *stage_desc, 572 struct ia_css_pipeline_stage **new_stage) 573 { 574 enum ia_css_err err = IA_CSS_SUCCESS; 575 struct ia_css_pipeline_stage *stage = NULL; 576 struct ia_css_binary *binary; 577 struct ia_css_frame *vf_frame; 578 struct ia_css_frame *out_frame[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; 579 const struct ia_css_fw_info *firmware; 580 unsigned int i; 581 582 /* Verify input parameters*/ 583 if (!(stage_desc->in_frame) && !(stage_desc->firmware) 584 && (stage_desc->binary) && !(stage_desc->binary->online)) { 585 err = IA_CSS_ERR_INTERNAL_ERROR; 586 goto ERR; 587 } 588 589 binary = stage_desc->binary; 590 firmware = stage_desc->firmware; 591 vf_frame = stage_desc->vf_frame; 592 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { 593 out_frame[i] = stage_desc->out_frame[i]; 594 } 595 596 stage = kvmalloc(sizeof(*stage), GFP_KERNEL); 597 if (!stage) { 598 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; 599 goto ERR; 600 } 601 memset(stage, 0, sizeof(*stage)); 602 603 if (firmware) { 604 stage->binary = NULL; 605 stage->binary_info = 606 (struct ia_css_binary_info *)&firmware->info.isp; 607 } else { 608 stage->binary = binary; 609 if (binary) 610 stage->binary_info = 611 (struct ia_css_binary_info *)binary->info; 612 else 613 stage->binary_info = NULL; 614 } 615 616 stage->firmware = firmware; 617 stage->sp_func = stage_desc->sp_func; 618 stage->max_input_width = stage_desc->max_input_width; 619 stage->mode = stage_desc->mode; 620 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) 621 stage->out_frame_allocated[i] = false; 622 stage->vf_frame_allocated = false; 623 stage->next = NULL; 624 sh_css_binary_args_reset(&stage->args); 625 626 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { 627 if (!(out_frame[i]) && (binary) 628 && (binary->out_frame_info[i].res.width)) { 629 err = ia_css_frame_allocate_from_info(&out_frame[i], 630 &binary->out_frame_info[i]); 631 if (err != IA_CSS_SUCCESS) 632 goto ERR; 633 stage->out_frame_allocated[i] = true; 634 } 635 } 636 /* VF frame is not needed in case of need_pp 637 However, the capture binary needs a vf frame to write to. 638 */ 639 if (!vf_frame) { 640 if ((binary && binary->vf_frame_info.res.width) || 641 (firmware && firmware->info.isp.sp.enable.vf_veceven) 642 ) { 643 err = ia_css_frame_allocate_from_info(&vf_frame, 644 &binary->vf_frame_info); 645 if (err != IA_CSS_SUCCESS) 646 goto ERR; 647 stage->vf_frame_allocated = true; 648 } 649 } else if (vf_frame && binary && binary->vf_frame_info.res.width 650 && !firmware) { 651 /* only mark as allocated if buffer pointer available */ 652 if (vf_frame->data != mmgr_NULL) 653 stage->vf_frame_allocated = true; 654 } 655 656 stage->args.in_frame = stage_desc->in_frame; 657 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) 658 stage->args.out_frame[i] = out_frame[i]; 659 stage->args.out_vf_frame = vf_frame; 660 *new_stage = stage; 661 return err; 662 ERR: 663 if (stage) 664 pipeline_stage_destroy(stage); 665 return err; 666 } 667 668 static void pipeline_init_defaults( 669 struct ia_css_pipeline *pipeline, 670 enum ia_css_pipe_id pipe_id, 671 unsigned int pipe_num, 672 unsigned int dvs_frame_delay) 673 { 674 unsigned int i; 675 676 pipeline->pipe_id = pipe_id; 677 pipeline->stages = NULL; 678 pipeline->stop_requested = false; 679 pipeline->current_stage = NULL; 680 pipeline->in_frame = DEFAULT_FRAME; 681 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { 682 pipeline->out_frame[i] = DEFAULT_FRAME; 683 pipeline->vf_frame[i] = DEFAULT_FRAME; 684 } 685 pipeline->num_execs = -1; 686 pipeline->acquire_isp_each_stage = true; 687 pipeline->pipe_num = (uint8_t)pipe_num; 688 pipeline->dvs_frame_delay = dvs_frame_delay; 689 } 690 691 static void ia_css_pipeline_set_zoom_stage(struct ia_css_pipeline *pipeline) 692 { 693 struct ia_css_pipeline_stage *stage = NULL; 694 enum ia_css_err err = IA_CSS_SUCCESS; 695 696 assert(pipeline); 697 if (pipeline->pipe_id == IA_CSS_PIPE_ID_PREVIEW) { 698 /* in preview pipeline, vf_pp stage should do zoom */ 699 err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_VF_PP, &stage); 700 if (err == IA_CSS_SUCCESS) 701 stage->enable_zoom = true; 702 } else if (pipeline->pipe_id == IA_CSS_PIPE_ID_CAPTURE) { 703 /* in capture pipeline, capture_pp stage should do zoom */ 704 err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_CAPTURE_PP, 705 &stage); 706 if (err == IA_CSS_SUCCESS) 707 stage->enable_zoom = true; 708 } else if (pipeline->pipe_id == IA_CSS_PIPE_ID_VIDEO) { 709 /* in video pipeline, video stage should do zoom */ 710 err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_VIDEO, &stage); 711 if (err == IA_CSS_SUCCESS) 712 stage->enable_zoom = true; 713 } else if (pipeline->pipe_id == IA_CSS_PIPE_ID_YUVPP) { 714 /* in yuvpp pipeline, first yuv_scaler stage should do zoom */ 715 err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_CAPTURE_PP, 716 &stage); 717 if (err == IA_CSS_SUCCESS) 718 stage->enable_zoom = true; 719 } 720 } 721 722 static void 723 ia_css_pipeline_configure_inout_port(struct ia_css_pipeline *me, 724 bool continuous) 725 { 726 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 727 "ia_css_pipeline_configure_inout_port() enter: pipe_id(%d) continuous(%d)\n", 728 me->pipe_id, continuous); 729 switch (me->pipe_id) { 730 case IA_CSS_PIPE_ID_PREVIEW: 731 case IA_CSS_PIPE_ID_VIDEO: 732 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 733 (uint8_t)SH_CSS_PORT_INPUT, 734 (uint8_t)(continuous ? SH_CSS_COPYSINK_TYPE : SH_CSS_HOST_TYPE), 1); 735 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 736 (uint8_t)SH_CSS_PORT_OUTPUT, 737 (uint8_t)SH_CSS_HOST_TYPE, 1); 738 break; 739 case IA_CSS_PIPE_ID_COPY: /*Copy pipe ports configured to "offline" mode*/ 740 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 741 (uint8_t)SH_CSS_PORT_INPUT, 742 (uint8_t)SH_CSS_HOST_TYPE, 1); 743 if (continuous) { 744 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 745 (uint8_t)SH_CSS_PORT_OUTPUT, 746 (uint8_t)SH_CSS_COPYSINK_TYPE, 1); 747 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 748 (uint8_t)SH_CSS_PORT_OUTPUT, 749 (uint8_t)SH_CSS_TAGGERSINK_TYPE, 1); 750 } else { 751 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 752 (uint8_t)SH_CSS_PORT_OUTPUT, 753 (uint8_t)SH_CSS_HOST_TYPE, 1); 754 } 755 break; 756 case IA_CSS_PIPE_ID_CAPTURE: 757 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 758 (uint8_t)SH_CSS_PORT_INPUT, 759 (uint8_t)(continuous ? SH_CSS_TAGGERSINK_TYPE : SH_CSS_HOST_TYPE), 760 1); 761 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 762 (uint8_t)SH_CSS_PORT_OUTPUT, 763 (uint8_t)SH_CSS_HOST_TYPE, 1); 764 break; 765 case IA_CSS_PIPE_ID_YUVPP: 766 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 767 (uint8_t)SH_CSS_PORT_INPUT, 768 (uint8_t)(SH_CSS_HOST_TYPE), 1); 769 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 770 (uint8_t)SH_CSS_PORT_OUTPUT, 771 (uint8_t)SH_CSS_HOST_TYPE, 1); 772 break; 773 case IA_CSS_PIPE_ID_ACC: 774 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 775 (uint8_t)SH_CSS_PORT_INPUT, 776 (uint8_t)SH_CSS_HOST_TYPE, 1); 777 SH_CSS_PIPE_PORT_CONFIG_SET(me->inout_port_config, 778 (uint8_t)SH_CSS_PORT_OUTPUT, 779 (uint8_t)SH_CSS_HOST_TYPE, 1); 780 break; 781 default: 782 break; 783 } 784 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 785 "ia_css_pipeline_configure_inout_port() leave: inout_port_config(%x)\n", 786 me->inout_port_config); 787 } 788