1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * camss-csid-4-7.c 4 * 5 * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module 6 * 7 * Copyright (C) 2020 Linaro Ltd. 8 */ 9 #include <linux/completion.h> 10 #include <linux/interrupt.h> 11 #include <linux/io.h> 12 #include <linux/kernel.h> 13 #include <linux/of.h> 14 15 #include "camss-csid.h" 16 #include "camss-csid-gen2.h" 17 #include "camss.h" 18 19 /* The CSID 2 IP-block is different from the others, 20 * and is of a bare-bones Lite version, with no PIX 21 * interface support. As a result of that it has an 22 * alternate register layout. 23 */ 24 #define IS_LITE (csid->id >= 2 ? 1 : 0) 25 26 #define CSID_HW_VERSION 0x0 27 #define HW_VERSION_STEPPING 0 28 #define HW_VERSION_REVISION 16 29 #define HW_VERSION_GENERATION 28 30 31 #define CSID_RST_STROBES 0x10 32 #define RST_STROBES 0 33 34 #define CSID_CSI2_RX_IRQ_STATUS 0x20 35 #define CSID_CSI2_RX_IRQ_MASK 0x24 36 #define CSID_CSI2_RX_IRQ_CLEAR 0x28 37 38 #define CSID_CSI2_RDIN_IRQ_STATUS(rdi) ((IS_LITE ? 0x30 : 0x40) \ 39 + 0x10 * (rdi)) 40 #define CSID_CSI2_RDIN_IRQ_MASK(rdi) ((IS_LITE ? 0x34 : 0x44) \ 41 + 0x10 * (rdi)) 42 #define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) ((IS_LITE ? 0x38 : 0x48) \ 43 + 0x10 * (rdi)) 44 #define CSID_CSI2_RDIN_IRQ_SET(rdi) ((IS_LITE ? 0x3C : 0x4C) \ 45 + 0x10 * (rdi)) 46 47 #define CSID_TOP_IRQ_STATUS 0x70 48 #define TOP_IRQ_STATUS_RESET_DONE 0 49 #define CSID_TOP_IRQ_MASK 0x74 50 #define CSID_TOP_IRQ_CLEAR 0x78 51 #define CSID_TOP_IRQ_SET 0x7C 52 #define CSID_IRQ_CMD 0x80 53 #define IRQ_CMD_CLEAR 0 54 #define IRQ_CMD_SET 4 55 56 #define CSID_CSI2_RX_CFG0 0x100 57 #define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0 58 #define CSI2_RX_CFG0_DL0_INPUT_SEL 4 59 #define CSI2_RX_CFG0_DL1_INPUT_SEL 8 60 #define CSI2_RX_CFG0_DL2_INPUT_SEL 12 61 #define CSI2_RX_CFG0_DL3_INPUT_SEL 16 62 #define CSI2_RX_CFG0_PHY_NUM_SEL 20 63 #define CSI2_RX_CFG0_PHY_TYPE_SEL 24 64 65 #define CSID_CSI2_RX_CFG1 0x104 66 #define CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN 0 67 #define CSI2_RX_CFG1_DE_SCRAMBLE_EN 1 68 #define CSI2_RX_CFG1_VC_MODE 2 69 #define CSI2_RX_CFG1_COMPLETE_STREAM_EN 4 70 #define CSI2_RX_CFG1_COMPLETE_STREAM_FRAME_TIMING 5 71 #define CSI2_RX_CFG1_MISR_EN 6 72 #define CSI2_RX_CFG1_CGC_MODE 7 73 #define CGC_MODE_DYNAMIC_GATING 0 74 #define CGC_MODE_ALWAYS_ON 1 75 76 #define CSID_RDI_CFG0(rdi) ((IS_LITE ? 0x200 : 0x300) \ 77 + 0x100 * (rdi)) 78 #define RDI_CFG0_BYTE_CNTR_EN 0 79 #define RDI_CFG0_FORMAT_MEASURE_EN 1 80 #define RDI_CFG0_TIMESTAMP_EN 2 81 #define RDI_CFG0_DROP_H_EN 3 82 #define RDI_CFG0_DROP_V_EN 4 83 #define RDI_CFG0_CROP_H_EN 5 84 #define RDI_CFG0_CROP_V_EN 6 85 #define RDI_CFG0_MISR_EN 7 86 #define RDI_CFG0_CGC_MODE 8 87 #define CGC_MODE_DYNAMIC 0 88 #define CGC_MODE_ALWAYS_ON 1 89 #define RDI_CFG0_PLAIN_ALIGNMENT 9 90 #define PLAIN_ALIGNMENT_LSB 0 91 #define PLAIN_ALIGNMENT_MSB 1 92 #define RDI_CFG0_PLAIN_FORMAT 10 93 #define RDI_CFG0_DECODE_FORMAT 12 94 #define RDI_CFG0_DATA_TYPE 16 95 #define RDI_CFG0_VIRTUAL_CHANNEL 22 96 #define RDI_CFG0_DT_ID 27 97 #define RDI_CFG0_EARLY_EOF_EN 29 98 #define RDI_CFG0_PACKING_FORMAT 30 99 #define RDI_CFG0_ENABLE 31 100 101 #define CSID_RDI_CFG1(rdi) ((IS_LITE ? 0x204 : 0x304)\ 102 + 0x100 * (rdi)) 103 #define RDI_CFG1_TIMESTAMP_STB_SEL 0 104 105 #define CSID_RDI_CTRL(rdi) ((IS_LITE ? 0x208 : 0x308)\ 106 + 0x100 * (rdi)) 107 #define RDI_CTRL_HALT_CMD 0 108 #define HALT_CMD_HALT_AT_FRAME_BOUNDARY 0 109 #define HALT_CMD_RESUME_AT_FRAME_BOUNDARY 1 110 #define RDI_CTRL_HALT_MODE 2 111 112 #define CSID_RDI_FRM_DROP_PATTERN(rdi) ((IS_LITE ? 0x20C : 0x30C)\ 113 + 0x100 * (rdi)) 114 #define CSID_RDI_FRM_DROP_PERIOD(rdi) ((IS_LITE ? 0x210 : 0x310)\ 115 + 0x100 * (rdi)) 116 #define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) ((IS_LITE ? 0x214 : 0x314)\ 117 + 0x100 * (rdi)) 118 #define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) ((IS_LITE ? 0x218 : 0x318)\ 119 + 0x100 * (rdi)) 120 #define CSID_RDI_RPP_PIX_DROP_PATTERN(rdi) ((IS_LITE ? 0x224 : 0x324)\ 121 + 0x100 * (rdi)) 122 #define CSID_RDI_RPP_PIX_DROP_PERIOD(rdi) ((IS_LITE ? 0x228 : 0x328)\ 123 + 0x100 * (rdi)) 124 #define CSID_RDI_RPP_LINE_DROP_PATTERN(rdi) ((IS_LITE ? 0x22C : 0x32C)\ 125 + 0x100 * (rdi)) 126 #define CSID_RDI_RPP_LINE_DROP_PERIOD(rdi) ((IS_LITE ? 0x230 : 0x330)\ 127 + 0x100 * (rdi)) 128 129 #define CSID_TPG_CTRL 0x600 130 #define TPG_CTRL_TEST_EN 0 131 #define TPG_CTRL_FS_PKT_EN 1 132 #define TPG_CTRL_FE_PKT_EN 2 133 #define TPG_CTRL_NUM_ACTIVE_LANES 4 134 #define TPG_CTRL_CYCLES_BETWEEN_PKTS 8 135 #define TPG_CTRL_NUM_TRAIL_BYTES 20 136 137 #define CSID_TPG_VC_CFG0 0x604 138 #define TPG_VC_CFG0_VC_NUM 0 139 #define TPG_VC_CFG0_NUM_ACTIVE_SLOTS 8 140 #define NUM_ACTIVE_SLOTS_0_ENABLED 0 141 #define NUM_ACTIVE_SLOTS_0_1_ENABLED 1 142 #define NUM_ACTIVE_SLOTS_0_1_2_ENABLED 2 143 #define NUM_ACTIVE_SLOTS_0_1_3_ENABLED 3 144 #define TPG_VC_CFG0_LINE_INTERLEAVING_MODE 10 145 #define INTELEAVING_MODE_INTERLEAVED 0 146 #define INTELEAVING_MODE_ONE_SHOT 1 147 #define TPG_VC_CFG0_NUM_FRAMES 16 148 149 #define CSID_TPG_VC_CFG1 0x608 150 #define TPG_VC_CFG1_H_BLANKING_COUNT 0 151 #define TPG_VC_CFG1_V_BLANKING_COUNT 12 152 #define TPG_VC_CFG1_V_BLANK_FRAME_WIDTH_SEL 24 153 154 #define CSID_TPG_LFSR_SEED 0x60C 155 156 #define CSID_TPG_DT_n_CFG_0(n) (0x610 + (n) * 0xC) 157 #define TPG_DT_n_CFG_0_FRAME_HEIGHT 0 158 #define TPG_DT_n_CFG_0_FRAME_WIDTH 16 159 160 #define CSID_TPG_DT_n_CFG_1(n) (0x614 + (n) * 0xC) 161 #define TPG_DT_n_CFG_1_DATA_TYPE 0 162 #define TPG_DT_n_CFG_1_ECC_XOR_MASK 8 163 #define TPG_DT_n_CFG_1_CRC_XOR_MASK 16 164 165 #define CSID_TPG_DT_n_CFG_2(n) (0x618 + (n) * 0xC) 166 #define TPG_DT_n_CFG_2_PAYLOAD_MODE 0 167 #define TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD 4 168 #define TPG_DT_n_CFG_2_ENCODE_FORMAT 16 169 170 #define CSID_TPG_COLOR_BARS_CFG 0x640 171 #define TPG_COLOR_BARS_CFG_UNICOLOR_BAR_EN 0 172 #define TPG_COLOR_BARS_CFG_UNICOLOR_BAR_SEL 4 173 #define TPG_COLOR_BARS_CFG_SPLIT_EN 5 174 #define TPG_COLOR_BARS_CFG_ROTATE_PERIOD 8 175 176 #define CSID_TPG_COLOR_BOX_CFG 0x644 177 #define TPG_COLOR_BOX_CFG_MODE 0 178 #define TPG_COLOR_BOX_PATTERN_SEL 2 179 180 static const struct csid_format csid_formats[] = { 181 { 182 MEDIA_BUS_FMT_UYVY8_2X8, 183 DATA_TYPE_YUV422_8BIT, 184 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 185 8, 186 2, 187 }, 188 { 189 MEDIA_BUS_FMT_VYUY8_2X8, 190 DATA_TYPE_YUV422_8BIT, 191 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 192 8, 193 2, 194 }, 195 { 196 MEDIA_BUS_FMT_YUYV8_2X8, 197 DATA_TYPE_YUV422_8BIT, 198 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 199 8, 200 2, 201 }, 202 { 203 MEDIA_BUS_FMT_YVYU8_2X8, 204 DATA_TYPE_YUV422_8BIT, 205 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 206 8, 207 2, 208 }, 209 { 210 MEDIA_BUS_FMT_SBGGR8_1X8, 211 DATA_TYPE_RAW_8BIT, 212 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 213 8, 214 1, 215 }, 216 { 217 MEDIA_BUS_FMT_SGBRG8_1X8, 218 DATA_TYPE_RAW_8BIT, 219 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 220 8, 221 1, 222 }, 223 { 224 MEDIA_BUS_FMT_SGRBG8_1X8, 225 DATA_TYPE_RAW_8BIT, 226 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 227 8, 228 1, 229 }, 230 { 231 MEDIA_BUS_FMT_SRGGB8_1X8, 232 DATA_TYPE_RAW_8BIT, 233 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 234 8, 235 1, 236 }, 237 { 238 MEDIA_BUS_FMT_SBGGR10_1X10, 239 DATA_TYPE_RAW_10BIT, 240 DECODE_FORMAT_UNCOMPRESSED_10_BIT, 241 10, 242 1, 243 }, 244 { 245 MEDIA_BUS_FMT_SGBRG10_1X10, 246 DATA_TYPE_RAW_10BIT, 247 DECODE_FORMAT_UNCOMPRESSED_10_BIT, 248 10, 249 1, 250 }, 251 { 252 MEDIA_BUS_FMT_SGRBG10_1X10, 253 DATA_TYPE_RAW_10BIT, 254 DECODE_FORMAT_UNCOMPRESSED_10_BIT, 255 10, 256 1, 257 }, 258 { 259 MEDIA_BUS_FMT_SRGGB10_1X10, 260 DATA_TYPE_RAW_10BIT, 261 DECODE_FORMAT_UNCOMPRESSED_10_BIT, 262 10, 263 1, 264 }, 265 { 266 MEDIA_BUS_FMT_Y8_1X8, 267 DATA_TYPE_RAW_8BIT, 268 DECODE_FORMAT_UNCOMPRESSED_8_BIT, 269 8, 270 1, 271 }, 272 { 273 MEDIA_BUS_FMT_Y10_1X10, 274 DATA_TYPE_RAW_10BIT, 275 DECODE_FORMAT_UNCOMPRESSED_10_BIT, 276 10, 277 1, 278 }, 279 { 280 MEDIA_BUS_FMT_SBGGR12_1X12, 281 DATA_TYPE_RAW_12BIT, 282 DECODE_FORMAT_UNCOMPRESSED_12_BIT, 283 12, 284 1, 285 }, 286 { 287 MEDIA_BUS_FMT_SGBRG12_1X12, 288 DATA_TYPE_RAW_12BIT, 289 DECODE_FORMAT_UNCOMPRESSED_12_BIT, 290 12, 291 1, 292 }, 293 { 294 MEDIA_BUS_FMT_SGRBG12_1X12, 295 DATA_TYPE_RAW_12BIT, 296 DECODE_FORMAT_UNCOMPRESSED_12_BIT, 297 12, 298 1, 299 }, 300 { 301 MEDIA_BUS_FMT_SRGGB12_1X12, 302 DATA_TYPE_RAW_12BIT, 303 DECODE_FORMAT_UNCOMPRESSED_12_BIT, 304 12, 305 1, 306 }, 307 { 308 MEDIA_BUS_FMT_SBGGR14_1X14, 309 DATA_TYPE_RAW_14BIT, 310 DECODE_FORMAT_UNCOMPRESSED_14_BIT, 311 14, 312 1, 313 }, 314 { 315 MEDIA_BUS_FMT_SGBRG14_1X14, 316 DATA_TYPE_RAW_14BIT, 317 DECODE_FORMAT_UNCOMPRESSED_14_BIT, 318 14, 319 1, 320 }, 321 { 322 MEDIA_BUS_FMT_SGRBG14_1X14, 323 DATA_TYPE_RAW_14BIT, 324 DECODE_FORMAT_UNCOMPRESSED_14_BIT, 325 14, 326 1, 327 }, 328 { 329 MEDIA_BUS_FMT_SRGGB14_1X14, 330 DATA_TYPE_RAW_14BIT, 331 DECODE_FORMAT_UNCOMPRESSED_14_BIT, 332 14, 333 1, 334 }, 335 }; 336 337 static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc) 338 { 339 struct csid_testgen_config *tg = &csid->testgen; 340 u32 val; 341 u32 phy_sel = 0; 342 u8 lane_cnt = csid->phy.lane_cnt; 343 /* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */ 344 struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc]; 345 const struct csid_format *format = csid_get_fmt_entry(csid->formats, csid->nformats, 346 input_format->code); 347 348 if (!lane_cnt) 349 lane_cnt = 4; 350 351 if (!tg->enabled) 352 phy_sel = csid->phy.csiphy_id; 353 354 if (enable) { 355 u8 dt_id = vc; 356 357 if (tg->enabled) { 358 /* Config Test Generator */ 359 vc = 0xa; 360 361 /* configure one DT, infinite frames */ 362 val = vc << TPG_VC_CFG0_VC_NUM; 363 val |= INTELEAVING_MODE_ONE_SHOT << TPG_VC_CFG0_LINE_INTERLEAVING_MODE; 364 val |= 0 << TPG_VC_CFG0_NUM_FRAMES; 365 writel_relaxed(val, csid->base + CSID_TPG_VC_CFG0); 366 367 val = 0x740 << TPG_VC_CFG1_H_BLANKING_COUNT; 368 val |= 0x3ff << TPG_VC_CFG1_V_BLANKING_COUNT; 369 writel_relaxed(val, csid->base + CSID_TPG_VC_CFG1); 370 371 writel_relaxed(0x12345678, csid->base + CSID_TPG_LFSR_SEED); 372 373 val = input_format->height & 0x1fff << TPG_DT_n_CFG_0_FRAME_HEIGHT; 374 val |= input_format->width & 0x1fff << TPG_DT_n_CFG_0_FRAME_WIDTH; 375 writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_0(0)); 376 377 val = format->data_type << TPG_DT_n_CFG_1_DATA_TYPE; 378 writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_1(0)); 379 380 val = tg->mode << TPG_DT_n_CFG_2_PAYLOAD_MODE; 381 val |= 0xBE << TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD; 382 val |= format->decode_format << TPG_DT_n_CFG_2_ENCODE_FORMAT; 383 writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_2(0)); 384 385 writel_relaxed(0, csid->base + CSID_TPG_COLOR_BARS_CFG); 386 387 writel_relaxed(0, csid->base + CSID_TPG_COLOR_BOX_CFG); 388 } 389 390 val = 1 << RDI_CFG0_BYTE_CNTR_EN; 391 val |= 1 << RDI_CFG0_FORMAT_MEASURE_EN; 392 val |= 1 << RDI_CFG0_TIMESTAMP_EN; 393 /* note: for non-RDI path, this should be format->decode_format */ 394 val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT; 395 val |= format->data_type << RDI_CFG0_DATA_TYPE; 396 val |= vc << RDI_CFG0_VIRTUAL_CHANNEL; 397 val |= dt_id << RDI_CFG0_DT_ID; 398 writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc)); 399 400 /* CSID_TIMESTAMP_STB_POST_IRQ */ 401 val = 2 << RDI_CFG1_TIMESTAMP_STB_SEL; 402 writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc)); 403 404 val = 1; 405 writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc)); 406 407 val = 0; 408 writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PATTERN(vc)); 409 410 val = 1; 411 writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc)); 412 413 val = 0; 414 writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc)); 415 416 val = 1; 417 writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(vc)); 418 419 val = 0; 420 writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(vc)); 421 422 val = 1; 423 writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(vc)); 424 425 val = 0; 426 writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(vc)); 427 428 val = 0; 429 writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc)); 430 431 val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc)); 432 val |= 1 << RDI_CFG0_ENABLE; 433 writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc)); 434 } 435 436 if (tg->enabled) { 437 val = enable << TPG_CTRL_TEST_EN; 438 val |= 1 << TPG_CTRL_FS_PKT_EN; 439 val |= 1 << TPG_CTRL_FE_PKT_EN; 440 val |= (lane_cnt - 1) << TPG_CTRL_NUM_ACTIVE_LANES; 441 val |= 0x64 << TPG_CTRL_CYCLES_BETWEEN_PKTS; 442 val |= 0xA << TPG_CTRL_NUM_TRAIL_BYTES; 443 writel_relaxed(val, csid->base + CSID_TPG_CTRL); 444 } 445 446 val = (lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES; 447 val |= csid->phy.lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL; 448 val |= phy_sel << CSI2_RX_CFG0_PHY_NUM_SEL; 449 writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0); 450 451 val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN; 452 val |= 1 << CSI2_RX_CFG1_MISR_EN; 453 writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1); 454 455 if (enable) 456 val = HALT_CMD_RESUME_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD; 457 else 458 val = HALT_CMD_HALT_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD; 459 writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc)); 460 } 461 462 static void csid_configure_stream(struct csid_device *csid, u8 enable) 463 { 464 u8 i; 465 /* Loop through all enabled VCs and configure stream for each */ 466 for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) 467 if (csid->phy.en_vc & BIT(i)) 468 __csid_configure_stream(csid, enable, i); 469 } 470 471 static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val) 472 { 473 if (val > 0 && val <= csid->testgen.nmodes) 474 csid->testgen.mode = val; 475 476 return 0; 477 } 478 479 /* 480 * csid_hw_version - CSID hardware version query 481 * @csid: CSID device 482 * 483 * Return HW version or error 484 */ 485 static u32 csid_hw_version(struct csid_device *csid) 486 { 487 u32 hw_version; 488 u32 hw_gen; 489 u32 hw_rev; 490 u32 hw_step; 491 492 hw_version = readl_relaxed(csid->base + CSID_HW_VERSION); 493 hw_gen = (hw_version >> HW_VERSION_GENERATION) & 0xF; 494 hw_rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF; 495 hw_step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF; 496 dev_dbg(csid->camss->dev, "CSID HW Version = %u.%u.%u\n", 497 hw_gen, hw_rev, hw_step); 498 499 return hw_version; 500 } 501 502 /* 503 * csid_isr - CSID module interrupt service routine 504 * @irq: Interrupt line 505 * @dev: CSID device 506 * 507 * Return IRQ_HANDLED on success 508 */ 509 static irqreturn_t csid_isr(int irq, void *dev) 510 { 511 struct csid_device *csid = dev; 512 u32 val; 513 u8 reset_done; 514 int i; 515 516 val = readl_relaxed(csid->base + CSID_TOP_IRQ_STATUS); 517 writel_relaxed(val, csid->base + CSID_TOP_IRQ_CLEAR); 518 reset_done = val & BIT(TOP_IRQ_STATUS_RESET_DONE); 519 520 val = readl_relaxed(csid->base + CSID_CSI2_RX_IRQ_STATUS); 521 writel_relaxed(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR); 522 523 /* Read and clear IRQ status for each enabled RDI channel */ 524 for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) 525 if (csid->phy.en_vc & BIT(i)) { 526 val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i)); 527 writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i)); 528 } 529 530 val = 1 << IRQ_CMD_CLEAR; 531 writel_relaxed(val, csid->base + CSID_IRQ_CMD); 532 533 if (reset_done) 534 complete(&csid->reset_complete); 535 536 return IRQ_HANDLED; 537 } 538 539 /* 540 * csid_reset - Trigger reset on CSID module and wait to complete 541 * @csid: CSID device 542 * 543 * Return 0 on success or a negative error code otherwise 544 */ 545 static int csid_reset(struct csid_device *csid) 546 { 547 unsigned long time; 548 u32 val; 549 550 reinit_completion(&csid->reset_complete); 551 552 writel_relaxed(1, csid->base + CSID_TOP_IRQ_CLEAR); 553 writel_relaxed(1, csid->base + CSID_IRQ_CMD); 554 writel_relaxed(1, csid->base + CSID_TOP_IRQ_MASK); 555 writel_relaxed(1, csid->base + CSID_IRQ_CMD); 556 557 /* preserve registers */ 558 val = 0x1e << RST_STROBES; 559 writel_relaxed(val, csid->base + CSID_RST_STROBES); 560 561 time = wait_for_completion_timeout(&csid->reset_complete, 562 msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); 563 if (!time) { 564 dev_err(csid->camss->dev, "CSID reset timeout\n"); 565 return -EIO; 566 } 567 568 return 0; 569 } 570 571 static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, 572 unsigned int match_format_idx, u32 match_code) 573 { 574 switch (sink_code) { 575 case MEDIA_BUS_FMT_SBGGR10_1X10: 576 { 577 u32 src_code[] = { 578 MEDIA_BUS_FMT_SBGGR10_1X10, 579 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 580 }; 581 582 return csid_find_code(src_code, ARRAY_SIZE(src_code), 583 match_format_idx, match_code); 584 } 585 case MEDIA_BUS_FMT_Y10_1X10: 586 { 587 u32 src_code[] = { 588 MEDIA_BUS_FMT_Y10_1X10, 589 MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 590 }; 591 592 return csid_find_code(src_code, ARRAY_SIZE(src_code), 593 match_format_idx, match_code); 594 } 595 default: 596 if (match_format_idx > 0) 597 return 0; 598 599 return sink_code; 600 } 601 } 602 603 static void csid_subdev_init(struct csid_device *csid) 604 { 605 csid->formats = csid_formats; 606 csid->nformats = ARRAY_SIZE(csid_formats); 607 csid->testgen.modes = csid_testgen_modes; 608 csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN2; 609 } 610 611 const struct csid_hw_ops csid_ops_gen2 = { 612 .configure_stream = csid_configure_stream, 613 .configure_testgen_pattern = csid_configure_testgen_pattern, 614 .hw_version = csid_hw_version, 615 .isr = csid_isr, 616 .reset = csid_reset, 617 .src_pad_code = csid_src_pad_code, 618 .subdev_init = csid_subdev_init, 619 }; 620