1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Support for Intel Camera Imaging ISP subsystem. 4 * Copyright (c) 2010 - 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#define __INLINE_INPUT_SYSTEM__ 17#include "input_system.h" 18#include "assert_support.h" 19#include "ia_css_isys.h" 20#include "ia_css_irq.h" 21#include "sh_css_internal.h" 22 23void ia_css_isys_rx_enable_all_interrupts(enum mipi_port_id port) 24{ 25 hrt_data bits = receiver_port_reg_load(RX0_ID, 26 port, 27 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX); 28 29 bits |= (1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT) | 30 (1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT) | 31 (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT) | 32 (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT) | 33 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT) | 34 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT) | 35 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT) | 36 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT) | 37 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT) | 38 /*(1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_NO_CORRECTION_BIT) | */ 39 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT) | 40 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT) | 41 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT) | 42 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT) | 43 (1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT) | 44 (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT); 45 /*(1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT); */ 46 47 receiver_port_reg_store(RX0_ID, 48 port, 49 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, bits); 50 51 /* 52 * The CSI is nested into the Iunit IRQ's 53 */ 54 ia_css_irq_enable(IA_CSS_IRQ_INFO_CSS_RECEIVER_ERROR, true); 55 56 return; 57} 58 59/* This function converts between the enum used on the CSS API and the 60 * internal DLI enum type. 61 * We do not use an array for this since we cannot use named array 62 * initializers in Windows. Without that there is no easy way to guarantee 63 * that the array values would be in the correct order. 64 * */ 65enum mipi_port_id ia_css_isys_port_to_mipi_port(enum mipi_port_id api_port) 66{ 67 /* In this module the validity of the inptu variable should 68 * have been checked already, so we do not check for erroneous 69 * values. */ 70 enum mipi_port_id port = MIPI_PORT0_ID; 71 72 if (api_port == MIPI_PORT1_ID) 73 port = MIPI_PORT1_ID; 74 else if (api_port == MIPI_PORT2_ID) 75 port = MIPI_PORT2_ID; 76 77 return port; 78} 79 80unsigned int ia_css_isys_rx_get_interrupt_reg(enum mipi_port_id port) 81{ 82 return receiver_port_reg_load(RX0_ID, 83 port, 84 _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX); 85} 86 87void ia_css_rx_get_irq_info(unsigned int *irq_infos) 88{ 89 ia_css_rx_port_get_irq_info(MIPI_PORT1_ID, irq_infos); 90} 91 92void ia_css_rx_port_get_irq_info(enum mipi_port_id api_port, 93 unsigned int *irq_infos) 94{ 95 enum mipi_port_id port = ia_css_isys_port_to_mipi_port(api_port); 96 97 ia_css_isys_rx_get_irq_info(port, irq_infos); 98} 99 100void ia_css_isys_rx_get_irq_info(enum mipi_port_id port, 101 unsigned int *irq_infos) 102{ 103 unsigned int bits; 104 105 assert(irq_infos); 106 bits = ia_css_isys_rx_get_interrupt_reg(port); 107 *irq_infos = ia_css_isys_rx_translate_irq_infos(bits); 108} 109 110/* Translate register bits to CSS API enum mask */ 111unsigned int ia_css_isys_rx_translate_irq_infos(unsigned int bits) 112{ 113 unsigned int infos = 0; 114 115 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT)) 116 infos |= IA_CSS_RX_IRQ_INFO_BUFFER_OVERRUN; 117 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT)) 118 infos |= IA_CSS_RX_IRQ_INFO_INIT_TIMEOUT; 119 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT)) 120 infos |= IA_CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE; 121 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT)) 122 infos |= IA_CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE; 123 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT)) 124 infos |= IA_CSS_RX_IRQ_INFO_ECC_CORRECTED; 125 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT)) 126 infos |= IA_CSS_RX_IRQ_INFO_ERR_SOT; 127 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT)) 128 infos |= IA_CSS_RX_IRQ_INFO_ERR_SOT_SYNC; 129 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT)) 130 infos |= IA_CSS_RX_IRQ_INFO_ERR_CONTROL; 131 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT)) 132 infos |= IA_CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE; 133 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT)) 134 infos |= IA_CSS_RX_IRQ_INFO_ERR_CRC; 135 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT)) 136 infos |= IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID; 137 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT)) 138 infos |= IA_CSS_RX_IRQ_INFO_ERR_FRAME_SYNC; 139 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT)) 140 infos |= IA_CSS_RX_IRQ_INFO_ERR_FRAME_DATA; 141 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT)) 142 infos |= IA_CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT; 143 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT)) 144 infos |= IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC; 145 if (bits & (1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT)) 146 infos |= IA_CSS_RX_IRQ_INFO_ERR_LINE_SYNC; 147 148 return infos; 149} 150 151void ia_css_rx_clear_irq_info(unsigned int irq_infos) 152{ 153 ia_css_rx_port_clear_irq_info(MIPI_PORT1_ID, irq_infos); 154} 155 156void ia_css_rx_port_clear_irq_info(enum mipi_port_id api_port, 157 unsigned int irq_infos) 158{ 159 enum mipi_port_id port = ia_css_isys_port_to_mipi_port(api_port); 160 161 ia_css_isys_rx_clear_irq_info(port, irq_infos); 162} 163 164void ia_css_isys_rx_clear_irq_info(enum mipi_port_id port, 165 unsigned int irq_infos) 166{ 167 hrt_data bits = receiver_port_reg_load(RX0_ID, 168 port, 169 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX); 170 171 /* MW: Why do we remap the receiver bitmap */ 172 if (irq_infos & IA_CSS_RX_IRQ_INFO_BUFFER_OVERRUN) 173 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_OVERRUN_BIT; 174 if (irq_infos & IA_CSS_RX_IRQ_INFO_INIT_TIMEOUT) 175 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_INIT_TIMEOUT_BIT; 176 if (irq_infos & IA_CSS_RX_IRQ_INFO_ENTER_SLEEP_MODE) 177 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_ENTRY_BIT; 178 if (irq_infos & IA_CSS_RX_IRQ_INFO_EXIT_SLEEP_MODE) 179 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_SLEEP_MODE_EXIT_BIT; 180 if (irq_infos & IA_CSS_RX_IRQ_INFO_ECC_CORRECTED) 181 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_CORRECTED_BIT; 182 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_SOT) 183 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_HS_BIT; 184 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_SOT_SYNC) 185 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_SOT_SYNC_HS_BIT; 186 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_CONTROL) 187 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_CONTROL_BIT; 188 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_ECC_DOUBLE) 189 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ECC_DOUBLE_BIT; 190 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_CRC) 191 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_CRC_BIT; 192 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ID) 193 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ID_BIT; 194 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_SYNC) 195 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_SYNC_BIT; 196 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_FRAME_DATA) 197 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_FRAME_DATA_BIT; 198 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_DATA_TIMEOUT) 199 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_DATA_TIMEOUT_BIT; 200 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_UNKNOWN_ESC) 201 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_ESCAPE_BIT; 202 if (irq_infos & IA_CSS_RX_IRQ_INFO_ERR_LINE_SYNC) 203 bits |= 1U << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT; 204 205 receiver_port_reg_store(RX0_ID, 206 port, 207 _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, bits); 208 209 return; 210} 211 212static int ia_css_isys_2400_set_fmt_type(enum atomisp_input_format input_format, 213 unsigned int *fmt_type) 214{ 215 switch (input_format) { 216 case ATOMISP_INPUT_FORMAT_RGB_888: 217 *fmt_type = MIPI_FORMAT_2400_RGB888; 218 break; 219 case ATOMISP_INPUT_FORMAT_RGB_555: 220 *fmt_type = MIPI_FORMAT_2400_RGB555; 221 break; 222 case ATOMISP_INPUT_FORMAT_RGB_444: 223 *fmt_type = MIPI_FORMAT_2400_RGB444; 224 break; 225 case ATOMISP_INPUT_FORMAT_RGB_565: 226 *fmt_type = MIPI_FORMAT_2400_RGB565; 227 break; 228 case ATOMISP_INPUT_FORMAT_RGB_666: 229 *fmt_type = MIPI_FORMAT_2400_RGB666; 230 break; 231 case ATOMISP_INPUT_FORMAT_RAW_8: 232 *fmt_type = MIPI_FORMAT_2400_RAW8; 233 break; 234 case ATOMISP_INPUT_FORMAT_RAW_10: 235 *fmt_type = MIPI_FORMAT_2400_RAW10; 236 break; 237 case ATOMISP_INPUT_FORMAT_RAW_6: 238 *fmt_type = MIPI_FORMAT_2400_RAW6; 239 break; 240 case ATOMISP_INPUT_FORMAT_RAW_7: 241 *fmt_type = MIPI_FORMAT_2400_RAW7; 242 break; 243 case ATOMISP_INPUT_FORMAT_RAW_12: 244 *fmt_type = MIPI_FORMAT_2400_RAW12; 245 break; 246 case ATOMISP_INPUT_FORMAT_RAW_14: 247 *fmt_type = MIPI_FORMAT_2400_RAW14; 248 break; 249 case ATOMISP_INPUT_FORMAT_YUV420_8: 250 *fmt_type = MIPI_FORMAT_2400_YUV420_8; 251 break; 252 case ATOMISP_INPUT_FORMAT_YUV420_10: 253 *fmt_type = MIPI_FORMAT_2400_YUV420_10; 254 break; 255 case ATOMISP_INPUT_FORMAT_YUV422_8: 256 *fmt_type = MIPI_FORMAT_2400_YUV422_8; 257 break; 258 case ATOMISP_INPUT_FORMAT_YUV422_10: 259 *fmt_type = MIPI_FORMAT_2400_YUV422_10; 260 break; 261 case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY: 262 *fmt_type = MIPI_FORMAT_2400_YUV420_8_LEGACY; 263 break; 264 case ATOMISP_INPUT_FORMAT_EMBEDDED: 265 *fmt_type = MIPI_FORMAT_2400_EMBEDDED; 266 break; 267 case ATOMISP_INPUT_FORMAT_RAW_16: 268 /* This is not specified by Arasan, so we use 269 * 17 for now. 270 */ 271 *fmt_type = MIPI_FORMAT_2400_RAW16; 272 break; 273 case ATOMISP_INPUT_FORMAT_BINARY_8: 274 *fmt_type = MIPI_FORMAT_2400_CUSTOM0; 275 break; 276 case ATOMISP_INPUT_FORMAT_YUV420_16: 277 case ATOMISP_INPUT_FORMAT_YUV422_16: 278 default: 279 return -EINVAL; 280 } 281 return 0; 282} 283 284static int ia_css_isys_2401_set_fmt_type(enum atomisp_input_format input_format, 285 unsigned int *fmt_type) 286{ 287 switch (input_format) { 288 case ATOMISP_INPUT_FORMAT_RGB_888: 289 *fmt_type = MIPI_FORMAT_2401_RGB888; 290 break; 291 case ATOMISP_INPUT_FORMAT_RGB_555: 292 *fmt_type = MIPI_FORMAT_2401_RGB555; 293 break; 294 case ATOMISP_INPUT_FORMAT_RGB_444: 295 *fmt_type = MIPI_FORMAT_2401_RGB444; 296 break; 297 case ATOMISP_INPUT_FORMAT_RGB_565: 298 *fmt_type = MIPI_FORMAT_2401_RGB565; 299 break; 300 case ATOMISP_INPUT_FORMAT_RGB_666: 301 *fmt_type = MIPI_FORMAT_2401_RGB666; 302 break; 303 case ATOMISP_INPUT_FORMAT_RAW_8: 304 *fmt_type = MIPI_FORMAT_2401_RAW8; 305 break; 306 case ATOMISP_INPUT_FORMAT_RAW_10: 307 *fmt_type = MIPI_FORMAT_2401_RAW10; 308 break; 309 case ATOMISP_INPUT_FORMAT_RAW_6: 310 *fmt_type = MIPI_FORMAT_2401_RAW6; 311 break; 312 case ATOMISP_INPUT_FORMAT_RAW_7: 313 *fmt_type = MIPI_FORMAT_2401_RAW7; 314 break; 315 case ATOMISP_INPUT_FORMAT_RAW_12: 316 *fmt_type = MIPI_FORMAT_2401_RAW12; 317 break; 318 case ATOMISP_INPUT_FORMAT_RAW_14: 319 *fmt_type = MIPI_FORMAT_2401_RAW14; 320 break; 321 case ATOMISP_INPUT_FORMAT_YUV420_8: 322 *fmt_type = MIPI_FORMAT_2401_YUV420_8; 323 break; 324 case ATOMISP_INPUT_FORMAT_YUV420_10: 325 *fmt_type = MIPI_FORMAT_2401_YUV420_10; 326 break; 327 case ATOMISP_INPUT_FORMAT_YUV422_8: 328 *fmt_type = MIPI_FORMAT_2401_YUV422_8; 329 break; 330 case ATOMISP_INPUT_FORMAT_YUV422_10: 331 *fmt_type = MIPI_FORMAT_2401_YUV422_10; 332 break; 333 case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY: 334 *fmt_type = MIPI_FORMAT_2401_YUV420_8_LEGACY; 335 break; 336 case ATOMISP_INPUT_FORMAT_EMBEDDED: 337 *fmt_type = MIPI_FORMAT_2401_EMBEDDED; 338 break; 339 case ATOMISP_INPUT_FORMAT_USER_DEF1: 340 *fmt_type = MIPI_FORMAT_2401_CUSTOM0; 341 break; 342 case ATOMISP_INPUT_FORMAT_USER_DEF2: 343 *fmt_type = MIPI_FORMAT_2401_CUSTOM1; 344 break; 345 case ATOMISP_INPUT_FORMAT_USER_DEF3: 346 *fmt_type = MIPI_FORMAT_2401_CUSTOM2; 347 break; 348 case ATOMISP_INPUT_FORMAT_USER_DEF4: 349 *fmt_type = MIPI_FORMAT_2401_CUSTOM3; 350 break; 351 case ATOMISP_INPUT_FORMAT_USER_DEF5: 352 *fmt_type = MIPI_FORMAT_2401_CUSTOM4; 353 break; 354 case ATOMISP_INPUT_FORMAT_USER_DEF6: 355 *fmt_type = MIPI_FORMAT_2401_CUSTOM5; 356 break; 357 case ATOMISP_INPUT_FORMAT_USER_DEF7: 358 *fmt_type = MIPI_FORMAT_2401_CUSTOM6; 359 break; 360 case ATOMISP_INPUT_FORMAT_USER_DEF8: 361 *fmt_type = MIPI_FORMAT_2401_CUSTOM7; 362 break; 363 364 case ATOMISP_INPUT_FORMAT_YUV420_16: 365 case ATOMISP_INPUT_FORMAT_YUV422_16: 366 default: 367 return -EINVAL; 368 } 369 return 0; 370} 371 372int ia_css_isys_convert_stream_format_to_mipi_format( 373 enum atomisp_input_format input_format, 374 mipi_predictor_t compression, 375 unsigned int *fmt_type) 376{ 377 assert(fmt_type); 378 /* 379 * Custom (user defined) modes. Used for compressed 380 * MIPI transfers 381 * 382 * Checkpatch thinks the indent before "if" is suspect 383 * I think the only suspect part is the missing "else" 384 * because of the return. 385 */ 386 if (compression != MIPI_PREDICTOR_NONE) { 387 switch (input_format) { 388 case ATOMISP_INPUT_FORMAT_RAW_6: 389 *fmt_type = 6; 390 break; 391 case ATOMISP_INPUT_FORMAT_RAW_7: 392 *fmt_type = 7; 393 break; 394 case ATOMISP_INPUT_FORMAT_RAW_8: 395 *fmt_type = 8; 396 break; 397 case ATOMISP_INPUT_FORMAT_RAW_10: 398 *fmt_type = 10; 399 break; 400 case ATOMISP_INPUT_FORMAT_RAW_12: 401 *fmt_type = 12; 402 break; 403 case ATOMISP_INPUT_FORMAT_RAW_14: 404 *fmt_type = 14; 405 break; 406 case ATOMISP_INPUT_FORMAT_RAW_16: 407 *fmt_type = 16; 408 break; 409 default: 410 return -EINVAL; 411 } 412 return 0; 413 } 414 /* 415 * This mapping comes from the Arasan CSS function spec 416 * (CSS_func_spec1.08_ahb_sep29_08.pdf). 417 * 418 * MW: For some reason the mapping is not 1-to-1 419 */ 420 if (IS_ISP2401) 421 return ia_css_isys_2401_set_fmt_type(input_format, fmt_type); 422 else 423 return ia_css_isys_2400_set_fmt_type(input_format, fmt_type); 424} 425 426static mipi_predictor_t sh_css_csi2_compression_type_2_mipi_predictor( 427 enum ia_css_csi2_compression_type type) 428{ 429 mipi_predictor_t predictor = MIPI_PREDICTOR_NONE; 430 431 switch (type) { 432 case IA_CSS_CSI2_COMPRESSION_TYPE_1: 433 predictor = MIPI_PREDICTOR_TYPE1 - 1; 434 break; 435 case IA_CSS_CSI2_COMPRESSION_TYPE_2: 436 predictor = MIPI_PREDICTOR_TYPE2 - 1; 437 break; 438 default: 439 break; 440 } 441 return predictor; 442} 443 444int ia_css_isys_convert_compressed_format( 445 struct ia_css_csi2_compression *comp, 446 struct isp2401_input_system_cfg_s *cfg) 447{ 448 int err = 0; 449 450 assert(comp); 451 assert(cfg); 452 453 if (comp->type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) { 454 /* compression register bit slicing 455 4 bit for each user defined data type 456 3 bit indicate compression scheme 457 000 No compression 458 001 10-6-10 459 010 10-7-10 460 011 10-8-10 461 100 12-6-12 462 101 12-6-12 463 100 12-7-12 464 110 12-8-12 465 1 bit indicate predictor 466 */ 467 if (comp->uncompressed_bits_per_pixel == UNCOMPRESSED_BITS_PER_PIXEL_10) { 468 switch (comp->compressed_bits_per_pixel) { 469 case COMPRESSED_BITS_PER_PIXEL_6: 470 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_6_10; 471 break; 472 case COMPRESSED_BITS_PER_PIXEL_7: 473 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_7_10; 474 break; 475 case COMPRESSED_BITS_PER_PIXEL_8: 476 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_10_8_10; 477 break; 478 default: 479 err = -EINVAL; 480 } 481 } else if (comp->uncompressed_bits_per_pixel == 482 UNCOMPRESSED_BITS_PER_PIXEL_12) { 483 switch (comp->compressed_bits_per_pixel) { 484 case COMPRESSED_BITS_PER_PIXEL_6: 485 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_6_12; 486 break; 487 case COMPRESSED_BITS_PER_PIXEL_7: 488 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_7_12; 489 break; 490 case COMPRESSED_BITS_PER_PIXEL_8: 491 cfg->csi_port_attr.comp_scheme = MIPI_COMPRESSOR_12_8_12; 492 break; 493 default: 494 err = -EINVAL; 495 } 496 } else 497 err = -EINVAL; 498 cfg->csi_port_attr.comp_predictor = 499 sh_css_csi2_compression_type_2_mipi_predictor(comp->type); 500 cfg->csi_port_attr.comp_enable = true; 501 } else /* No compression */ 502 cfg->csi_port_attr.comp_enable = false; 503 return err; 504} 505 506unsigned int ia_css_csi2_calculate_input_system_alignment( 507 enum atomisp_input_format fmt_type) 508{ 509 unsigned int memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES; 510 511 switch (fmt_type) { 512 case ATOMISP_INPUT_FORMAT_RAW_6: 513 case ATOMISP_INPUT_FORMAT_RAW_7: 514 case ATOMISP_INPUT_FORMAT_RAW_8: 515 case ATOMISP_INPUT_FORMAT_RAW_10: 516 case ATOMISP_INPUT_FORMAT_RAW_12: 517 case ATOMISP_INPUT_FORMAT_RAW_14: 518 memory_alignment_in_bytes = 2 * ISP_VEC_NELEMS; 519 break; 520 case ATOMISP_INPUT_FORMAT_YUV420_8: 521 case ATOMISP_INPUT_FORMAT_YUV422_8: 522 case ATOMISP_INPUT_FORMAT_USER_DEF1: 523 case ATOMISP_INPUT_FORMAT_USER_DEF2: 524 case ATOMISP_INPUT_FORMAT_USER_DEF3: 525 case ATOMISP_INPUT_FORMAT_USER_DEF4: 526 case ATOMISP_INPUT_FORMAT_USER_DEF5: 527 case ATOMISP_INPUT_FORMAT_USER_DEF6: 528 case ATOMISP_INPUT_FORMAT_USER_DEF7: 529 case ATOMISP_INPUT_FORMAT_USER_DEF8: 530 /* Planar YUV formats need to have all planes aligned, this means 531 * double the alignment for the Y plane if the horizontal decimation is 2. */ 532 memory_alignment_in_bytes = 2 * HIVE_ISP_DDR_WORD_BYTES; 533 break; 534 case ATOMISP_INPUT_FORMAT_EMBEDDED: 535 default: 536 memory_alignment_in_bytes = HIVE_ISP_DDR_WORD_BYTES; 537 break; 538 } 539 return memory_alignment_in_bytes; 540} 541 542 543static const mipi_lane_cfg_t MIPI_PORT_LANES[N_RX_MODE][N_MIPI_PORT_ID] = { 544 {MIPI_4LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG}, 545 {MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG}, 546 {MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG}, 547 {MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_0LANE_CFG}, 548 {MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_2LANE_CFG}, 549 {MIPI_3LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG}, 550 {MIPI_2LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG}, 551 {MIPI_1LANE_CFG, MIPI_1LANE_CFG, MIPI_1LANE_CFG} 552}; 553 554void ia_css_isys_rx_configure(const rx_cfg_t *config, 555 const enum ia_css_input_mode input_mode) 556{ 557 bool any_port_enabled = false; 558 enum mipi_port_id port; 559 560 if ((!config) 561 || (config->mode >= N_RX_MODE) 562 || (config->port >= N_MIPI_PORT_ID)) { 563 assert(0); 564 return; 565 } 566 for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) { 567 if (is_receiver_port_enabled(RX0_ID, port)) 568 any_port_enabled = true; 569 } 570 /* AM: Check whether this is a problem with multiple 571 * streams. MS: This is the case. */ 572 573 port = config->port; 574 receiver_port_enable(RX0_ID, port, false); 575 576 port = config->port; 577 578 /* AM: Check whether this is a problem with multiple streams. */ 579 if (MIPI_PORT_LANES[config->mode][port] != MIPI_0LANE_CFG) { 580 receiver_port_reg_store(RX0_ID, port, 581 _HRT_CSS_RECEIVER_FUNC_PROG_REG_IDX, 582 config->timeout); 583 receiver_port_reg_store(RX0_ID, port, 584 _HRT_CSS_RECEIVER_2400_INIT_COUNT_REG_IDX, 585 config->initcount); 586 receiver_port_reg_store(RX0_ID, port, 587 _HRT_CSS_RECEIVER_2400_SYNC_COUNT_REG_IDX, 588 config->synccount); 589 receiver_port_reg_store(RX0_ID, port, 590 _HRT_CSS_RECEIVER_2400_RX_COUNT_REG_IDX, 591 config->rxcount); 592 593 if (input_mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) { 594 /* MW: A bit of a hack, straight wiring of the capture 595 * units,assuming they are linearly enumerated. */ 596 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID, 597 GPREGS_UNIT0_ID, 598 HIVE_ISYS_GPREG_MULTICAST_A_IDX 599 + (unsigned int)port, 600 INPUT_SYSTEM_CSI_BACKEND); 601 /* MW: Like the integration test example we overwite, 602 * the GPREG_MUX register */ 603 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID, 604 GPREGS_UNIT0_ID, 605 HIVE_ISYS_GPREG_MUX_IDX, 606 (input_system_multiplex_t)port); 607 } else { 608 /* 609 * AM: A bit of a hack, wiring the input system. 610 */ 611 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID, 612 GPREGS_UNIT0_ID, 613 HIVE_ISYS_GPREG_MULTICAST_A_IDX 614 + (unsigned int)port, 615 INPUT_SYSTEM_INPUT_BUFFER); 616 input_system_sub_system_reg_store(INPUT_SYSTEM0_ID, 617 GPREGS_UNIT0_ID, 618 HIVE_ISYS_GPREG_MUX_IDX, 619 INPUT_SYSTEM_ACQUISITION_UNIT); 620 } 621 } 622 /* 623 * The 2ppc is shared for all ports, so we cannot 624 * disable->configure->enable individual ports 625 */ 626 /* AM: Check whether this is a problem with multiple streams. */ 627 /* MS: 2ppc should be a property per binary and should be 628 * enabled/disabled per binary. 629 * Currently it is implemented as a system wide setting due 630 * to effort and risks. */ 631 if (!any_port_enabled) { 632 receiver_reg_store(RX0_ID, 633 _HRT_CSS_RECEIVER_TWO_PIXEL_EN_REG_IDX, 634 config->is_two_ppc); 635 receiver_reg_store(RX0_ID, _HRT_CSS_RECEIVER_BE_TWO_PPC_REG_IDX, 636 config->is_two_ppc); 637 } 638 receiver_port_enable(RX0_ID, port, true); 639 /* TODO: JB: need to add the beneath used define to mizuchi */ 640 /* sh_css_sw_hive_isp_css_2400_system_20121224_0125\css 641 * \hrt\input_system_defs.h 642 * #define INPUT_SYSTEM_CSI_RECEIVER_SELECT_BACKENG 0X207 643 */ 644 /* TODO: need better name for define 645 * input_system_reg_store(INPUT_SYSTEM0_ID, 646 * INPUT_SYSTEM_CSI_RECEIVER_SELECT_BACKENG, 1); 647 */ 648 input_system_reg_store(INPUT_SYSTEM0_ID, 0x207, 1); 649 650 return; 651} 652 653void ia_css_isys_rx_disable(void) 654{ 655 enum mipi_port_id port; 656 657 for (port = (enum mipi_port_id)0; port < N_MIPI_PORT_ID; port++) { 658 receiver_port_reg_store(RX0_ID, port, 659 _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX, 660 false); 661 } 662 return; 663} 664