1 /* 2 * Support for Intel Camera Imaging ISP subsystem. 3 * Copyright (c) 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 "system_global.h" 16 17 #ifdef USE_INPUT_SYSTEM_VERSION_2401 18 19 #include "ia_css_isys.h" 20 #include "ia_css_debug.h" 21 #include "math_support.h" 22 #include "string_support.h" 23 #include "virtual_isys.h" 24 #include "isp.h" 25 #include "sh_css_defs.h" 26 27 /************************************************* 28 * 29 * Forwarded Declaration 30 * 31 *************************************************/ 32 33 static bool create_input_system_channel( 34 input_system_cfg_t *cfg, 35 bool metadata, 36 input_system_channel_t *channel); 37 38 static void destroy_input_system_channel( 39 input_system_channel_t *channel); 40 41 static bool create_input_system_input_port( 42 input_system_cfg_t *cfg, 43 input_system_input_port_t *input_port); 44 45 static void destroy_input_system_input_port( 46 input_system_input_port_t *input_port); 47 48 static bool calculate_input_system_channel_cfg( 49 input_system_channel_t *channel, 50 input_system_input_port_t *input_port, 51 input_system_cfg_t *isys_cfg, 52 input_system_channel_cfg_t *channel_cfg, 53 bool metadata); 54 55 static bool calculate_input_system_input_port_cfg( 56 input_system_channel_t *channel, 57 input_system_input_port_t *input_port, 58 input_system_cfg_t *isys_cfg, 59 input_system_input_port_cfg_t *input_port_cfg); 60 61 static bool acquire_sid( 62 stream2mmio_ID_t stream2mmio, 63 stream2mmio_sid_ID_t *sid); 64 65 static void release_sid( 66 stream2mmio_ID_t stream2mmio, 67 stream2mmio_sid_ID_t *sid); 68 69 static bool acquire_ib_buffer( 70 s32 bits_per_pixel, 71 s32 pixels_per_line, 72 s32 lines_per_frame, 73 s32 align_in_bytes, 74 bool online, 75 ib_buffer_t *buf); 76 77 static void release_ib_buffer( 78 ib_buffer_t *buf); 79 80 static bool acquire_dma_channel( 81 isys2401_dma_ID_t dma_id, 82 isys2401_dma_channel *channel); 83 84 static void release_dma_channel( 85 isys2401_dma_ID_t dma_id, 86 isys2401_dma_channel *channel); 87 88 static bool acquire_be_lut_entry( 89 csi_rx_backend_ID_t backend, 90 csi_mipi_packet_type_t packet_type, 91 csi_rx_backend_lut_entry_t *entry); 92 93 static void release_be_lut_entry( 94 csi_rx_backend_ID_t backend, 95 csi_mipi_packet_type_t packet_type, 96 csi_rx_backend_lut_entry_t *entry); 97 98 static bool calculate_tpg_cfg( 99 input_system_channel_t *channel, 100 input_system_input_port_t *input_port, 101 input_system_cfg_t *isys_cfg, 102 pixelgen_tpg_cfg_t *cfg); 103 104 static bool calculate_prbs_cfg( 105 input_system_channel_t *channel, 106 input_system_input_port_t *input_port, 107 input_system_cfg_t *isys_cfg, 108 pixelgen_prbs_cfg_t *cfg); 109 110 static bool calculate_fe_cfg( 111 const input_system_cfg_t *isys_cfg, 112 csi_rx_frontend_cfg_t *cfg); 113 114 static bool calculate_be_cfg( 115 const input_system_input_port_t *input_port, 116 const input_system_cfg_t *isys_cfg, 117 bool metadata, 118 csi_rx_backend_cfg_t *cfg); 119 120 static bool calculate_stream2mmio_cfg( 121 const input_system_cfg_t *isys_cfg, 122 bool metadata, 123 stream2mmio_cfg_t *cfg); 124 125 static bool calculate_ibuf_ctrl_cfg( 126 const input_system_channel_t *channel, 127 const input_system_input_port_t *input_port, 128 const input_system_cfg_t *isys_cfg, 129 ibuf_ctrl_cfg_t *cfg); 130 131 static bool calculate_isys2401_dma_cfg( 132 const input_system_channel_t *channel, 133 const input_system_cfg_t *isys_cfg, 134 isys2401_dma_cfg_t *cfg); 135 136 static bool calculate_isys2401_dma_port_cfg( 137 const input_system_cfg_t *isys_cfg, 138 bool raw_packed, 139 bool metadata, 140 isys2401_dma_port_cfg_t *cfg); 141 142 static csi_mipi_packet_type_t get_csi_mipi_packet_type( 143 int32_t data_type); 144 145 static int32_t calculate_stride( 146 s32 bits_per_pixel, 147 s32 pixels_per_line, 148 bool raw_packed, 149 int32_t align_in_bytes); 150 151 /* end of Forwarded Declaration */ 152 153 /************************************************** 154 * 155 * Public Methods 156 * 157 **************************************************/ 158 ia_css_isys_error_t ia_css_isys_stream_create( 159 ia_css_isys_descr_t *isys_stream_descr, 160 ia_css_isys_stream_h isys_stream, 161 uint32_t isys_stream_id) 162 { 163 ia_css_isys_error_t rc; 164 165 if (!isys_stream_descr || !isys_stream || 166 isys_stream_id >= SH_CSS_MAX_ISYS_CHANNEL_NODES) 167 return false; 168 169 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 170 "ia_css_isys_stream_create() enter:\n"); 171 172 /*Reset isys_stream to 0*/ 173 memset(isys_stream, 0, sizeof(*isys_stream)); 174 isys_stream->enable_metadata = isys_stream_descr->metadata.enable; 175 isys_stream->id = isys_stream_id; 176 177 isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id; 178 rc = create_input_system_input_port(isys_stream_descr, 179 &isys_stream->input_port); 180 if (rc == false) 181 return false; 182 183 rc = create_input_system_channel(isys_stream_descr, false, 184 &isys_stream->channel); 185 if (rc == false) { 186 destroy_input_system_input_port(&isys_stream->input_port); 187 return false; 188 } 189 190 #ifdef ISP2401 191 /* 192 * Early polling is required for timestamp accuracy in certain cause. 193 * The ISYS HW polling is started on 194 * ia_css_isys_stream_capture_indication() instead of 195 * ia_css_pipeline_sp_wait_for_isys_stream_N() as isp processing of 196 * capture takes longer than getting an ISYS frame 197 */ 198 isys_stream->polling_mode = isys_stream_descr->polling_mode; 199 200 #endif 201 /* create metadata channel */ 202 if (isys_stream_descr->metadata.enable) { 203 rc = create_input_system_channel(isys_stream_descr, true, 204 &isys_stream->md_channel); 205 if (rc == false) { 206 destroy_input_system_input_port(&isys_stream->input_port); 207 destroy_input_system_channel(&isys_stream->channel); 208 return false; 209 } 210 } 211 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 212 "ia_css_isys_stream_create() leave:\n"); 213 214 return true; 215 } 216 217 void ia_css_isys_stream_destroy( 218 ia_css_isys_stream_h isys_stream) 219 { 220 destroy_input_system_input_port(&isys_stream->input_port); 221 destroy_input_system_channel(&isys_stream->channel); 222 if (isys_stream->enable_metadata) { 223 /* Destroy metadata channel only if its allocated*/ 224 destroy_input_system_channel(&isys_stream->md_channel); 225 } 226 } 227 228 ia_css_isys_error_t ia_css_isys_stream_calculate_cfg( 229 ia_css_isys_stream_h isys_stream, 230 ia_css_isys_descr_t *isys_stream_descr, 231 ia_css_isys_stream_cfg_t *isys_stream_cfg) 232 { 233 ia_css_isys_error_t rc; 234 235 if (!isys_stream_cfg || 236 !isys_stream_descr || 237 !isys_stream) 238 return false; 239 240 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 241 "ia_css_isys_stream_calculate_cfg() enter:\n"); 242 243 rc = calculate_input_system_channel_cfg( 244 &isys_stream->channel, 245 &isys_stream->input_port, 246 isys_stream_descr, 247 &isys_stream_cfg->channel_cfg, 248 false); 249 if (rc == false) 250 return false; 251 252 /* configure metadata channel */ 253 if (isys_stream_descr->metadata.enable) { 254 isys_stream_cfg->enable_metadata = true; 255 rc = calculate_input_system_channel_cfg( 256 &isys_stream->md_channel, 257 &isys_stream->input_port, 258 isys_stream_descr, 259 &isys_stream_cfg->md_channel_cfg, 260 true); 261 if (rc == false) 262 return false; 263 } 264 265 rc = calculate_input_system_input_port_cfg( 266 &isys_stream->channel, 267 &isys_stream->input_port, 268 isys_stream_descr, 269 &isys_stream_cfg->input_port_cfg); 270 if (rc == false) 271 return false; 272 273 isys_stream->valid = 1; 274 isys_stream_cfg->valid = 1; 275 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 276 "ia_css_isys_stream_calculate_cfg() leave:\n"); 277 return rc; 278 } 279 280 /* end of Public Methods */ 281 282 /************************************************** 283 * 284 * Private Methods 285 * 286 **************************************************/ 287 static bool create_input_system_channel( 288 input_system_cfg_t *cfg, 289 bool metadata, 290 input_system_channel_t *me) 291 { 292 bool rc = true; 293 294 me->dma_id = ISYS2401_DMA0_ID; 295 296 switch (cfg->input_port_id) { 297 case INPUT_SYSTEM_CSI_PORT0_ID: 298 case INPUT_SYSTEM_PIXELGEN_PORT0_ID: 299 me->stream2mmio_id = STREAM2MMIO0_ID; 300 me->ibuf_ctrl_id = IBUF_CTRL0_ID; 301 break; 302 303 case INPUT_SYSTEM_CSI_PORT1_ID: 304 case INPUT_SYSTEM_PIXELGEN_PORT1_ID: 305 me->stream2mmio_id = STREAM2MMIO1_ID; 306 me->ibuf_ctrl_id = IBUF_CTRL1_ID; 307 break; 308 309 case INPUT_SYSTEM_CSI_PORT2_ID: 310 case INPUT_SYSTEM_PIXELGEN_PORT2_ID: 311 me->stream2mmio_id = STREAM2MMIO2_ID; 312 me->ibuf_ctrl_id = IBUF_CTRL2_ID; 313 break; 314 default: 315 rc = false; 316 break; 317 } 318 319 if (!rc) 320 return false; 321 322 if (!acquire_sid(me->stream2mmio_id, &me->stream2mmio_sid_id)) { 323 return false; 324 } 325 326 if (!acquire_ib_buffer( 327 metadata ? cfg->metadata.bits_per_pixel : 328 cfg->input_port_resolution.bits_per_pixel, 329 metadata ? cfg->metadata.pixels_per_line : 330 cfg->input_port_resolution.pixels_per_line, 331 metadata ? cfg->metadata.lines_per_frame : 332 cfg->input_port_resolution.lines_per_frame, 333 metadata ? cfg->metadata.align_req_in_bytes : 334 cfg->input_port_resolution.align_req_in_bytes, 335 cfg->online, 336 &me->ib_buffer)) { 337 release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id); 338 return false; 339 } 340 341 if (!acquire_dma_channel(me->dma_id, &me->dma_channel)) { 342 release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id); 343 release_ib_buffer(&me->ib_buffer); 344 return false; 345 } 346 347 return true; 348 } 349 350 static void destroy_input_system_channel( 351 input_system_channel_t *me) 352 { 353 release_sid(me->stream2mmio_id, 354 &me->stream2mmio_sid_id); 355 356 release_ib_buffer(&me->ib_buffer); 357 358 release_dma_channel(me->dma_id, &me->dma_channel); 359 } 360 361 static bool create_input_system_input_port( 362 input_system_cfg_t *cfg, 363 input_system_input_port_t *me) 364 { 365 csi_mipi_packet_type_t packet_type; 366 bool rc = true; 367 368 switch (cfg->input_port_id) { 369 case INPUT_SYSTEM_CSI_PORT0_ID: 370 me->csi_rx.frontend_id = CSI_RX_FRONTEND0_ID; 371 me->csi_rx.backend_id = CSI_RX_BACKEND0_ID; 372 373 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); 374 me->csi_rx.packet_type = packet_type; 375 376 rc = acquire_be_lut_entry( 377 me->csi_rx.backend_id, 378 packet_type, 379 &me->csi_rx.backend_lut_entry); 380 break; 381 case INPUT_SYSTEM_PIXELGEN_PORT0_ID: 382 me->pixelgen.pixelgen_id = PIXELGEN0_ID; 383 break; 384 case INPUT_SYSTEM_CSI_PORT1_ID: 385 me->csi_rx.frontend_id = CSI_RX_FRONTEND1_ID; 386 me->csi_rx.backend_id = CSI_RX_BACKEND1_ID; 387 388 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); 389 me->csi_rx.packet_type = packet_type; 390 391 rc = acquire_be_lut_entry( 392 me->csi_rx.backend_id, 393 packet_type, 394 &me->csi_rx.backend_lut_entry); 395 break; 396 case INPUT_SYSTEM_PIXELGEN_PORT1_ID: 397 me->pixelgen.pixelgen_id = PIXELGEN1_ID; 398 399 break; 400 case INPUT_SYSTEM_CSI_PORT2_ID: 401 me->csi_rx.frontend_id = CSI_RX_FRONTEND2_ID; 402 me->csi_rx.backend_id = CSI_RX_BACKEND2_ID; 403 404 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); 405 me->csi_rx.packet_type = packet_type; 406 407 rc = acquire_be_lut_entry( 408 me->csi_rx.backend_id, 409 packet_type, 410 &me->csi_rx.backend_lut_entry); 411 break; 412 case INPUT_SYSTEM_PIXELGEN_PORT2_ID: 413 me->pixelgen.pixelgen_id = PIXELGEN2_ID; 414 break; 415 default: 416 rc = false; 417 break; 418 } 419 420 me->source_type = cfg->mode; 421 422 /* for metadata */ 423 me->metadata.packet_type = CSI_MIPI_PACKET_TYPE_UNDEFINED; 424 if (rc && cfg->metadata.enable) { 425 me->metadata.packet_type = get_csi_mipi_packet_type( 426 cfg->metadata.fmt_type); 427 rc = acquire_be_lut_entry( 428 me->csi_rx.backend_id, 429 me->metadata.packet_type, 430 &me->metadata.backend_lut_entry); 431 } 432 433 return rc; 434 } 435 436 static void destroy_input_system_input_port( 437 input_system_input_port_t *me) 438 { 439 if (me->source_type == INPUT_SYSTEM_SOURCE_TYPE_SENSOR) { 440 release_be_lut_entry( 441 me->csi_rx.backend_id, 442 me->csi_rx.packet_type, 443 &me->csi_rx.backend_lut_entry); 444 } 445 446 if (me->metadata.packet_type != CSI_MIPI_PACKET_TYPE_UNDEFINED) { 447 /*Free the backend lut allocated for metadata*/ 448 release_be_lut_entry( 449 me->csi_rx.backend_id, 450 me->metadata.packet_type, 451 &me->metadata.backend_lut_entry); 452 } 453 } 454 455 static bool calculate_input_system_channel_cfg( 456 input_system_channel_t *channel, 457 input_system_input_port_t *input_port, 458 input_system_cfg_t *isys_cfg, 459 input_system_channel_cfg_t *channel_cfg, 460 bool metadata) 461 { 462 bool rc; 463 464 rc = calculate_stream2mmio_cfg(isys_cfg, metadata, 465 &channel_cfg->stream2mmio_cfg); 466 if (!rc) 467 return false; 468 469 rc = calculate_ibuf_ctrl_cfg( 470 channel, 471 input_port, 472 isys_cfg, 473 &channel_cfg->ibuf_ctrl_cfg); 474 if (!rc) 475 return false; 476 if (metadata) 477 channel_cfg->ibuf_ctrl_cfg.stores_per_frame = 478 isys_cfg->metadata.lines_per_frame; 479 480 rc = calculate_isys2401_dma_cfg( 481 channel, 482 isys_cfg, 483 &channel_cfg->dma_cfg); 484 if (!rc) 485 return false; 486 487 rc = calculate_isys2401_dma_port_cfg( 488 isys_cfg, 489 false, 490 metadata, 491 &channel_cfg->dma_src_port_cfg); 492 if (!rc) 493 return false; 494 495 rc = calculate_isys2401_dma_port_cfg( 496 isys_cfg, 497 isys_cfg->raw_packed, 498 metadata, 499 &channel_cfg->dma_dest_port_cfg); 500 if (!rc) 501 return false; 502 503 return true; 504 } 505 506 static bool calculate_input_system_input_port_cfg( 507 input_system_channel_t *channel, 508 input_system_input_port_t *input_port, 509 input_system_cfg_t *isys_cfg, 510 input_system_input_port_cfg_t *input_port_cfg) 511 { 512 bool rc; 513 514 switch (input_port->source_type) { 515 case INPUT_SYSTEM_SOURCE_TYPE_SENSOR: 516 rc = calculate_fe_cfg( 517 isys_cfg, 518 &input_port_cfg->csi_rx_cfg.frontend_cfg); 519 520 rc &= calculate_be_cfg( 521 input_port, 522 isys_cfg, 523 false, 524 &input_port_cfg->csi_rx_cfg.backend_cfg); 525 526 if (rc && isys_cfg->metadata.enable) 527 rc &= calculate_be_cfg(input_port, isys_cfg, true, 528 &input_port_cfg->csi_rx_cfg.md_backend_cfg); 529 break; 530 case INPUT_SYSTEM_SOURCE_TYPE_TPG: 531 rc = calculate_tpg_cfg( 532 channel, 533 input_port, 534 isys_cfg, 535 &input_port_cfg->pixelgen_cfg.tpg_cfg); 536 break; 537 case INPUT_SYSTEM_SOURCE_TYPE_PRBS: 538 rc = calculate_prbs_cfg( 539 channel, 540 input_port, 541 isys_cfg, 542 &input_port_cfg->pixelgen_cfg.prbs_cfg); 543 break; 544 default: 545 rc = false; 546 break; 547 } 548 549 return rc; 550 } 551 552 static bool acquire_sid( 553 stream2mmio_ID_t stream2mmio, 554 stream2mmio_sid_ID_t *sid) 555 { 556 return ia_css_isys_stream2mmio_sid_rmgr_acquire(stream2mmio, sid); 557 } 558 559 static void release_sid( 560 stream2mmio_ID_t stream2mmio, 561 stream2mmio_sid_ID_t *sid) 562 { 563 ia_css_isys_stream2mmio_sid_rmgr_release(stream2mmio, sid); 564 } 565 566 /* See also: ia_css_dma_configure_from_info() */ 567 static int32_t calculate_stride( 568 s32 bits_per_pixel, 569 s32 pixels_per_line, 570 bool raw_packed, 571 int32_t align_in_bytes) 572 { 573 s32 bytes_per_line; 574 s32 pixels_per_word; 575 s32 words_per_line; 576 s32 pixels_per_line_padded; 577 578 pixels_per_line_padded = CEIL_MUL(pixels_per_line, align_in_bytes); 579 580 if (!raw_packed) 581 bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); 582 583 pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; 584 words_per_line = ceil_div(pixels_per_line_padded, pixels_per_word); 585 bytes_per_line = HIVE_ISP_DDR_WORD_BYTES * words_per_line; 586 587 return bytes_per_line; 588 } 589 590 static bool acquire_ib_buffer( 591 s32 bits_per_pixel, 592 s32 pixels_per_line, 593 s32 lines_per_frame, 594 s32 align_in_bytes, 595 bool online, 596 ib_buffer_t *buf) 597 { 598 buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false, 599 align_in_bytes); 600 if (online) 601 buf->lines = 4; /* use double buffering for online usecases */ 602 else 603 buf->lines = 2; 604 605 (void)(lines_per_frame); 606 return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines, 607 &buf->start_addr); 608 } 609 610 static void release_ib_buffer( 611 ib_buffer_t *buf) 612 { 613 ia_css_isys_ibuf_rmgr_release(&buf->start_addr); 614 } 615 616 static bool acquire_dma_channel( 617 isys2401_dma_ID_t dma_id, 618 isys2401_dma_channel *channel) 619 { 620 return ia_css_isys_dma_channel_rmgr_acquire(dma_id, channel); 621 } 622 623 static void release_dma_channel( 624 isys2401_dma_ID_t dma_id, 625 isys2401_dma_channel *channel) 626 { 627 ia_css_isys_dma_channel_rmgr_release(dma_id, channel); 628 } 629 630 static bool acquire_be_lut_entry( 631 csi_rx_backend_ID_t backend, 632 csi_mipi_packet_type_t packet_type, 633 csi_rx_backend_lut_entry_t *entry) 634 { 635 return ia_css_isys_csi_rx_lut_rmgr_acquire(backend, packet_type, entry); 636 } 637 638 static void release_be_lut_entry( 639 csi_rx_backend_ID_t backend, 640 csi_mipi_packet_type_t packet_type, 641 csi_rx_backend_lut_entry_t *entry) 642 { 643 ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry); 644 } 645 646 static bool calculate_tpg_cfg( 647 input_system_channel_t *channel, 648 input_system_input_port_t *input_port, 649 input_system_cfg_t *isys_cfg, 650 pixelgen_tpg_cfg_t *cfg) 651 { 652 (void)channel; 653 (void)input_port; 654 655 memcpy_s( 656 (void *)cfg, 657 sizeof(pixelgen_tpg_cfg_t), 658 (void *)(&isys_cfg->tpg_port_attr), 659 sizeof(pixelgen_tpg_cfg_t)); 660 return true; 661 } 662 663 static bool calculate_prbs_cfg( 664 input_system_channel_t *channel, 665 input_system_input_port_t *input_port, 666 input_system_cfg_t *isys_cfg, 667 pixelgen_prbs_cfg_t *cfg) 668 { 669 (void)channel; 670 (void)input_port; 671 672 memcpy_s( 673 (void *)cfg, 674 sizeof(pixelgen_prbs_cfg_t), 675 (void *)(&isys_cfg->prbs_port_attr), 676 sizeof(pixelgen_prbs_cfg_t)); 677 return true; 678 } 679 680 static bool calculate_fe_cfg( 681 const input_system_cfg_t *isys_cfg, 682 csi_rx_frontend_cfg_t *cfg) 683 { 684 cfg->active_lanes = isys_cfg->csi_port_attr.active_lanes; 685 return true; 686 } 687 688 static bool calculate_be_cfg( 689 const input_system_input_port_t *input_port, 690 const input_system_cfg_t *isys_cfg, 691 bool metadata, 692 csi_rx_backend_cfg_t *cfg) 693 { 694 memcpy_s( 695 (void *)(&cfg->lut_entry), 696 sizeof(csi_rx_backend_lut_entry_t), 697 metadata ? (void *)(&input_port->metadata.backend_lut_entry) : 698 (void *)(&input_port->csi_rx.backend_lut_entry), 699 sizeof(csi_rx_backend_lut_entry_t)); 700 701 cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id; 702 if (metadata) { 703 cfg->csi_mipi_packet_type = get_csi_mipi_packet_type( 704 isys_cfg->metadata.fmt_type); 705 cfg->csi_mipi_cfg.comp_enable = false; 706 cfg->csi_mipi_cfg.data_type = isys_cfg->metadata.fmt_type; 707 } else { 708 cfg->csi_mipi_packet_type = get_csi_mipi_packet_type( 709 isys_cfg->csi_port_attr.fmt_type); 710 cfg->csi_mipi_cfg.data_type = isys_cfg->csi_port_attr.fmt_type; 711 cfg->csi_mipi_cfg.comp_enable = isys_cfg->csi_port_attr.comp_enable; 712 cfg->csi_mipi_cfg.comp_scheme = isys_cfg->csi_port_attr.comp_scheme; 713 cfg->csi_mipi_cfg.comp_predictor = isys_cfg->csi_port_attr.comp_predictor; 714 cfg->csi_mipi_cfg.comp_bit_idx = cfg->csi_mipi_cfg.data_type - 715 MIPI_FORMAT_CUSTOM0; 716 } 717 718 return true; 719 } 720 721 static bool calculate_stream2mmio_cfg( 722 const input_system_cfg_t *isys_cfg, 723 bool metadata, 724 stream2mmio_cfg_t *cfg 725 ) 726 { 727 cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel : 728 isys_cfg->input_port_resolution.bits_per_pixel; 729 730 cfg->enable_blocking = 731 ((isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_TPG) || 732 (isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS)); 733 734 return true; 735 } 736 737 static bool calculate_ibuf_ctrl_cfg( 738 const input_system_channel_t *channel, 739 const input_system_input_port_t *input_port, 740 const input_system_cfg_t *isys_cfg, 741 ibuf_ctrl_cfg_t *cfg) 742 { 743 const s32 bits_per_byte = 8; 744 s32 bits_per_pixel; 745 s32 bytes_per_pixel; 746 s32 left_padding; 747 748 (void)input_port; 749 750 bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; 751 bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte); 752 753 left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS) 754 * bytes_per_pixel; 755 756 cfg->online = isys_cfg->online; 757 758 cfg->dma_cfg.channel = channel->dma_channel; 759 cfg->dma_cfg.cmd = _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND; 760 761 cfg->dma_cfg.shift_returned_items = 0; 762 cfg->dma_cfg.elems_per_word_in_ibuf = 0; 763 cfg->dma_cfg.elems_per_word_in_dest = 0; 764 765 cfg->ib_buffer.start_addr = channel->ib_buffer.start_addr; 766 cfg->ib_buffer.stride = channel->ib_buffer.stride; 767 cfg->ib_buffer.lines = channel->ib_buffer.lines; 768 769 /* 770 #ifndef ISP2401 771 * zhengjie.lu@intel.com: 772 #endif 773 * "dest_buf_cfg" should be part of the input system output 774 * port configuration. 775 * 776 * TODO: move "dest_buf_cfg" to the input system output 777 * port configuration. 778 */ 779 780 /* input_buf addr only available in sched mode; 781 this buffer is allocated in isp, crun mode addr 782 can be passed by after ISP allocation */ 783 if (cfg->online) { 784 cfg->dest_buf_cfg.start_addr = ISP_INPUT_BUF_START_ADDR + left_padding; 785 cfg->dest_buf_cfg.stride = bytes_per_pixel 786 * isys_cfg->output_port_attr.max_isp_input_width; 787 cfg->dest_buf_cfg.lines = LINES_OF_ISP_INPUT_BUF; 788 } else if (isys_cfg->raw_packed) { 789 cfg->dest_buf_cfg.stride = calculate_stride(bits_per_pixel, 790 isys_cfg->input_port_resolution.pixels_per_line, 791 isys_cfg->raw_packed, 792 isys_cfg->input_port_resolution.align_req_in_bytes); 793 } else { 794 cfg->dest_buf_cfg.stride = channel->ib_buffer.stride; 795 } 796 797 /* 798 #ifndef ISP2401 799 * zhengjie.lu@intel.com: 800 #endif 801 * "items_per_store" is hard coded as "1", which is ONLY valid 802 * when the CSI-MIPI long packet is transferred. 803 * 804 * TODO: After the 1st stage of MERR+, make the proper solution to 805 * configure "items_per_store" so that it can also handle the CSI-MIPI 806 * short packet. 807 */ 808 cfg->items_per_store = 1; 809 810 cfg->stores_per_frame = isys_cfg->input_port_resolution.lines_per_frame; 811 812 cfg->stream2mmio_cfg.sync_cmd = _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME; 813 814 /* TODO: Define conditions as when to use store words vs store packets */ 815 cfg->stream2mmio_cfg.store_cmd = _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS; 816 817 return true; 818 } 819 820 static bool calculate_isys2401_dma_cfg( 821 const input_system_channel_t *channel, 822 const input_system_cfg_t *isys_cfg, 823 isys2401_dma_cfg_t *cfg) 824 { 825 cfg->channel = channel->dma_channel; 826 827 /* only online/sensor mode goto vmem 828 offline/buffered_sensor, tpg and prbs will go to ddr */ 829 if (isys_cfg->online) 830 cfg->connection = isys2401_dma_ibuf_to_vmem_connection; 831 else 832 cfg->connection = isys2401_dma_ibuf_to_ddr_connection; 833 834 cfg->extension = isys2401_dma_zero_extension; 835 cfg->height = 1; 836 837 return true; 838 } 839 840 /* See also: ia_css_dma_configure_from_info() */ 841 static bool calculate_isys2401_dma_port_cfg( 842 const input_system_cfg_t *isys_cfg, 843 bool raw_packed, 844 bool metadata, 845 isys2401_dma_port_cfg_t *cfg) 846 { 847 s32 bits_per_pixel; 848 s32 pixels_per_line; 849 s32 align_req_in_bytes; 850 851 /* TODO: Move metadata away from isys_cfg to application layer */ 852 if (metadata) { 853 bits_per_pixel = isys_cfg->metadata.bits_per_pixel; 854 pixels_per_line = isys_cfg->metadata.pixels_per_line; 855 align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes; 856 } else { 857 bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; 858 pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line; 859 align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes; 860 } 861 862 cfg->stride = calculate_stride(bits_per_pixel, pixels_per_line, raw_packed, 863 align_req_in_bytes); 864 865 if (!raw_packed) 866 bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); 867 868 cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; 869 cfg->cropping = 0; 870 cfg->width = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES); 871 872 return true; 873 } 874 875 static csi_mipi_packet_type_t get_csi_mipi_packet_type( 876 int32_t data_type) 877 { 878 csi_mipi_packet_type_t packet_type; 879 880 packet_type = CSI_MIPI_PACKET_TYPE_RESERVED; 881 882 if (data_type >= 0 && data_type <= MIPI_FORMAT_SHORT8) 883 packet_type = CSI_MIPI_PACKET_TYPE_SHORT; 884 885 if (data_type > MIPI_FORMAT_SHORT8 && data_type <= N_MIPI_FORMAT) 886 packet_type = CSI_MIPI_PACKET_TYPE_LONG; 887 888 return packet_type; 889 } 890 891 /* end of Private Methods */ 892 #endif 893