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