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 /* create metadata channel */ 193 if (isys_stream_descr->metadata.enable) { 194 rc = create_input_system_channel(isys_stream_descr, true, 195 &isys_stream->md_channel); 196 if (!rc) { 197 destroy_input_system_input_port(&isys_stream->input_port); 198 destroy_input_system_channel(&isys_stream->channel); 199 return false; 200 } 201 } 202 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 203 "ia_css_isys_stream_create() leave:\n"); 204 205 return true; 206 } 207 208 void ia_css_isys_stream_destroy( 209 ia_css_isys_stream_h isys_stream) 210 { 211 destroy_input_system_input_port(&isys_stream->input_port); 212 destroy_input_system_channel(&isys_stream->channel); 213 if (isys_stream->enable_metadata) { 214 /* Destroy metadata channel only if its allocated*/ 215 destroy_input_system_channel(&isys_stream->md_channel); 216 } 217 } 218 219 ia_css_isys_error_t ia_css_isys_stream_calculate_cfg( 220 ia_css_isys_stream_h isys_stream, 221 ia_css_isys_descr_t *isys_stream_descr, 222 ia_css_isys_stream_cfg_t *isys_stream_cfg) 223 { 224 ia_css_isys_error_t rc; 225 226 if (!isys_stream_cfg || 227 !isys_stream_descr || 228 !isys_stream) 229 return false; 230 231 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 232 "ia_css_isys_stream_calculate_cfg() enter:\n"); 233 234 rc = calculate_input_system_channel_cfg( 235 &isys_stream->channel, 236 &isys_stream->input_port, 237 isys_stream_descr, 238 &isys_stream_cfg->channel_cfg, 239 false); 240 if (!rc) 241 return false; 242 243 /* configure metadata channel */ 244 if (isys_stream_descr->metadata.enable) { 245 isys_stream_cfg->enable_metadata = true; 246 rc = calculate_input_system_channel_cfg( 247 &isys_stream->md_channel, 248 &isys_stream->input_port, 249 isys_stream_descr, 250 &isys_stream_cfg->md_channel_cfg, 251 true); 252 if (!rc) 253 return false; 254 } 255 256 rc = calculate_input_system_input_port_cfg( 257 &isys_stream->channel, 258 &isys_stream->input_port, 259 isys_stream_descr, 260 &isys_stream_cfg->input_port_cfg); 261 if (!rc) 262 return false; 263 264 isys_stream->valid = 1; 265 isys_stream_cfg->valid = 1; 266 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 267 "ia_css_isys_stream_calculate_cfg() leave:\n"); 268 return rc; 269 } 270 271 /* end of Public Methods */ 272 273 /************************************************** 274 * 275 * Private Methods 276 * 277 **************************************************/ 278 static bool create_input_system_channel( 279 isp2401_input_system_cfg_t *cfg, 280 bool metadata, 281 input_system_channel_t *me) 282 { 283 bool rc = true; 284 285 me->dma_id = ISYS2401_DMA0_ID; 286 287 switch (cfg->input_port_id) { 288 case INPUT_SYSTEM_CSI_PORT0_ID: 289 case INPUT_SYSTEM_PIXELGEN_PORT0_ID: 290 me->stream2mmio_id = STREAM2MMIO0_ID; 291 me->ibuf_ctrl_id = IBUF_CTRL0_ID; 292 break; 293 294 case INPUT_SYSTEM_CSI_PORT1_ID: 295 case INPUT_SYSTEM_PIXELGEN_PORT1_ID: 296 me->stream2mmio_id = STREAM2MMIO1_ID; 297 me->ibuf_ctrl_id = IBUF_CTRL1_ID; 298 break; 299 300 case INPUT_SYSTEM_CSI_PORT2_ID: 301 case INPUT_SYSTEM_PIXELGEN_PORT2_ID: 302 me->stream2mmio_id = STREAM2MMIO2_ID; 303 me->ibuf_ctrl_id = IBUF_CTRL2_ID; 304 break; 305 default: 306 rc = false; 307 break; 308 } 309 310 if (!rc) 311 return false; 312 313 if (!acquire_sid(me->stream2mmio_id, &me->stream2mmio_sid_id)) { 314 return false; 315 } 316 317 if (!acquire_ib_buffer( 318 metadata ? cfg->metadata.bits_per_pixel : 319 cfg->input_port_resolution.bits_per_pixel, 320 metadata ? cfg->metadata.pixels_per_line : 321 cfg->input_port_resolution.pixels_per_line, 322 metadata ? cfg->metadata.lines_per_frame : 323 cfg->input_port_resolution.lines_per_frame, 324 metadata ? cfg->metadata.align_req_in_bytes : 325 cfg->input_port_resolution.align_req_in_bytes, 326 cfg->online, 327 &me->ib_buffer)) { 328 release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id); 329 return false; 330 } 331 332 if (!acquire_dma_channel(me->dma_id, &me->dma_channel)) { 333 release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id); 334 release_ib_buffer(&me->ib_buffer); 335 return false; 336 } 337 338 return true; 339 } 340 341 static void destroy_input_system_channel( 342 input_system_channel_t *me) 343 { 344 release_sid(me->stream2mmio_id, 345 &me->stream2mmio_sid_id); 346 347 release_ib_buffer(&me->ib_buffer); 348 349 release_dma_channel(me->dma_id, &me->dma_channel); 350 } 351 352 static bool create_input_system_input_port( 353 isp2401_input_system_cfg_t *cfg, 354 input_system_input_port_t *me) 355 { 356 csi_mipi_packet_type_t packet_type; 357 bool rc = true; 358 359 switch (cfg->input_port_id) { 360 case INPUT_SYSTEM_CSI_PORT0_ID: 361 me->csi_rx.frontend_id = CSI_RX_FRONTEND0_ID; 362 me->csi_rx.backend_id = CSI_RX_BACKEND0_ID; 363 364 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); 365 me->csi_rx.packet_type = packet_type; 366 367 rc = acquire_be_lut_entry( 368 me->csi_rx.backend_id, 369 packet_type, 370 &me->csi_rx.backend_lut_entry); 371 break; 372 case INPUT_SYSTEM_PIXELGEN_PORT0_ID: 373 me->pixelgen.pixelgen_id = PIXELGEN0_ID; 374 break; 375 case INPUT_SYSTEM_CSI_PORT1_ID: 376 me->csi_rx.frontend_id = CSI_RX_FRONTEND1_ID; 377 me->csi_rx.backend_id = CSI_RX_BACKEND1_ID; 378 379 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); 380 me->csi_rx.packet_type = packet_type; 381 382 rc = acquire_be_lut_entry( 383 me->csi_rx.backend_id, 384 packet_type, 385 &me->csi_rx.backend_lut_entry); 386 break; 387 case INPUT_SYSTEM_PIXELGEN_PORT1_ID: 388 me->pixelgen.pixelgen_id = PIXELGEN1_ID; 389 390 break; 391 case INPUT_SYSTEM_CSI_PORT2_ID: 392 me->csi_rx.frontend_id = CSI_RX_FRONTEND2_ID; 393 me->csi_rx.backend_id = CSI_RX_BACKEND2_ID; 394 395 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type); 396 me->csi_rx.packet_type = packet_type; 397 398 rc = acquire_be_lut_entry( 399 me->csi_rx.backend_id, 400 packet_type, 401 &me->csi_rx.backend_lut_entry); 402 break; 403 case INPUT_SYSTEM_PIXELGEN_PORT2_ID: 404 me->pixelgen.pixelgen_id = PIXELGEN2_ID; 405 break; 406 default: 407 rc = false; 408 break; 409 } 410 411 me->source_type = cfg->mode; 412 413 /* for metadata */ 414 me->metadata.packet_type = CSI_MIPI_PACKET_TYPE_UNDEFINED; 415 if (rc && cfg->metadata.enable) { 416 me->metadata.packet_type = get_csi_mipi_packet_type( 417 cfg->metadata.fmt_type); 418 rc = acquire_be_lut_entry( 419 me->csi_rx.backend_id, 420 me->metadata.packet_type, 421 &me->metadata.backend_lut_entry); 422 } 423 424 return rc; 425 } 426 427 static void destroy_input_system_input_port( 428 input_system_input_port_t *me) 429 { 430 if (me->source_type == INPUT_SYSTEM_SOURCE_TYPE_SENSOR) { 431 release_be_lut_entry( 432 me->csi_rx.backend_id, 433 me->csi_rx.packet_type, 434 &me->csi_rx.backend_lut_entry); 435 } 436 437 if (me->metadata.packet_type != CSI_MIPI_PACKET_TYPE_UNDEFINED) { 438 /*Free the backend lut allocated for metadata*/ 439 release_be_lut_entry( 440 me->csi_rx.backend_id, 441 me->metadata.packet_type, 442 &me->metadata.backend_lut_entry); 443 } 444 } 445 446 static bool calculate_input_system_channel_cfg( 447 input_system_channel_t *channel, 448 input_system_input_port_t *input_port, 449 isp2401_input_system_cfg_t *isys_cfg, 450 input_system_channel_cfg_t *channel_cfg, 451 bool metadata) 452 { 453 bool rc; 454 455 rc = calculate_stream2mmio_cfg(isys_cfg, metadata, 456 &channel_cfg->stream2mmio_cfg); 457 if (!rc) 458 return false; 459 460 rc = calculate_ibuf_ctrl_cfg( 461 channel, 462 input_port, 463 isys_cfg, 464 &channel_cfg->ibuf_ctrl_cfg); 465 if (!rc) 466 return false; 467 if (metadata) 468 channel_cfg->ibuf_ctrl_cfg.stores_per_frame = 469 isys_cfg->metadata.lines_per_frame; 470 471 rc = calculate_isys2401_dma_cfg( 472 channel, 473 isys_cfg, 474 &channel_cfg->dma_cfg); 475 if (!rc) 476 return false; 477 478 rc = calculate_isys2401_dma_port_cfg( 479 isys_cfg, 480 false, 481 metadata, 482 &channel_cfg->dma_src_port_cfg); 483 if (!rc) 484 return false; 485 486 rc = calculate_isys2401_dma_port_cfg( 487 isys_cfg, 488 isys_cfg->raw_packed, 489 metadata, 490 &channel_cfg->dma_dest_port_cfg); 491 if (!rc) 492 return false; 493 494 return true; 495 } 496 497 static bool calculate_input_system_input_port_cfg( 498 input_system_channel_t *channel, 499 input_system_input_port_t *input_port, 500 isp2401_input_system_cfg_t *isys_cfg, 501 input_system_input_port_cfg_t *input_port_cfg) 502 { 503 bool rc; 504 505 switch (input_port->source_type) { 506 case INPUT_SYSTEM_SOURCE_TYPE_SENSOR: 507 rc = calculate_fe_cfg( 508 isys_cfg, 509 &input_port_cfg->csi_rx_cfg.frontend_cfg); 510 511 rc &= calculate_be_cfg( 512 input_port, 513 isys_cfg, 514 false, 515 &input_port_cfg->csi_rx_cfg.backend_cfg); 516 517 if (rc && isys_cfg->metadata.enable) 518 rc &= calculate_be_cfg(input_port, isys_cfg, true, 519 &input_port_cfg->csi_rx_cfg.md_backend_cfg); 520 break; 521 case INPUT_SYSTEM_SOURCE_TYPE_TPG: 522 rc = calculate_tpg_cfg( 523 channel, 524 input_port, 525 isys_cfg, 526 &input_port_cfg->pixelgen_cfg.tpg_cfg); 527 break; 528 case INPUT_SYSTEM_SOURCE_TYPE_PRBS: 529 rc = calculate_prbs_cfg( 530 channel, 531 input_port, 532 isys_cfg, 533 &input_port_cfg->pixelgen_cfg.prbs_cfg); 534 break; 535 default: 536 rc = false; 537 break; 538 } 539 540 return rc; 541 } 542 543 static bool acquire_sid( 544 stream2mmio_ID_t stream2mmio, 545 stream2mmio_sid_ID_t *sid) 546 { 547 return ia_css_isys_stream2mmio_sid_rmgr_acquire(stream2mmio, sid); 548 } 549 550 static void release_sid( 551 stream2mmio_ID_t stream2mmio, 552 stream2mmio_sid_ID_t *sid) 553 { 554 ia_css_isys_stream2mmio_sid_rmgr_release(stream2mmio, sid); 555 } 556 557 /* See also: ia_css_dma_configure_from_info() */ 558 static int32_t calculate_stride( 559 s32 bits_per_pixel, 560 s32 pixels_per_line, 561 bool raw_packed, 562 int32_t align_in_bytes) 563 { 564 s32 bytes_per_line; 565 s32 pixels_per_word; 566 s32 words_per_line; 567 s32 pixels_per_line_padded; 568 569 pixels_per_line_padded = CEIL_MUL(pixels_per_line, align_in_bytes); 570 571 if (!raw_packed) 572 bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); 573 574 pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; 575 words_per_line = ceil_div(pixels_per_line_padded, pixels_per_word); 576 bytes_per_line = HIVE_ISP_DDR_WORD_BYTES * words_per_line; 577 578 return bytes_per_line; 579 } 580 581 static bool acquire_ib_buffer( 582 s32 bits_per_pixel, 583 s32 pixels_per_line, 584 s32 lines_per_frame, 585 s32 align_in_bytes, 586 bool online, 587 isp2401_ib_buffer_t *buf) 588 { 589 buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false, 590 align_in_bytes); 591 if (online) 592 buf->lines = 4; /* use double buffering for online usecases */ 593 else 594 buf->lines = 2; 595 596 (void)(lines_per_frame); 597 return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines, 598 &buf->start_addr); 599 } 600 601 static void release_ib_buffer( 602 isp2401_ib_buffer_t *buf) 603 { 604 ia_css_isys_ibuf_rmgr_release(&buf->start_addr); 605 } 606 607 static bool acquire_dma_channel( 608 isys2401_dma_ID_t dma_id, 609 isys2401_dma_channel *channel) 610 { 611 return ia_css_isys_dma_channel_rmgr_acquire(dma_id, channel); 612 } 613 614 static void release_dma_channel( 615 isys2401_dma_ID_t dma_id, 616 isys2401_dma_channel *channel) 617 { 618 ia_css_isys_dma_channel_rmgr_release(dma_id, channel); 619 } 620 621 static bool acquire_be_lut_entry( 622 csi_rx_backend_ID_t backend, 623 csi_mipi_packet_type_t packet_type, 624 csi_rx_backend_lut_entry_t *entry) 625 { 626 return ia_css_isys_csi_rx_lut_rmgr_acquire(backend, packet_type, entry); 627 } 628 629 static void release_be_lut_entry( 630 csi_rx_backend_ID_t backend, 631 csi_mipi_packet_type_t packet_type, 632 csi_rx_backend_lut_entry_t *entry) 633 { 634 ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry); 635 } 636 637 static bool calculate_tpg_cfg( 638 input_system_channel_t *channel, 639 input_system_input_port_t *input_port, 640 isp2401_input_system_cfg_t *isys_cfg, 641 pixelgen_tpg_cfg_t *cfg) 642 { 643 memcpy(cfg, &isys_cfg->tpg_port_attr, sizeof(pixelgen_tpg_cfg_t)); 644 645 return true; 646 } 647 648 static bool calculate_prbs_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_prbs_cfg_t *cfg) 653 { 654 memcpy(cfg, &isys_cfg->prbs_port_attr, sizeof(pixelgen_prbs_cfg_t)); 655 656 return true; 657 } 658 659 static bool calculate_fe_cfg( 660 const isp2401_input_system_cfg_t *isys_cfg, 661 csi_rx_frontend_cfg_t *cfg) 662 { 663 cfg->active_lanes = isys_cfg->csi_port_attr.active_lanes; 664 return true; 665 } 666 667 static bool calculate_be_cfg( 668 const input_system_input_port_t *input_port, 669 const isp2401_input_system_cfg_t *isys_cfg, 670 bool metadata, 671 csi_rx_backend_cfg_t *cfg) 672 { 673 memcpy(&cfg->lut_entry, 674 metadata ? &input_port->metadata.backend_lut_entry : 675 &input_port->csi_rx.backend_lut_entry, 676 sizeof(csi_rx_backend_lut_entry_t)); 677 678 cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id; 679 if (metadata) { 680 cfg->csi_mipi_packet_type = get_csi_mipi_packet_type( 681 isys_cfg->metadata.fmt_type); 682 cfg->csi_mipi_cfg.comp_enable = false; 683 cfg->csi_mipi_cfg.data_type = isys_cfg->metadata.fmt_type; 684 } else { 685 cfg->csi_mipi_packet_type = get_csi_mipi_packet_type( 686 isys_cfg->csi_port_attr.fmt_type); 687 cfg->csi_mipi_cfg.data_type = isys_cfg->csi_port_attr.fmt_type; 688 cfg->csi_mipi_cfg.comp_enable = isys_cfg->csi_port_attr.comp_enable; 689 cfg->csi_mipi_cfg.comp_scheme = isys_cfg->csi_port_attr.comp_scheme; 690 cfg->csi_mipi_cfg.comp_predictor = isys_cfg->csi_port_attr.comp_predictor; 691 cfg->csi_mipi_cfg.comp_bit_idx = cfg->csi_mipi_cfg.data_type - 692 MIPI_FORMAT_CUSTOM0; 693 } 694 695 return true; 696 } 697 698 static bool calculate_stream2mmio_cfg( 699 const isp2401_input_system_cfg_t *isys_cfg, 700 bool metadata, 701 stream2mmio_cfg_t *cfg 702 ) 703 { 704 cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel : 705 isys_cfg->input_port_resolution.bits_per_pixel; 706 707 cfg->enable_blocking = 708 ((isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_TPG) || 709 (isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS)); 710 711 return true; 712 } 713 714 static bool calculate_ibuf_ctrl_cfg( 715 const input_system_channel_t *channel, 716 const input_system_input_port_t *input_port, 717 const isp2401_input_system_cfg_t *isys_cfg, 718 ibuf_ctrl_cfg_t *cfg) 719 { 720 const s32 bits_per_byte = 8; 721 s32 bits_per_pixel; 722 s32 bytes_per_pixel; 723 s32 left_padding; 724 725 (void)input_port; 726 727 bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; 728 bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte); 729 730 left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS) 731 * bytes_per_pixel; 732 733 cfg->online = isys_cfg->online; 734 735 cfg->dma_cfg.channel = channel->dma_channel; 736 cfg->dma_cfg.cmd = _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND; 737 738 cfg->dma_cfg.shift_returned_items = 0; 739 cfg->dma_cfg.elems_per_word_in_ibuf = 0; 740 cfg->dma_cfg.elems_per_word_in_dest = 0; 741 742 cfg->ib_buffer.start_addr = channel->ib_buffer.start_addr; 743 cfg->ib_buffer.stride = channel->ib_buffer.stride; 744 cfg->ib_buffer.lines = channel->ib_buffer.lines; 745 746 /* 747 #ifndef ISP2401 748 * zhengjie.lu@intel.com: 749 #endif 750 * "dest_buf_cfg" should be part of the input system output 751 * port configuration. 752 * 753 * TODO: move "dest_buf_cfg" to the input system output 754 * port configuration. 755 */ 756 757 /* input_buf addr only available in sched mode; 758 this buffer is allocated in isp, crun mode addr 759 can be passed by after ISP allocation */ 760 if (cfg->online) { 761 cfg->dest_buf_cfg.start_addr = ISP_INPUT_BUF_START_ADDR + left_padding; 762 cfg->dest_buf_cfg.stride = bytes_per_pixel 763 * isys_cfg->output_port_attr.max_isp_input_width; 764 cfg->dest_buf_cfg.lines = LINES_OF_ISP_INPUT_BUF; 765 } else if (isys_cfg->raw_packed) { 766 cfg->dest_buf_cfg.stride = calculate_stride(bits_per_pixel, 767 isys_cfg->input_port_resolution.pixels_per_line, 768 isys_cfg->raw_packed, 769 isys_cfg->input_port_resolution.align_req_in_bytes); 770 } else { 771 cfg->dest_buf_cfg.stride = channel->ib_buffer.stride; 772 } 773 774 /* 775 #ifndef ISP2401 776 * zhengjie.lu@intel.com: 777 #endif 778 * "items_per_store" is hard coded as "1", which is ONLY valid 779 * when the CSI-MIPI long packet is transferred. 780 * 781 * TODO: After the 1st stage of MERR+, make the proper solution to 782 * configure "items_per_store" so that it can also handle the CSI-MIPI 783 * short packet. 784 */ 785 cfg->items_per_store = 1; 786 787 cfg->stores_per_frame = isys_cfg->input_port_resolution.lines_per_frame; 788 789 cfg->stream2mmio_cfg.sync_cmd = _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME; 790 791 /* TODO: Define conditions as when to use store words vs store packets */ 792 cfg->stream2mmio_cfg.store_cmd = _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS; 793 794 return true; 795 } 796 797 static bool calculate_isys2401_dma_cfg( 798 const input_system_channel_t *channel, 799 const isp2401_input_system_cfg_t *isys_cfg, 800 isys2401_dma_cfg_t *cfg) 801 { 802 cfg->channel = channel->dma_channel; 803 804 /* only online/sensor mode goto vmem 805 offline/buffered_sensor, tpg and prbs will go to ddr */ 806 if (isys_cfg->online) 807 cfg->connection = isys2401_dma_ibuf_to_vmem_connection; 808 else 809 cfg->connection = isys2401_dma_ibuf_to_ddr_connection; 810 811 cfg->extension = isys2401_dma_zero_extension; 812 cfg->height = 1; 813 814 return true; 815 } 816 817 /* See also: ia_css_dma_configure_from_info() */ 818 static bool calculate_isys2401_dma_port_cfg( 819 const isp2401_input_system_cfg_t *isys_cfg, 820 bool raw_packed, 821 bool metadata, 822 isys2401_dma_port_cfg_t *cfg) 823 { 824 s32 bits_per_pixel; 825 s32 pixels_per_line; 826 s32 align_req_in_bytes; 827 828 /* TODO: Move metadata away from isys_cfg to application layer */ 829 if (metadata) { 830 bits_per_pixel = isys_cfg->metadata.bits_per_pixel; 831 pixels_per_line = isys_cfg->metadata.pixels_per_line; 832 align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes; 833 } else { 834 bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; 835 pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line; 836 align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes; 837 } 838 839 cfg->stride = calculate_stride(bits_per_pixel, pixels_per_line, raw_packed, 840 align_req_in_bytes); 841 842 if (!raw_packed) 843 bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); 844 845 cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; 846 cfg->cropping = 0; 847 cfg->width = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES); 848 849 return true; 850 } 851 852 static csi_mipi_packet_type_t get_csi_mipi_packet_type( 853 int32_t data_type) 854 { 855 csi_mipi_packet_type_t packet_type; 856 857 packet_type = CSI_MIPI_PACKET_TYPE_RESERVED; 858 859 if (data_type >= 0 && data_type <= MIPI_FORMAT_SHORT8) 860 packet_type = CSI_MIPI_PACKET_TYPE_SHORT; 861 862 if (data_type > MIPI_FORMAT_SHORT8 && data_type <= N_MIPI_FORMAT) 863 packet_type = CSI_MIPI_PACKET_TYPE_LONG; 864 865 return packet_type; 866 } 867 868 /* end of Private Methods */ 869 #endif 870