| .. | .. |
|---|
| 17 | 17 | #include <media/v4l2-mc.h> |
|---|
| 18 | 18 | #include <linux/workqueue.h> |
|---|
| 19 | 19 | #include <linux/rk-camera-module.h> |
|---|
| 20 | +#include <linux/rkcif-config.h> |
|---|
| 21 | +#include <linux/soc/rockchip/rockchip_thunderboot_service.h> |
|---|
| 20 | 22 | |
|---|
| 21 | 23 | #include "regs.h" |
|---|
| 22 | 24 | #include "version.h" |
|---|
| .. | .. |
|---|
| 24 | 26 | #include "mipi-csi2.h" |
|---|
| 25 | 27 | #include "hw.h" |
|---|
| 26 | 28 | #include "subdev-itf.h" |
|---|
| 29 | + |
|---|
| 30 | +#if IS_ENABLED(CONFIG_CPU_RV1106) |
|---|
| 31 | +#include <linux/soc/rockchip/rk_sdmmc.h> |
|---|
| 32 | +#endif |
|---|
| 27 | 33 | |
|---|
| 28 | 34 | #define CIF_DRIVER_NAME "rkcif" |
|---|
| 29 | 35 | #define CIF_VIDEODEVICE_NAME "stream_cif" |
|---|
| .. | .. |
|---|
| 46 | 52 | #define CIF_DVP_ID2_VDEV_NAME CIF_VIDEODEVICE_NAME "_dvp_id2" |
|---|
| 47 | 53 | #define CIF_DVP_ID3_VDEV_NAME CIF_VIDEODEVICE_NAME "_dvp_id3" |
|---|
| 48 | 54 | |
|---|
| 55 | +#define RKCIF_PLANE_Y 0 |
|---|
| 56 | +#define RKCIF_PLANE_CBCR 1 |
|---|
| 57 | + |
|---|
| 49 | 58 | /* |
|---|
| 50 | 59 | * RK1808 support 5 channel inputs simultaneously: |
|---|
| 51 | 60 | * dvp + 4 mipi virtual channels; |
|---|
| .. | .. |
|---|
| 61 | 70 | #define RKCIF_MAX_STREAM_DVP 4 |
|---|
| 62 | 71 | #define RKCIF_STREAM_DVP 4 |
|---|
| 63 | 72 | |
|---|
| 64 | | -#define RKCIF_MAX_DEV 8 |
|---|
| 65 | | - |
|---|
| 66 | 73 | #define RKCIF_MAX_SENSOR 2 |
|---|
| 67 | 74 | #define RKCIF_MAX_CSI_CHANNEL 4 |
|---|
| 68 | 75 | #define RKCIF_MAX_PIPELINE 4 |
|---|
| .. | .. |
|---|
| 71 | 78 | #define RKCIF_DEFAULT_HEIGHT 480 |
|---|
| 72 | 79 | #define RKCIF_FS_DETECTED_NUM 2 |
|---|
| 73 | 80 | |
|---|
| 81 | +#define RKCIF_MAX_INTERVAL_NS 5000000 |
|---|
| 74 | 82 | /* |
|---|
| 75 | 83 | * for HDR mode sync buf |
|---|
| 76 | 84 | */ |
|---|
| 77 | 85 | #define RDBK_MAX 3 |
|---|
| 86 | +#define RDBK_TOISP_MAX 2 |
|---|
| 78 | 87 | #define RDBK_L 0 |
|---|
| 79 | 88 | #define RDBK_M 1 |
|---|
| 80 | 89 | #define RDBK_S 2 |
|---|
| .. | .. |
|---|
| 85 | 94 | #define CROP_SRC_SENSOR_MASK (0x1 << 0) |
|---|
| 86 | 95 | #define CROP_SRC_USR_MASK (0x1 << 1) |
|---|
| 87 | 96 | |
|---|
| 97 | +/* |
|---|
| 98 | + * max wait time for stream stop |
|---|
| 99 | + */ |
|---|
| 100 | +#define RKCIF_STOP_MAX_WAIT_TIME_MS (500) |
|---|
| 101 | + |
|---|
| 102 | +#define RKCIF_SKIP_FRAME_MAX (16) |
|---|
| 103 | + |
|---|
| 88 | 104 | enum rkcif_workmode { |
|---|
| 89 | 105 | RKCIF_WORKMODE_ONEFRAME = 0x00, |
|---|
| 90 | 106 | RKCIF_WORKMODE_PINGPONG = 0x01, |
|---|
| 91 | 107 | RKCIF_WORKMODE_LINELOOP = 0x02 |
|---|
| 108 | +}; |
|---|
| 109 | + |
|---|
| 110 | +enum rkcif_stream_mode { |
|---|
| 111 | + RKCIF_STREAM_MODE_NONE = 0x0, |
|---|
| 112 | + RKCIF_STREAM_MODE_CAPTURE = 0x01, |
|---|
| 113 | + RKCIF_STREAM_MODE_TOISP = 0x02, |
|---|
| 114 | + RKCIF_STREAM_MODE_TOSCALE = 0x04, |
|---|
| 115 | + RKCIF_STREAM_MODE_TOISP_RDBK = 0x08, |
|---|
| 116 | + RKCIF_STREAM_MODE_ROCKIT = 0x10 |
|---|
| 92 | 117 | }; |
|---|
| 93 | 118 | |
|---|
| 94 | 119 | enum rkcif_yuvaddr_state { |
|---|
| .. | .. |
|---|
| 103 | 128 | RKCIF_STATE_RESET_IN_STREAMING, |
|---|
| 104 | 129 | }; |
|---|
| 105 | 130 | |
|---|
| 106 | | -enum host_type_t { |
|---|
| 107 | | - RK_CSI_RXHOST, |
|---|
| 108 | | - RK_DSI_RXHOST |
|---|
| 109 | | -}; |
|---|
| 110 | | - |
|---|
| 111 | 131 | enum rkcif_lvds_pad { |
|---|
| 112 | 132 | RKCIF_LVDS_PAD_SINK = 0x0, |
|---|
| 113 | 133 | RKCIF_LVDS_PAD_SRC_ID0, |
|---|
| 114 | 134 | RKCIF_LVDS_PAD_SRC_ID1, |
|---|
| 115 | 135 | RKCIF_LVDS_PAD_SRC_ID2, |
|---|
| 116 | 136 | RKCIF_LVDS_PAD_SRC_ID3, |
|---|
| 117 | | - RKCIF_LVDS_PAD_MAX |
|---|
| 137 | + RKCIF_LVDS_PAD_SCL_ID0, |
|---|
| 138 | + RKCIF_LVDS_PAD_SCL_ID1, |
|---|
| 139 | + RKCIF_LVDS_PAD_SCL_ID2, |
|---|
| 140 | + RKCIF_LVDS_PAD_SCL_ID3, |
|---|
| 141 | + RKCIF_LVDS_PAD_MAX, |
|---|
| 118 | 142 | }; |
|---|
| 119 | 143 | |
|---|
| 120 | 144 | enum rkcif_lvds_state { |
|---|
| .. | .. |
|---|
| 170 | 194 | u32 buff_addr[VIDEO_MAX_PLANES]; |
|---|
| 171 | 195 | void *vaddr[VIDEO_MAX_PLANES]; |
|---|
| 172 | 196 | }; |
|---|
| 197 | + struct dma_buf *dbuf; |
|---|
| 198 | + u64 fe_timestamp; |
|---|
| 173 | 199 | }; |
|---|
| 174 | 200 | |
|---|
| 175 | | -struct rkcif_dummy_buffer { |
|---|
| 176 | | - void *vaddr; |
|---|
| 177 | | - dma_addr_t dma_addr; |
|---|
| 178 | | - u32 size; |
|---|
| 201 | +struct rkcif_tools_buffer { |
|---|
| 202 | + struct vb2_v4l2_buffer *vb; |
|---|
| 203 | + struct rkisp_rx_buf *dbufs; |
|---|
| 204 | + struct list_head list; |
|---|
| 205 | + u32 frame_idx; |
|---|
| 206 | + u64 timestamp; |
|---|
| 207 | + int use_cnt; |
|---|
| 179 | 208 | }; |
|---|
| 180 | 209 | |
|---|
| 181 | 210 | extern int rkcif_debug; |
|---|
| .. | .. |
|---|
| 250 | 279 | unsigned char enable; /* capture enable */ |
|---|
| 251 | 280 | unsigned char vc; |
|---|
| 252 | 281 | unsigned char data_type; |
|---|
| 282 | + unsigned char data_bit; |
|---|
| 253 | 283 | unsigned char crop_en; |
|---|
| 254 | 284 | unsigned char cmd_mode_en; |
|---|
| 255 | 285 | unsigned char fmt_val; |
|---|
| 286 | + unsigned char csi_fmt_val; |
|---|
| 256 | 287 | unsigned int width; |
|---|
| 257 | 288 | unsigned int height; |
|---|
| 258 | 289 | unsigned int virtual_width; |
|---|
| 290 | + unsigned int left_virtual_width; |
|---|
| 259 | 291 | unsigned int crop_st_x; |
|---|
| 260 | 292 | unsigned int crop_st_y; |
|---|
| 261 | 293 | unsigned int dsi_input; |
|---|
| 262 | 294 | struct rkmodule_lvds_cfg lvds_cfg; |
|---|
| 295 | + struct rkmodule_capture_info capture_info; |
|---|
| 263 | 296 | }; |
|---|
| 264 | 297 | |
|---|
| 265 | 298 | struct rkcif_vdev_node { |
|---|
| .. | .. |
|---|
| 326 | 359 | struct rkcif_irq_stats { |
|---|
| 327 | 360 | u64 csi_overflow_cnt; |
|---|
| 328 | 361 | u64 csi_bwidth_lack_cnt; |
|---|
| 362 | + u64 csi_size_err_cnt; |
|---|
| 329 | 363 | u64 dvp_bus_err_cnt; |
|---|
| 330 | 364 | u64 dvp_overflow_cnt; |
|---|
| 331 | 365 | u64 dvp_line_err_cnt; |
|---|
| 332 | 366 | u64 dvp_pix_err_cnt; |
|---|
| 333 | | - u64 all_frm_end_cnt; |
|---|
| 367 | + u64 dvp_size_err_cnt; |
|---|
| 368 | + u64 dvp_bwidth_lack_cnt; |
|---|
| 369 | + u64 frm_end_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 370 | + u64 not_active_buf_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 371 | + u64 trig_simult_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 334 | 372 | u64 all_err_cnt; |
|---|
| 373 | +}; |
|---|
| 374 | + |
|---|
| 375 | +/* |
|---|
| 376 | + * the detecting mode of cif reset timer |
|---|
| 377 | + * related with dts property:rockchip,cif-monitor |
|---|
| 378 | + */ |
|---|
| 379 | +enum rkcif_monitor_mode { |
|---|
| 380 | + RKCIF_MONITOR_MODE_IDLE = 0x0, |
|---|
| 381 | + RKCIF_MONITOR_MODE_CONTINUE, |
|---|
| 382 | + RKCIF_MONITOR_MODE_TRIGGER, |
|---|
| 383 | + RKCIF_MONITOR_MODE_HOTPLUG, |
|---|
| 335 | 384 | }; |
|---|
| 336 | 385 | |
|---|
| 337 | 386 | /* |
|---|
| .. | .. |
|---|
| 348 | 397 | }; |
|---|
| 349 | 398 | |
|---|
| 350 | 399 | struct rkcif_timer { |
|---|
| 400 | + struct timer_list timer; |
|---|
| 401 | + spinlock_t timer_lock; |
|---|
| 351 | 402 | spinlock_t csi2_err_lock; |
|---|
| 352 | | - unsigned int last_buf_wakeup_cnt[RKCIF_MAX_CSI_CHANNEL]; |
|---|
| 403 | + unsigned long cycle; |
|---|
| 404 | + /* unit: us */ |
|---|
| 405 | + unsigned long line_end_cycle; |
|---|
| 406 | + unsigned int run_cnt; |
|---|
| 407 | + unsigned int max_run_cnt; |
|---|
| 408 | + unsigned int stop_index_of_run_cnt; |
|---|
| 409 | + unsigned int last_buf_wakeup_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 353 | 410 | unsigned long csi2_err_cnt_even; |
|---|
| 354 | 411 | unsigned long csi2_err_cnt_odd; |
|---|
| 412 | + unsigned int csi2_err_ref_cnt; |
|---|
| 355 | 413 | unsigned int csi2_err_fs_fe_cnt; |
|---|
| 356 | 414 | unsigned int csi2_err_fs_fe_detect_cnt; |
|---|
| 415 | + unsigned int frm_num_of_monitor_cycle; |
|---|
| 416 | + unsigned int triggered_frame_num; |
|---|
| 417 | + unsigned int vts; |
|---|
| 418 | + unsigned int raw_height; |
|---|
| 419 | + /* unit: ms */ |
|---|
| 420 | + unsigned int err_time_interval; |
|---|
| 357 | 421 | unsigned int csi2_err_triggered_cnt; |
|---|
| 358 | 422 | unsigned int notifer_called_cnt; |
|---|
| 423 | + unsigned long frame_end_cycle_us; |
|---|
| 359 | 424 | u64 csi2_first_err_timestamp; |
|---|
| 360 | 425 | bool is_triggered; |
|---|
| 361 | 426 | bool is_buf_stop_update; |
|---|
| 427 | + bool is_running; |
|---|
| 362 | 428 | bool is_csi2_err_occurred; |
|---|
| 429 | + bool has_been_init; |
|---|
| 430 | + bool is_ctrl_by_user; |
|---|
| 431 | + enum rkcif_monitor_mode monitor_mode; |
|---|
| 432 | + enum rkmodule_reset_src reset_src; |
|---|
| 363 | 433 | }; |
|---|
| 364 | 434 | |
|---|
| 365 | 435 | struct rkcif_extend_info { |
|---|
| 366 | 436 | struct v4l2_pix_format_mplane pixm; |
|---|
| 367 | 437 | bool is_extended; |
|---|
| 438 | +}; |
|---|
| 439 | + |
|---|
| 440 | +enum rkcif_capture_mode { |
|---|
| 441 | + RKCIF_TO_DDR = 0, |
|---|
| 442 | + RKCIF_TO_ISP_DDR, |
|---|
| 443 | + RKCIF_TO_ISP_DMA, |
|---|
| 444 | +}; |
|---|
| 445 | + |
|---|
| 446 | +/* |
|---|
| 447 | + * list: used for buf rotation |
|---|
| 448 | + * list_free: only used to release buf asynchronously |
|---|
| 449 | + */ |
|---|
| 450 | +struct rkcif_rx_buffer { |
|---|
| 451 | + int buf_idx; |
|---|
| 452 | + struct list_head list; |
|---|
| 453 | + struct list_head list_free; |
|---|
| 454 | + struct rkisp_rx_buf dbufs; |
|---|
| 455 | + struct rkcif_dummy_buffer dummy; |
|---|
| 456 | + struct rkisp_thunderboot_shmem shmem; |
|---|
| 457 | + u64 fe_timestamp; |
|---|
| 458 | +}; |
|---|
| 459 | + |
|---|
| 460 | +enum rkcif_dma_en_mode { |
|---|
| 461 | + RKCIF_DMAEN_BY_VICAP = 0x1, |
|---|
| 462 | + RKCIF_DMAEN_BY_ISP = 0x2, |
|---|
| 463 | + RKCIF_DMAEN_BY_VICAP_TO_ISP = 0x4, |
|---|
| 464 | + RKCIF_DMAEN_BY_ISP_TO_VICAP = 0x8, |
|---|
| 465 | + RKCIF_DMAEN_BY_ROCKIT = 0x10, |
|---|
| 466 | +}; |
|---|
| 467 | + |
|---|
| 468 | +struct rkcif_skip_info { |
|---|
| 469 | + u8 cap_m; |
|---|
| 470 | + u8 skip_n; |
|---|
| 471 | + bool skip_en; |
|---|
| 472 | + bool skip_to_en; |
|---|
| 473 | + bool skip_to_dis; |
|---|
| 474 | +}; |
|---|
| 475 | + |
|---|
| 476 | +struct rkcif_sync_cfg { |
|---|
| 477 | + u32 type; |
|---|
| 478 | + u32 group; |
|---|
| 479 | +}; |
|---|
| 480 | + |
|---|
| 481 | +enum rkcif_toisp_buf_update_state { |
|---|
| 482 | + RKCIF_TOISP_BUF_ROTATE, |
|---|
| 483 | + RKCIF_TOISP_BUF_THESAME, |
|---|
| 484 | + RKCIF_TOISP_BUF_LOSS, |
|---|
| 485 | +}; |
|---|
| 486 | + |
|---|
| 487 | +struct rkcif_toisp_buf_state { |
|---|
| 488 | + enum rkcif_toisp_buf_update_state state; |
|---|
| 489 | + int check_cnt; |
|---|
| 490 | + bool is_early_update; |
|---|
| 368 | 491 | }; |
|---|
| 369 | 492 | |
|---|
| 370 | 493 | /* |
|---|
| .. | .. |
|---|
| 394 | 517 | struct list_head buf_head; |
|---|
| 395 | 518 | struct rkcif_buffer *curr_buf; |
|---|
| 396 | 519 | struct rkcif_buffer *next_buf; |
|---|
| 520 | + struct rkcif_rx_buffer *curr_buf_toisp; |
|---|
| 521 | + struct rkcif_rx_buffer *next_buf_toisp; |
|---|
| 522 | + struct list_head rockit_buf_head; |
|---|
| 523 | + struct rkcif_buffer *curr_buf_rockit; |
|---|
| 524 | + struct rkcif_buffer *next_buf_rockit; |
|---|
| 397 | 525 | |
|---|
| 398 | 526 | spinlock_t vbq_lock; /* vfd lock */ |
|---|
| 399 | 527 | spinlock_t fps_lock; |
|---|
| .. | .. |
|---|
| 408 | 536 | struct rkcif_extend_info extend_line; |
|---|
| 409 | 537 | struct rkcif_readout_stats readout; |
|---|
| 410 | 538 | unsigned int fs_cnt_in_single_frame; |
|---|
| 539 | + unsigned int capture_mode; |
|---|
| 540 | + struct rkcif_scale_vdev *scale_vdev; |
|---|
| 541 | + struct rkcif_tools_vdev *tools_vdev; |
|---|
| 542 | + int dma_en; |
|---|
| 543 | + int to_en_dma; |
|---|
| 544 | + int to_stop_dma; |
|---|
| 545 | + int buf_owner; |
|---|
| 546 | + int buf_replace_cnt; |
|---|
| 547 | + struct list_head rx_buf_head_vicap; |
|---|
| 548 | + unsigned int cur_stream_mode; |
|---|
| 549 | + struct rkcif_rx_buffer rx_buf[RKISP_VICAP_BUF_CNT_MAX]; |
|---|
| 550 | + struct list_head rx_buf_head; |
|---|
| 551 | + int total_buf_num; |
|---|
| 552 | + int rx_buf_num; |
|---|
| 411 | 553 | u64 line_int_cnt; |
|---|
| 412 | | - int vc; |
|---|
| 413 | | - u64 streamon_timestamp; |
|---|
| 554 | + int lack_buf_cnt; |
|---|
| 555 | + unsigned int buf_wake_up_cnt; |
|---|
| 556 | + struct rkcif_skip_info skip_info; |
|---|
| 557 | + struct tasklet_struct vb_done_tasklet; |
|---|
| 558 | + struct list_head vb_done_list; |
|---|
| 559 | + int last_rx_buf_idx; |
|---|
| 560 | + int last_frame_idx; |
|---|
| 561 | + int new_fource_idx; |
|---|
| 562 | + atomic_t buf_cnt; |
|---|
| 563 | + struct completion stop_complete; |
|---|
| 564 | + struct rkcif_toisp_buf_state toisp_buf_state; |
|---|
| 565 | + u32 skip_frame; |
|---|
| 566 | + u32 cur_skip_frame; |
|---|
| 414 | 567 | bool stopping; |
|---|
| 415 | 568 | bool crop_enable; |
|---|
| 416 | 569 | bool crop_dyn_en; |
|---|
| .. | .. |
|---|
| 422 | 575 | bool is_can_stop; |
|---|
| 423 | 576 | bool is_buf_active; |
|---|
| 424 | 577 | bool is_high_align; |
|---|
| 578 | + bool to_en_scale; |
|---|
| 579 | + bool is_finish_stop_dma; |
|---|
| 580 | + bool is_in_vblank; |
|---|
| 581 | + bool is_change_toisp; |
|---|
| 582 | + bool is_stop_capture; |
|---|
| 583 | + bool is_wait_dma_stop; |
|---|
| 584 | + bool is_single_cap; |
|---|
| 585 | + bool is_wait_stop_complete; |
|---|
| 425 | 586 | }; |
|---|
| 426 | 587 | |
|---|
| 427 | 588 | struct rkcif_lvds_subdev { |
|---|
| .. | .. |
|---|
| 473 | 634 | return &vnode->buf_queue; |
|---|
| 474 | 635 | } |
|---|
| 475 | 636 | |
|---|
| 637 | +#define SCALE_DRIVER_NAME "rkcif_scale" |
|---|
| 638 | + |
|---|
| 639 | +#define RKCIF_SCALE_CH0 0 |
|---|
| 640 | +#define RKCIF_SCALE_CH1 1 |
|---|
| 641 | +#define RKCIF_SCALE_CH2 2 |
|---|
| 642 | +#define RKCIF_SCALE_CH3 3 |
|---|
| 643 | +#define RKCIF_MAX_SCALE_CH 4 |
|---|
| 644 | + |
|---|
| 645 | +#define CIF_SCALE_CH0_VDEV_NAME CIF_DRIVER_NAME "_scale_ch0" |
|---|
| 646 | +#define CIF_SCALE_CH1_VDEV_NAME CIF_DRIVER_NAME "_scale_ch1" |
|---|
| 647 | +#define CIF_SCALE_CH2_VDEV_NAME CIF_DRIVER_NAME "_scale_ch2" |
|---|
| 648 | +#define CIF_SCALE_CH3_VDEV_NAME CIF_DRIVER_NAME "_scale_ch3" |
|---|
| 649 | + |
|---|
| 650 | +#define RKCIF_SCALE_ENUM_SIZE_MAX 3 |
|---|
| 651 | +#define RKCIF_MAX_SDITF 4 |
|---|
| 652 | + |
|---|
| 653 | +enum scale_ch_sw { |
|---|
| 654 | + SCALE_MIPI0_ID0, |
|---|
| 655 | + SCALE_MIPI0_ID1, |
|---|
| 656 | + SCALE_MIPI0_ID2, |
|---|
| 657 | + SCALE_MIPI0_ID3, |
|---|
| 658 | + SCALE_MIPI1_ID0, |
|---|
| 659 | + SCALE_MIPI1_ID1, |
|---|
| 660 | + SCALE_MIPI1_ID2, |
|---|
| 661 | + SCALE_MIPI1_ID3, |
|---|
| 662 | + SCALE_MIPI2_ID0, |
|---|
| 663 | + SCALE_MIPI2_ID1, |
|---|
| 664 | + SCALE_MIPI2_ID2, |
|---|
| 665 | + SCALE_MIPI2_ID3, |
|---|
| 666 | + SCALE_MIPI3_ID0, |
|---|
| 667 | + SCALE_MIPI3_ID1, |
|---|
| 668 | + SCALE_MIPI3_ID2, |
|---|
| 669 | + SCALE_MIPI3_ID3, |
|---|
| 670 | + SCALE_MIPI4_ID0, |
|---|
| 671 | + SCALE_MIPI4_ID1, |
|---|
| 672 | + SCALE_MIPI4_ID2, |
|---|
| 673 | + SCALE_MIPI4_ID3, |
|---|
| 674 | + SCALE_MIPI5_ID0, |
|---|
| 675 | + SCALE_MIPI5_ID1, |
|---|
| 676 | + SCALE_MIPI5_ID2, |
|---|
| 677 | + SCALE_MIPI5_ID3, |
|---|
| 678 | + SCALE_DVP, |
|---|
| 679 | + SCALE_CH_MAX, |
|---|
| 680 | +}; |
|---|
| 681 | + |
|---|
| 682 | +enum scale_mode { |
|---|
| 683 | + SCALE_8TIMES, |
|---|
| 684 | + SCALE_16TIMES, |
|---|
| 685 | + SCALE_32TIMES, |
|---|
| 686 | +}; |
|---|
| 687 | + |
|---|
| 688 | +struct rkcif_scale_ch_info { |
|---|
| 689 | + u32 width; |
|---|
| 690 | + u32 height; |
|---|
| 691 | + u32 vir_width; |
|---|
| 692 | +}; |
|---|
| 693 | + |
|---|
| 694 | +struct rkcif_scale_src_res { |
|---|
| 695 | + u32 width; |
|---|
| 696 | + u32 height; |
|---|
| 697 | +}; |
|---|
| 698 | + |
|---|
| 699 | +/* |
|---|
| 700 | + * struct rkcif_scale_vdev - CIF Capture device |
|---|
| 701 | + * |
|---|
| 702 | + * @irq_lock: buffer queue lock |
|---|
| 703 | + * @stat: stats buffer list |
|---|
| 704 | + * @readout_wq: workqueue for statistics information read |
|---|
| 705 | + */ |
|---|
| 706 | +struct rkcif_scale_vdev { |
|---|
| 707 | + unsigned int ch:3; |
|---|
| 708 | + struct rkcif_device *cifdev; |
|---|
| 709 | + struct rkcif_vdev_node vnode; |
|---|
| 710 | + struct rkcif_stream *stream; |
|---|
| 711 | + struct list_head buf_head; |
|---|
| 712 | + spinlock_t vbq_lock; /* vfd lock */ |
|---|
| 713 | + wait_queue_head_t wq_stopped; |
|---|
| 714 | + struct v4l2_pix_format_mplane pixm; |
|---|
| 715 | + const struct cif_output_fmt *scale_out_fmt; |
|---|
| 716 | + struct rkcif_scale_ch_info ch_info; |
|---|
| 717 | + struct rkcif_scale_src_res src_res; |
|---|
| 718 | + struct rkcif_buffer *curr_buf; |
|---|
| 719 | + struct rkcif_buffer *next_buf; |
|---|
| 720 | + struct bayer_blc blc; |
|---|
| 721 | + enum rkcif_state state; |
|---|
| 722 | + unsigned int ch_src; |
|---|
| 723 | + unsigned int scale_mode; |
|---|
| 724 | + int frame_phase; |
|---|
| 725 | + unsigned int frame_idx; |
|---|
| 726 | + bool stopping; |
|---|
| 727 | +}; |
|---|
| 728 | + |
|---|
| 729 | +static inline |
|---|
| 730 | +struct rkcif_scale_vdev *to_rkcif_scale_vdev(struct rkcif_vdev_node *vnode) |
|---|
| 731 | +{ |
|---|
| 732 | + return container_of(vnode, struct rkcif_scale_vdev, vnode); |
|---|
| 733 | +} |
|---|
| 734 | + |
|---|
| 735 | +void rkcif_init_scale_vdev(struct rkcif_device *cif_dev, u32 ch); |
|---|
| 736 | +int rkcif_register_scale_vdevs(struct rkcif_device *cif_dev, |
|---|
| 737 | + int stream_num, |
|---|
| 738 | + bool is_multi_input); |
|---|
| 739 | +void rkcif_unregister_scale_vdevs(struct rkcif_device *cif_dev, |
|---|
| 740 | + int stream_num); |
|---|
| 741 | + |
|---|
| 742 | +#define TOOLS_DRIVER_NAME "rkcif_tools" |
|---|
| 743 | + |
|---|
| 744 | +#define RKCIF_TOOLS_CH0 0 |
|---|
| 745 | +#define RKCIF_TOOLS_CH1 1 |
|---|
| 746 | +#define RKCIF_TOOLS_CH2 2 |
|---|
| 747 | +#define RKCIF_MAX_TOOLS_CH 3 |
|---|
| 748 | + |
|---|
| 749 | +#define CIF_TOOLS_CH0_VDEV_NAME CIF_DRIVER_NAME "_tools_id0" |
|---|
| 750 | +#define CIF_TOOLS_CH1_VDEV_NAME CIF_DRIVER_NAME "_tools_id1" |
|---|
| 751 | +#define CIF_TOOLS_CH2_VDEV_NAME CIF_DRIVER_NAME "_tools_id2" |
|---|
| 752 | + |
|---|
| 753 | +/* |
|---|
| 754 | + * struct rkcif_tools_vdev - CIF Capture device |
|---|
| 755 | + * |
|---|
| 756 | + * @irq_lock: buffer queue lock |
|---|
| 757 | + * @stat: stats buffer list |
|---|
| 758 | + * @readout_wq: workqueue for statistics information read |
|---|
| 759 | + */ |
|---|
| 760 | +struct rkcif_tools_vdev { |
|---|
| 761 | + unsigned int ch:3; |
|---|
| 762 | + struct rkcif_device *cifdev; |
|---|
| 763 | + struct rkcif_vdev_node vnode; |
|---|
| 764 | + struct rkcif_stream *stream; |
|---|
| 765 | + struct list_head buf_head; |
|---|
| 766 | + struct list_head buf_done_head; |
|---|
| 767 | + struct list_head src_buf_head; |
|---|
| 768 | + spinlock_t vbq_lock; /* vfd lock */ |
|---|
| 769 | + wait_queue_head_t wq_stopped; |
|---|
| 770 | + struct v4l2_pix_format_mplane pixm; |
|---|
| 771 | + const struct cif_output_fmt *tools_out_fmt; |
|---|
| 772 | + struct rkcif_buffer *curr_buf; |
|---|
| 773 | + struct work_struct work; |
|---|
| 774 | + enum rkcif_state state; |
|---|
| 775 | + int frame_phase; |
|---|
| 776 | + unsigned int frame_idx; |
|---|
| 777 | + bool stopping; |
|---|
| 778 | +}; |
|---|
| 779 | + |
|---|
| 780 | +static inline |
|---|
| 781 | +struct rkcif_tools_vdev *to_rkcif_tools_vdev(struct rkcif_vdev_node *vnode) |
|---|
| 782 | +{ |
|---|
| 783 | + return container_of(vnode, struct rkcif_tools_vdev, vnode); |
|---|
| 784 | +} |
|---|
| 785 | + |
|---|
| 786 | +void rkcif_init_tools_vdev(struct rkcif_device *cif_dev, u32 ch); |
|---|
| 787 | +int rkcif_register_tools_vdevs(struct rkcif_device *cif_dev, |
|---|
| 788 | + int stream_num, |
|---|
| 789 | + bool is_multi_input); |
|---|
| 790 | +void rkcif_unregister_tools_vdevs(struct rkcif_device *cif_dev, |
|---|
| 791 | + int stream_num); |
|---|
| 792 | + |
|---|
| 793 | +enum rkcif_err_state { |
|---|
| 794 | + RKCIF_ERR_ID0_NOT_BUF = 0x1, |
|---|
| 795 | + RKCIF_ERR_ID1_NOT_BUF = 0x2, |
|---|
| 796 | + RKCIF_ERR_ID2_NOT_BUF = 0x4, |
|---|
| 797 | + RKCIF_ERR_ID3_NOT_BUF = 0x8, |
|---|
| 798 | + RKCIF_ERR_ID0_TRIG_SIMULT = 0x10, |
|---|
| 799 | + RKCIF_ERR_ID1_TRIG_SIMULT = 0x20, |
|---|
| 800 | + RKCIF_ERR_ID2_TRIG_SIMULT = 0x40, |
|---|
| 801 | + RKCIF_ERR_ID3_TRIG_SIMULT = 0x80, |
|---|
| 802 | + RKCIF_ERR_SIZE = 0x100, |
|---|
| 803 | + RKCIF_ERR_OVERFLOW = 0x200, |
|---|
| 804 | + RKCIF_ERR_BANDWIDTH_LACK = 0x400, |
|---|
| 805 | + RKCIF_ERR_BUS = 0X800, |
|---|
| 806 | + RKCIF_ERR_ID0_MULTI_FS = 0x1000, |
|---|
| 807 | + RKCIF_ERR_ID1_MULTI_FS = 0x2000, |
|---|
| 808 | + RKCIF_ERR_ID2_MULTI_FS = 0x4000, |
|---|
| 809 | + RKCIF_ERR_ID3_MULTI_FS = 0x8000, |
|---|
| 810 | + RKCIF_ERR_PIXEL = 0x10000, |
|---|
| 811 | + RKCIF_ERR_LINE = 0x20000, |
|---|
| 812 | +}; |
|---|
| 813 | + |
|---|
| 814 | +struct rkcif_err_state_work { |
|---|
| 815 | + struct work_struct work; |
|---|
| 816 | + u64 last_timestamp; |
|---|
| 817 | + u32 err_state; |
|---|
| 818 | + u32 intstat; |
|---|
| 819 | + u32 lastline; |
|---|
| 820 | + u32 lastpixel; |
|---|
| 821 | + u32 size_id0; |
|---|
| 822 | + u32 size_id1; |
|---|
| 823 | + u32 size_id2; |
|---|
| 824 | + u32 size_id3; |
|---|
| 825 | +}; |
|---|
| 826 | + |
|---|
| 827 | +enum rkcif_resume_user { |
|---|
| 828 | + RKCIF_RESUME_CIF, |
|---|
| 829 | + RKCIF_RESUME_ISP, |
|---|
| 830 | +}; |
|---|
| 831 | + |
|---|
| 832 | +struct rkcif_sensor_work { |
|---|
| 833 | + struct work_struct work; |
|---|
| 834 | + int on; |
|---|
| 835 | +}; |
|---|
| 836 | + |
|---|
| 476 | 837 | /* |
|---|
| 477 | 838 | * struct rkcif_device - ISP platform device |
|---|
| 478 | 839 | * @base_addr: base register address |
|---|
| .. | .. |
|---|
| 492 | 853 | struct rkcif_sensor_info terminal_sensor; |
|---|
| 493 | 854 | |
|---|
| 494 | 855 | struct rkcif_stream stream[RKCIF_MULTI_STREAMS_NUM]; |
|---|
| 856 | + struct rkcif_scale_vdev scale_vdev[RKCIF_MULTI_STREAMS_NUM]; |
|---|
| 857 | + struct rkcif_tools_vdev tools_vdev[RKCIF_MAX_TOOLS_CH]; |
|---|
| 495 | 858 | struct rkcif_pipeline pipe; |
|---|
| 496 | 859 | |
|---|
| 497 | 860 | struct csi_channel_info channels[RKCIF_MAX_CSI_CHANNEL]; |
|---|
| 498 | 861 | int num_channels; |
|---|
| 499 | 862 | int chip_id; |
|---|
| 500 | 863 | atomic_t stream_cnt; |
|---|
| 501 | | - atomic_t fh_cnt; |
|---|
| 864 | + atomic_t power_cnt; |
|---|
| 865 | + atomic_t streamoff_cnt; |
|---|
| 502 | 866 | struct mutex stream_lock; /* lock between streams */ |
|---|
| 867 | + struct mutex scale_lock; /* lock between scale dev */ |
|---|
| 868 | + struct mutex tools_lock; /* lock between tools dev */ |
|---|
| 503 | 869 | enum rkcif_workmode workmode; |
|---|
| 504 | 870 | bool can_be_reset; |
|---|
| 505 | | - struct rkcif_hdr hdr; |
|---|
| 871 | + struct rkmodule_hdr_cfg hdr; |
|---|
| 506 | 872 | struct rkcif_buffer *rdbk_buf[RDBK_MAX]; |
|---|
| 873 | + struct rkcif_rx_buffer *rdbk_rx_buf[RDBK_MAX]; |
|---|
| 507 | 874 | struct rkcif_luma_vdev luma_vdev; |
|---|
| 508 | 875 | struct rkcif_lvds_subdev lvds_subdev; |
|---|
| 509 | 876 | struct rkcif_dvp_sof_subdev dvp_sof_subdev; |
|---|
| .. | .. |
|---|
| 511 | 878 | irqreturn_t (*isr_hdl)(int irq, struct rkcif_device *cif_dev); |
|---|
| 512 | 879 | int inf_id; |
|---|
| 513 | 880 | |
|---|
| 514 | | - struct sditf_priv *sditf; |
|---|
| 881 | + struct sditf_priv *sditf[RKCIF_MAX_SDITF]; |
|---|
| 515 | 882 | struct proc_dir_entry *proc_dir; |
|---|
| 516 | 883 | struct rkcif_irq_stats irq_stats; |
|---|
| 517 | 884 | spinlock_t hdr_lock; /* lock for hdr buf sync */ |
|---|
| 885 | + spinlock_t buffree_lock; |
|---|
| 518 | 886 | struct rkcif_timer reset_watchdog_timer; |
|---|
| 519 | | - struct notifier_block reset_notifier; /* reset for mipi csi crc err */ |
|---|
| 520 | 887 | struct rkcif_work_struct reset_work; |
|---|
| 888 | + int id_use_cnt; |
|---|
| 889 | + unsigned int csi_host_idx; |
|---|
| 890 | + unsigned int csi_host_idx_def; |
|---|
| 521 | 891 | unsigned int dvp_sof_in_oneframe; |
|---|
| 522 | 892 | unsigned int wait_line; |
|---|
| 523 | 893 | unsigned int wait_line_bak; |
|---|
| 524 | 894 | unsigned int wait_line_cache; |
|---|
| 525 | | - struct rkcif_dummy_buffer dummy_buf; |
|---|
| 895 | + struct completion cmpl_ntf; |
|---|
| 896 | + struct csi2_dphy_hw *dphy_hw; |
|---|
| 897 | + phys_addr_t resmem_pa; |
|---|
| 898 | + dma_addr_t resmem_addr; |
|---|
| 899 | + size_t resmem_size; |
|---|
| 900 | + struct rk_tb_client tb_client; |
|---|
| 526 | 901 | bool is_start_hdr; |
|---|
| 527 | 902 | bool reset_work_cancel; |
|---|
| 528 | 903 | bool iommu_en; |
|---|
| 529 | 904 | bool is_use_dummybuf; |
|---|
| 905 | + bool is_notifier_isp; |
|---|
| 906 | + bool is_thunderboot; |
|---|
| 907 | + bool is_rdbk_to_online; |
|---|
| 908 | + bool is_support_tools; |
|---|
| 909 | + bool is_rtt_suspend; |
|---|
| 910 | + bool sensor_state_change; |
|---|
| 911 | + bool is_toisp_reset; |
|---|
| 912 | + int rdbk_debug; |
|---|
| 913 | + struct rkcif_sync_cfg sync_cfg; |
|---|
| 914 | + int sditf_cnt; |
|---|
| 915 | + u32 early_line; |
|---|
| 916 | + int isp_runtime_max; |
|---|
| 917 | + int sensor_linetime; |
|---|
| 918 | + u32 err_state; |
|---|
| 919 | + struct rkcif_err_state_work err_state_work; |
|---|
| 920 | + struct rkcif_sensor_work sensor_work; |
|---|
| 921 | + int resume_mode; |
|---|
| 922 | + u32 nr_buf_size; |
|---|
| 923 | + u32 share_mem_size; |
|---|
| 924 | + u32 thunderboot_sensor_num; |
|---|
| 925 | + int sensor_state; |
|---|
| 926 | + u32 intr_mask; |
|---|
| 927 | + struct delayed_work work_deal_err; |
|---|
| 530 | 928 | }; |
|---|
| 531 | 929 | |
|---|
| 532 | 930 | extern struct platform_driver rkcif_plat_drv; |
|---|
| 931 | +void rkcif_set_fps(struct rkcif_stream *stream, struct rkcif_fps *fps); |
|---|
| 932 | +int rkcif_do_start_stream(struct rkcif_stream *stream, |
|---|
| 933 | + enum rkcif_stream_mode mode); |
|---|
| 934 | +void rkcif_do_stop_stream(struct rkcif_stream *stream, |
|---|
| 935 | + enum rkcif_stream_mode mode); |
|---|
| 936 | +void rkcif_irq_handle_scale(struct rkcif_device *cif_dev, |
|---|
| 937 | + unsigned int intstat_glb); |
|---|
| 938 | +void rkcif_buf_queue(struct vb2_buffer *vb); |
|---|
| 939 | + |
|---|
| 940 | +void rkcif_vb_done_tasklet(struct rkcif_stream *stream, struct rkcif_buffer *buf); |
|---|
| 941 | + |
|---|
| 942 | +int rkcif_scale_start(struct rkcif_scale_vdev *scale_vdev); |
|---|
| 943 | + |
|---|
| 944 | +const struct |
|---|
| 945 | +cif_input_fmt *rkcif_get_input_fmt(struct rkcif_device *dev, |
|---|
| 946 | + struct v4l2_rect *rect, |
|---|
| 947 | + u32 pad_id, struct csi_channel_info *csi_info); |
|---|
| 533 | 948 | |
|---|
| 534 | 949 | void rkcif_write_register(struct rkcif_device *dev, |
|---|
| 535 | 950 | enum cif_reg_index index, u32 val); |
|---|
| .. | .. |
|---|
| 552 | 967 | void rkcif_set_default_fmt(struct rkcif_device *cif_dev); |
|---|
| 553 | 968 | void rkcif_irq_oneframe(struct rkcif_device *cif_dev); |
|---|
| 554 | 969 | void rkcif_irq_pingpong(struct rkcif_device *cif_dev); |
|---|
| 555 | | -void rkcif_soft_reset(struct rkcif_device *cif_dev, |
|---|
| 556 | | - bool is_rst_iommu); |
|---|
| 970 | +void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev); |
|---|
| 971 | +unsigned int rkcif_irq_global(struct rkcif_device *cif_dev); |
|---|
| 972 | +void rkcif_irq_handle_toisp(struct rkcif_device *cif_dev, unsigned int intstat_glb); |
|---|
| 557 | 973 | int rkcif_register_lvds_subdev(struct rkcif_device *dev); |
|---|
| 558 | 974 | void rkcif_unregister_lvds_subdev(struct rkcif_device *dev); |
|---|
| 559 | 975 | int rkcif_register_dvp_sof_subdev(struct rkcif_device *dev); |
|---|
| 560 | 976 | void rkcif_unregister_dvp_sof_subdev(struct rkcif_device *dev); |
|---|
| 561 | 977 | void rkcif_irq_lite_lvds(struct rkcif_device *cif_dev); |
|---|
| 562 | | -u32 rkcif_get_sof(struct rkcif_device *cif_dev); |
|---|
| 563 | 978 | int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int inf_id); |
|---|
| 564 | 979 | int rkcif_plat_uninit(struct rkcif_device *cif_dev); |
|---|
| 565 | 980 | int rkcif_attach_hw(struct rkcif_device *cif_dev); |
|---|
| .. | .. |
|---|
| 570 | 985 | enum rkcif_clk_edge edge); |
|---|
| 571 | 986 | void rkcif_enable_dvp_clk_dual_edge(struct rkcif_device *dev, bool on); |
|---|
| 572 | 987 | void rkcif_reset_work(struct work_struct *work); |
|---|
| 573 | | -void rkcif_monitor_reset_event(struct rkcif_hw *hw); |
|---|
| 988 | + |
|---|
| 989 | +void rkcif_vb_done_oneframe(struct rkcif_stream *stream, |
|---|
| 990 | + struct vb2_v4l2_buffer *vb_done); |
|---|
| 991 | + |
|---|
| 992 | +int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num); |
|---|
| 993 | +void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num); |
|---|
| 994 | + |
|---|
| 995 | +int rkcif_set_fmt(struct rkcif_stream *stream, |
|---|
| 996 | + struct v4l2_pix_format_mplane *pixm, |
|---|
| 997 | + bool try); |
|---|
| 998 | +void rkcif_enable_dma_capture(struct rkcif_stream *stream, bool is_only_enable); |
|---|
| 999 | + |
|---|
| 1000 | +void rkcif_do_soft_reset(struct rkcif_device *dev); |
|---|
| 1001 | + |
|---|
| 1002 | +u32 rkcif_mbus_pixelcode_to_v4l2(u32 pixelcode); |
|---|
| 1003 | + |
|---|
| 1004 | +void rkcif_config_dvp_pin(struct rkcif_device *dev, bool on); |
|---|
| 1005 | + |
|---|
| 1006 | +s32 rkcif_get_sensor_vblank_def(struct rkcif_device *dev); |
|---|
| 1007 | +s32 rkcif_get_sensor_vblank(struct rkcif_device *dev); |
|---|
| 1008 | +int rkcif_get_linetime(struct rkcif_stream *stream); |
|---|
| 1009 | + |
|---|
| 1010 | +void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream); |
|---|
| 1011 | + |
|---|
| 1012 | +struct rkcif_rx_buffer *to_cif_rx_buf(struct rkisp_rx_buf *dbufs); |
|---|
| 1013 | + |
|---|
| 1014 | +int rkcif_clr_unready_dev(void); |
|---|
| 1015 | + |
|---|
| 1016 | +const struct |
|---|
| 1017 | +cif_output_fmt *rkcif_find_output_fmt(struct rkcif_stream *stream, u32 pixelfmt); |
|---|
| 1018 | +/* Rockit */ |
|---|
| 1019 | +int rkcif_rockit_buf_done(struct rkcif_stream *stream, struct rkcif_buffer *buf); |
|---|
| 1020 | +void rkcif_rockit_dev_init(struct rkcif_device *dev); |
|---|
| 1021 | +void rkcif_rockit_dev_deinit(void); |
|---|
| 1022 | + |
|---|
| 1023 | +void rkcif_err_print_work(struct work_struct *work); |
|---|
| 1024 | +int rkcif_stream_suspend(struct rkcif_device *cif_dev, int mode); |
|---|
| 1025 | +int rkcif_stream_resume(struct rkcif_device *cif_dev, int mode); |
|---|
| 1026 | + |
|---|
| 1027 | +static inline u64 rkcif_time_get_ns(struct rkcif_device *dev) |
|---|
| 1028 | +{ |
|---|
| 1029 | + if (dev->chip_id == CHIP_RV1106_CIF) |
|---|
| 1030 | + return ktime_get_boottime_ns(); |
|---|
| 1031 | + else |
|---|
| 1032 | + return ktime_get_ns(); |
|---|
| 1033 | +} |
|---|
| 574 | 1034 | |
|---|
| 575 | 1035 | #endif |
|---|