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