| .. | .. |
|---|
| 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 |
|---|
| .. | .. |
|---|
| 91 | 100 | RKCIF_WORKMODE_LINELOOP = 0x02 |
|---|
| 92 | 101 | }; |
|---|
| 93 | 102 | |
|---|
| 103 | +enum rkcif_stream_mode { |
|---|
| 104 | + RKCIF_STREAM_MODE_NONE = 0x0, |
|---|
| 105 | + RKCIF_STREAM_MODE_CAPTURE = 0x01, |
|---|
| 106 | + RKCIF_STREAM_MODE_TOISP = 0x02, |
|---|
| 107 | + RKCIF_STREAM_MODE_TOSCALE = 0x04, |
|---|
| 108 | + RKCIF_STREAM_MODE_TOISP_RDBK = 0x08, |
|---|
| 109 | + RKCIF_STREAM_MODE_ROCKIT = 0x10 |
|---|
| 110 | +}; |
|---|
| 111 | + |
|---|
| 94 | 112 | enum rkcif_yuvaddr_state { |
|---|
| 95 | 113 | RKCIF_YUV_ADDR_STATE_UPDATE = 0x0, |
|---|
| 96 | 114 | RKCIF_YUV_ADDR_STATE_INIT = 0x1 |
|---|
| .. | .. |
|---|
| 103 | 121 | RKCIF_STATE_RESET_IN_STREAMING, |
|---|
| 104 | 122 | }; |
|---|
| 105 | 123 | |
|---|
| 106 | | -enum host_type_t { |
|---|
| 107 | | - RK_CSI_RXHOST, |
|---|
| 108 | | - RK_DSI_RXHOST |
|---|
| 109 | | -}; |
|---|
| 110 | | - |
|---|
| 111 | 124 | enum rkcif_lvds_pad { |
|---|
| 112 | 125 | RKCIF_LVDS_PAD_SINK = 0x0, |
|---|
| 113 | 126 | RKCIF_LVDS_PAD_SRC_ID0, |
|---|
| 114 | 127 | RKCIF_LVDS_PAD_SRC_ID1, |
|---|
| 115 | 128 | RKCIF_LVDS_PAD_SRC_ID2, |
|---|
| 116 | 129 | RKCIF_LVDS_PAD_SRC_ID3, |
|---|
| 117 | | - RKCIF_LVDS_PAD_MAX |
|---|
| 130 | + RKCIF_LVDS_PAD_SCL_ID0, |
|---|
| 131 | + RKCIF_LVDS_PAD_SCL_ID1, |
|---|
| 132 | + RKCIF_LVDS_PAD_SCL_ID2, |
|---|
| 133 | + RKCIF_LVDS_PAD_SCL_ID3, |
|---|
| 134 | + RKCIF_LVDS_PAD_MAX, |
|---|
| 118 | 135 | }; |
|---|
| 119 | 136 | |
|---|
| 120 | 137 | enum rkcif_lvds_state { |
|---|
| .. | .. |
|---|
| 170 | 187 | u32 buff_addr[VIDEO_MAX_PLANES]; |
|---|
| 171 | 188 | void *vaddr[VIDEO_MAX_PLANES]; |
|---|
| 172 | 189 | }; |
|---|
| 190 | + struct dma_buf *dbuf; |
|---|
| 191 | + u64 fe_timestamp; |
|---|
| 173 | 192 | }; |
|---|
| 174 | 193 | |
|---|
| 175 | | -struct rkcif_dummy_buffer { |
|---|
| 176 | | - void *vaddr; |
|---|
| 177 | | - dma_addr_t dma_addr; |
|---|
| 178 | | - u32 size; |
|---|
| 194 | +struct rkcif_tools_buffer { |
|---|
| 195 | + struct vb2_v4l2_buffer *vb; |
|---|
| 196 | + struct list_head list; |
|---|
| 197 | + u32 frame_idx; |
|---|
| 198 | + u64 timestamp; |
|---|
| 199 | + int use_cnt; |
|---|
| 179 | 200 | }; |
|---|
| 180 | 201 | |
|---|
| 181 | 202 | extern int rkcif_debug; |
|---|
| .. | .. |
|---|
| 250 | 271 | unsigned char enable; /* capture enable */ |
|---|
| 251 | 272 | unsigned char vc; |
|---|
| 252 | 273 | unsigned char data_type; |
|---|
| 274 | + unsigned char data_bit; |
|---|
| 253 | 275 | unsigned char crop_en; |
|---|
| 254 | 276 | unsigned char cmd_mode_en; |
|---|
| 255 | 277 | unsigned char fmt_val; |
|---|
| 278 | + unsigned char csi_fmt_val; |
|---|
| 256 | 279 | unsigned int width; |
|---|
| 257 | 280 | unsigned int height; |
|---|
| 258 | 281 | unsigned int virtual_width; |
|---|
| .. | .. |
|---|
| 326 | 349 | struct rkcif_irq_stats { |
|---|
| 327 | 350 | u64 csi_overflow_cnt; |
|---|
| 328 | 351 | u64 csi_bwidth_lack_cnt; |
|---|
| 352 | + u64 csi_size_err_cnt; |
|---|
| 329 | 353 | u64 dvp_bus_err_cnt; |
|---|
| 330 | 354 | u64 dvp_overflow_cnt; |
|---|
| 331 | 355 | u64 dvp_line_err_cnt; |
|---|
| 332 | 356 | u64 dvp_pix_err_cnt; |
|---|
| 333 | | - u64 all_frm_end_cnt; |
|---|
| 357 | + u64 dvp_size_err_cnt; |
|---|
| 358 | + u64 dvp_bwidth_lack_cnt; |
|---|
| 359 | + u64 frm_end_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 360 | + u64 not_active_buf_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 361 | + u64 trig_simult_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 334 | 362 | u64 all_err_cnt; |
|---|
| 363 | +}; |
|---|
| 364 | + |
|---|
| 365 | +/* |
|---|
| 366 | + * the detecting mode of cif reset timer |
|---|
| 367 | + * related with dts property:rockchip,cif-monitor |
|---|
| 368 | + */ |
|---|
| 369 | +enum rkcif_monitor_mode { |
|---|
| 370 | + RKCIF_MONITOR_MODE_IDLE = 0x0, |
|---|
| 371 | + RKCIF_MONITOR_MODE_CONTINUE, |
|---|
| 372 | + RKCIF_MONITOR_MODE_TRIGGER, |
|---|
| 373 | + RKCIF_MONITOR_MODE_HOTPLUG, |
|---|
| 335 | 374 | }; |
|---|
| 336 | 375 | |
|---|
| 337 | 376 | /* |
|---|
| .. | .. |
|---|
| 348 | 387 | }; |
|---|
| 349 | 388 | |
|---|
| 350 | 389 | struct rkcif_timer { |
|---|
| 390 | + struct timer_list timer; |
|---|
| 391 | + spinlock_t timer_lock; |
|---|
| 351 | 392 | spinlock_t csi2_err_lock; |
|---|
| 352 | | - unsigned int last_buf_wakeup_cnt[RKCIF_MAX_CSI_CHANNEL]; |
|---|
| 393 | + unsigned long cycle; |
|---|
| 394 | + /* unit: us */ |
|---|
| 395 | + unsigned long line_end_cycle; |
|---|
| 396 | + unsigned int run_cnt; |
|---|
| 397 | + unsigned int max_run_cnt; |
|---|
| 398 | + unsigned int stop_index_of_run_cnt; |
|---|
| 399 | + unsigned int last_buf_wakeup_cnt[RKCIF_MAX_STREAM_MIPI]; |
|---|
| 353 | 400 | unsigned long csi2_err_cnt_even; |
|---|
| 354 | 401 | unsigned long csi2_err_cnt_odd; |
|---|
| 402 | + unsigned int csi2_err_ref_cnt; |
|---|
| 355 | 403 | unsigned int csi2_err_fs_fe_cnt; |
|---|
| 356 | 404 | unsigned int csi2_err_fs_fe_detect_cnt; |
|---|
| 405 | + unsigned int frm_num_of_monitor_cycle; |
|---|
| 406 | + unsigned int triggered_frame_num; |
|---|
| 407 | + unsigned int vts; |
|---|
| 408 | + unsigned int raw_height; |
|---|
| 409 | + /* unit: ms */ |
|---|
| 410 | + unsigned int err_time_interval; |
|---|
| 357 | 411 | unsigned int csi2_err_triggered_cnt; |
|---|
| 358 | 412 | unsigned int notifer_called_cnt; |
|---|
| 413 | + unsigned long frame_end_cycle_us; |
|---|
| 359 | 414 | u64 csi2_first_err_timestamp; |
|---|
| 360 | 415 | bool is_triggered; |
|---|
| 361 | 416 | bool is_buf_stop_update; |
|---|
| 417 | + bool is_running; |
|---|
| 362 | 418 | bool is_csi2_err_occurred; |
|---|
| 419 | + bool has_been_init; |
|---|
| 420 | + bool is_ctrl_by_user; |
|---|
| 421 | + enum rkcif_monitor_mode monitor_mode; |
|---|
| 422 | + enum rkmodule_reset_src reset_src; |
|---|
| 363 | 423 | }; |
|---|
| 364 | 424 | |
|---|
| 365 | 425 | struct rkcif_extend_info { |
|---|
| 366 | 426 | struct v4l2_pix_format_mplane pixm; |
|---|
| 367 | 427 | bool is_extended; |
|---|
| 428 | +}; |
|---|
| 429 | + |
|---|
| 430 | +enum rkcif_capture_mode { |
|---|
| 431 | + RKCIF_TO_DDR = 0, |
|---|
| 432 | + RKCIF_TO_ISP_DDR, |
|---|
| 433 | + RKCIF_TO_ISP_DMA, |
|---|
| 434 | +}; |
|---|
| 435 | + |
|---|
| 436 | +/* |
|---|
| 437 | + * list: used for buf rotation |
|---|
| 438 | + * list_free: only used to release buf asynchronously |
|---|
| 439 | + */ |
|---|
| 440 | +struct rkcif_rx_buffer { |
|---|
| 441 | + int buf_idx; |
|---|
| 442 | + struct list_head list; |
|---|
| 443 | + struct list_head list_free; |
|---|
| 444 | + struct rkisp_rx_buf dbufs; |
|---|
| 445 | + struct rkcif_dummy_buffer dummy; |
|---|
| 446 | + struct rkisp_thunderboot_shmem shmem; |
|---|
| 447 | + u64 fe_timestamp; |
|---|
| 448 | +}; |
|---|
| 449 | + |
|---|
| 450 | +enum rkcif_dma_en_mode { |
|---|
| 451 | + RKCIF_DMAEN_BY_VICAP = 0x1, |
|---|
| 452 | + RKCIF_DMAEN_BY_ISP = 0x2, |
|---|
| 453 | + RKCIF_DMAEN_BY_VICAP_TO_ISP = 0x4, |
|---|
| 454 | + RKCIF_DMAEN_BY_ISP_TO_VICAP = 0x8, |
|---|
| 455 | + RKCIF_DMAEN_BY_ROCKIT = 0x10, |
|---|
| 456 | +}; |
|---|
| 457 | + |
|---|
| 458 | +struct rkcif_skip_info { |
|---|
| 459 | + u8 cap_m; |
|---|
| 460 | + u8 skip_n; |
|---|
| 461 | + bool skip_en; |
|---|
| 462 | + bool skip_to_en; |
|---|
| 463 | + bool skip_to_dis; |
|---|
| 464 | +}; |
|---|
| 465 | + |
|---|
| 466 | +struct rkcif_sync_cfg { |
|---|
| 467 | + u32 type; |
|---|
| 468 | + u32 group; |
|---|
| 368 | 469 | }; |
|---|
| 369 | 470 | |
|---|
| 370 | 471 | /* |
|---|
| .. | .. |
|---|
| 394 | 495 | struct list_head buf_head; |
|---|
| 395 | 496 | struct rkcif_buffer *curr_buf; |
|---|
| 396 | 497 | struct rkcif_buffer *next_buf; |
|---|
| 498 | + struct rkcif_rx_buffer *curr_buf_toisp; |
|---|
| 499 | + struct rkcif_rx_buffer *next_buf_toisp; |
|---|
| 500 | + struct list_head rockit_buf_head; |
|---|
| 501 | + struct rkcif_buffer *curr_buf_rockit; |
|---|
| 502 | + struct rkcif_buffer *next_buf_rockit; |
|---|
| 397 | 503 | |
|---|
| 398 | 504 | spinlock_t vbq_lock; /* vfd lock */ |
|---|
| 399 | 505 | spinlock_t fps_lock; |
|---|
| .. | .. |
|---|
| 408 | 514 | struct rkcif_extend_info extend_line; |
|---|
| 409 | 515 | struct rkcif_readout_stats readout; |
|---|
| 410 | 516 | unsigned int fs_cnt_in_single_frame; |
|---|
| 517 | + unsigned int capture_mode; |
|---|
| 518 | + struct rkcif_scale_vdev *scale_vdev; |
|---|
| 519 | + struct rkcif_tools_vdev *tools_vdev; |
|---|
| 520 | + int dma_en; |
|---|
| 521 | + int to_en_dma; |
|---|
| 522 | + int to_stop_dma; |
|---|
| 523 | + int buf_owner; |
|---|
| 524 | + int buf_replace_cnt; |
|---|
| 525 | + struct list_head rx_buf_head_vicap; |
|---|
| 526 | + unsigned int cur_stream_mode; |
|---|
| 527 | + struct rkcif_rx_buffer rx_buf[RKISP_VICAP_BUF_CNT_MAX]; |
|---|
| 528 | + struct list_head rx_buf_head; |
|---|
| 529 | + int buf_num_toisp; |
|---|
| 411 | 530 | u64 line_int_cnt; |
|---|
| 412 | | - int vc; |
|---|
| 413 | | - u64 streamon_timestamp; |
|---|
| 531 | + int lack_buf_cnt; |
|---|
| 532 | + unsigned int buf_wake_up_cnt; |
|---|
| 533 | + struct rkcif_skip_info skip_info; |
|---|
| 534 | + struct tasklet_struct vb_done_tasklet; |
|---|
| 535 | + struct list_head vb_done_list; |
|---|
| 536 | + int last_rx_buf_idx; |
|---|
| 537 | + int last_frame_idx; |
|---|
| 538 | + int new_fource_idx; |
|---|
| 414 | 539 | bool stopping; |
|---|
| 415 | 540 | bool crop_enable; |
|---|
| 416 | 541 | bool crop_dyn_en; |
|---|
| .. | .. |
|---|
| 422 | 547 | bool is_can_stop; |
|---|
| 423 | 548 | bool is_buf_active; |
|---|
| 424 | 549 | bool is_high_align; |
|---|
| 550 | + bool to_en_scale; |
|---|
| 551 | + bool is_finish_stop_dma; |
|---|
| 552 | + bool is_in_vblank; |
|---|
| 553 | + bool is_change_toisp; |
|---|
| 554 | + bool is_stop_capture; |
|---|
| 425 | 555 | }; |
|---|
| 426 | 556 | |
|---|
| 427 | 557 | struct rkcif_lvds_subdev { |
|---|
| .. | .. |
|---|
| 473 | 603 | return &vnode->buf_queue; |
|---|
| 474 | 604 | } |
|---|
| 475 | 605 | |
|---|
| 606 | +#define SCALE_DRIVER_NAME "rkcif_scale" |
|---|
| 607 | + |
|---|
| 608 | +#define RKCIF_SCALE_CH0 0 |
|---|
| 609 | +#define RKCIF_SCALE_CH1 1 |
|---|
| 610 | +#define RKCIF_SCALE_CH2 2 |
|---|
| 611 | +#define RKCIF_SCALE_CH3 3 |
|---|
| 612 | +#define RKCIF_MAX_SCALE_CH 4 |
|---|
| 613 | + |
|---|
| 614 | +#define CIF_SCALE_CH0_VDEV_NAME CIF_DRIVER_NAME "_scale_ch0" |
|---|
| 615 | +#define CIF_SCALE_CH1_VDEV_NAME CIF_DRIVER_NAME "_scale_ch1" |
|---|
| 616 | +#define CIF_SCALE_CH2_VDEV_NAME CIF_DRIVER_NAME "_scale_ch2" |
|---|
| 617 | +#define CIF_SCALE_CH3_VDEV_NAME CIF_DRIVER_NAME "_scale_ch3" |
|---|
| 618 | + |
|---|
| 619 | +#define RKCIF_SCALE_ENUM_SIZE_MAX 3 |
|---|
| 620 | +#define RKCIF_MAX_SDITF 4 |
|---|
| 621 | + |
|---|
| 622 | +enum scale_ch_sw { |
|---|
| 623 | + SCALE_MIPI0_ID0, |
|---|
| 624 | + SCALE_MIPI0_ID1, |
|---|
| 625 | + SCALE_MIPI0_ID2, |
|---|
| 626 | + SCALE_MIPI0_ID3, |
|---|
| 627 | + SCALE_MIPI1_ID0, |
|---|
| 628 | + SCALE_MIPI1_ID1, |
|---|
| 629 | + SCALE_MIPI1_ID2, |
|---|
| 630 | + SCALE_MIPI1_ID3, |
|---|
| 631 | + SCALE_MIPI2_ID0, |
|---|
| 632 | + SCALE_MIPI2_ID1, |
|---|
| 633 | + SCALE_MIPI2_ID2, |
|---|
| 634 | + SCALE_MIPI2_ID3, |
|---|
| 635 | + SCALE_MIPI3_ID0, |
|---|
| 636 | + SCALE_MIPI3_ID1, |
|---|
| 637 | + SCALE_MIPI3_ID2, |
|---|
| 638 | + SCALE_MIPI3_ID3, |
|---|
| 639 | + SCALE_MIPI4_ID0, |
|---|
| 640 | + SCALE_MIPI4_ID1, |
|---|
| 641 | + SCALE_MIPI4_ID2, |
|---|
| 642 | + SCALE_MIPI4_ID3, |
|---|
| 643 | + SCALE_MIPI5_ID0, |
|---|
| 644 | + SCALE_MIPI5_ID1, |
|---|
| 645 | + SCALE_MIPI5_ID2, |
|---|
| 646 | + SCALE_MIPI5_ID3, |
|---|
| 647 | + SCALE_DVP, |
|---|
| 648 | + SCALE_CH_MAX, |
|---|
| 649 | +}; |
|---|
| 650 | + |
|---|
| 651 | +enum scale_mode { |
|---|
| 652 | + SCALE_8TIMES, |
|---|
| 653 | + SCALE_16TIMES, |
|---|
| 654 | + SCALE_32TIMES, |
|---|
| 655 | +}; |
|---|
| 656 | + |
|---|
| 657 | +struct rkcif_scale_ch_info { |
|---|
| 658 | + u32 width; |
|---|
| 659 | + u32 height; |
|---|
| 660 | + u32 vir_width; |
|---|
| 661 | +}; |
|---|
| 662 | + |
|---|
| 663 | +struct rkcif_scale_src_res { |
|---|
| 664 | + u32 width; |
|---|
| 665 | + u32 height; |
|---|
| 666 | +}; |
|---|
| 667 | + |
|---|
| 668 | +/* |
|---|
| 669 | + * struct rkcif_scale_vdev - CIF Capture device |
|---|
| 670 | + * |
|---|
| 671 | + * @irq_lock: buffer queue lock |
|---|
| 672 | + * @stat: stats buffer list |
|---|
| 673 | + * @readout_wq: workqueue for statistics information read |
|---|
| 674 | + */ |
|---|
| 675 | +struct rkcif_scale_vdev { |
|---|
| 676 | + unsigned int ch:3; |
|---|
| 677 | + struct rkcif_device *cifdev; |
|---|
| 678 | + struct rkcif_vdev_node vnode; |
|---|
| 679 | + struct rkcif_stream *stream; |
|---|
| 680 | + struct list_head buf_head; |
|---|
| 681 | + spinlock_t vbq_lock; /* vfd lock */ |
|---|
| 682 | + wait_queue_head_t wq_stopped; |
|---|
| 683 | + struct v4l2_pix_format_mplane pixm; |
|---|
| 684 | + const struct cif_output_fmt *scale_out_fmt; |
|---|
| 685 | + struct rkcif_scale_ch_info ch_info; |
|---|
| 686 | + struct rkcif_scale_src_res src_res; |
|---|
| 687 | + struct rkcif_buffer *curr_buf; |
|---|
| 688 | + struct rkcif_buffer *next_buf; |
|---|
| 689 | + struct bayer_blc blc; |
|---|
| 690 | + enum rkcif_state state; |
|---|
| 691 | + unsigned int ch_src; |
|---|
| 692 | + unsigned int scale_mode; |
|---|
| 693 | + int frame_phase; |
|---|
| 694 | + unsigned int frame_idx; |
|---|
| 695 | + bool stopping; |
|---|
| 696 | +}; |
|---|
| 697 | + |
|---|
| 698 | +static inline |
|---|
| 699 | +struct rkcif_scale_vdev *to_rkcif_scale_vdev(struct rkcif_vdev_node *vnode) |
|---|
| 700 | +{ |
|---|
| 701 | + return container_of(vnode, struct rkcif_scale_vdev, vnode); |
|---|
| 702 | +} |
|---|
| 703 | + |
|---|
| 704 | +void rkcif_init_scale_vdev(struct rkcif_device *cif_dev, u32 ch); |
|---|
| 705 | +int rkcif_register_scale_vdevs(struct rkcif_device *cif_dev, |
|---|
| 706 | + int stream_num, |
|---|
| 707 | + bool is_multi_input); |
|---|
| 708 | +void rkcif_unregister_scale_vdevs(struct rkcif_device *cif_dev, |
|---|
| 709 | + int stream_num); |
|---|
| 710 | + |
|---|
| 711 | +#define TOOLS_DRIVER_NAME "rkcif_tools" |
|---|
| 712 | + |
|---|
| 713 | +#define RKCIF_TOOLS_CH0 0 |
|---|
| 714 | +#define RKCIF_TOOLS_CH1 1 |
|---|
| 715 | +#define RKCIF_TOOLS_CH2 2 |
|---|
| 716 | +#define RKCIF_MAX_TOOLS_CH 3 |
|---|
| 717 | + |
|---|
| 718 | +#define CIF_TOOLS_CH0_VDEV_NAME CIF_DRIVER_NAME "_tools_id0" |
|---|
| 719 | +#define CIF_TOOLS_CH1_VDEV_NAME CIF_DRIVER_NAME "_tools_id1" |
|---|
| 720 | +#define CIF_TOOLS_CH2_VDEV_NAME CIF_DRIVER_NAME "_tools_id2" |
|---|
| 721 | + |
|---|
| 722 | +/* |
|---|
| 723 | + * struct rkcif_tools_vdev - CIF Capture device |
|---|
| 724 | + * |
|---|
| 725 | + * @irq_lock: buffer queue lock |
|---|
| 726 | + * @stat: stats buffer list |
|---|
| 727 | + * @readout_wq: workqueue for statistics information read |
|---|
| 728 | + */ |
|---|
| 729 | +struct rkcif_tools_vdev { |
|---|
| 730 | + unsigned int ch:3; |
|---|
| 731 | + struct rkcif_device *cifdev; |
|---|
| 732 | + struct rkcif_vdev_node vnode; |
|---|
| 733 | + struct rkcif_stream *stream; |
|---|
| 734 | + struct list_head buf_head; |
|---|
| 735 | + struct list_head buf_done_head; |
|---|
| 736 | + struct list_head src_buf_head; |
|---|
| 737 | + spinlock_t vbq_lock; /* vfd lock */ |
|---|
| 738 | + wait_queue_head_t wq_stopped; |
|---|
| 739 | + struct v4l2_pix_format_mplane pixm; |
|---|
| 740 | + const struct cif_output_fmt *tools_out_fmt; |
|---|
| 741 | + struct rkcif_buffer *curr_buf; |
|---|
| 742 | + struct work_struct work; |
|---|
| 743 | + enum rkcif_state state; |
|---|
| 744 | + int frame_phase; |
|---|
| 745 | + unsigned int frame_idx; |
|---|
| 746 | + bool stopping; |
|---|
| 747 | +}; |
|---|
| 748 | + |
|---|
| 749 | +static inline |
|---|
| 750 | +struct rkcif_tools_vdev *to_rkcif_tools_vdev(struct rkcif_vdev_node *vnode) |
|---|
| 751 | +{ |
|---|
| 752 | + return container_of(vnode, struct rkcif_tools_vdev, vnode); |
|---|
| 753 | +} |
|---|
| 754 | + |
|---|
| 755 | +void rkcif_init_tools_vdev(struct rkcif_device *cif_dev, u32 ch); |
|---|
| 756 | +int rkcif_register_tools_vdevs(struct rkcif_device *cif_dev, |
|---|
| 757 | + int stream_num, |
|---|
| 758 | + bool is_multi_input); |
|---|
| 759 | +void rkcif_unregister_tools_vdevs(struct rkcif_device *cif_dev, |
|---|
| 760 | + int stream_num); |
|---|
| 761 | + |
|---|
| 762 | +enum rkcif_err_state { |
|---|
| 763 | + RKCIF_ERR_ID0_NOT_BUF = 0x1, |
|---|
| 764 | + RKCIF_ERR_ID1_NOT_BUF = 0x2, |
|---|
| 765 | + RKCIF_ERR_ID2_NOT_BUF = 0x4, |
|---|
| 766 | + RKCIF_ERR_ID3_NOT_BUF = 0x8, |
|---|
| 767 | + RKCIF_ERR_ID0_TRIG_SIMULT = 0x10, |
|---|
| 768 | + RKCIF_ERR_ID1_TRIG_SIMULT = 0x20, |
|---|
| 769 | + RKCIF_ERR_ID2_TRIG_SIMULT = 0x40, |
|---|
| 770 | + RKCIF_ERR_ID3_TRIG_SIMULT = 0x80, |
|---|
| 771 | + RKCIF_ERR_SIZE = 0x100, |
|---|
| 772 | + RKCIF_ERR_OVERFLOW = 0x200, |
|---|
| 773 | + RKCIF_ERR_BANDWIDTH_LACK = 0x400, |
|---|
| 774 | + RKCIF_ERR_BUS = 0X800, |
|---|
| 775 | + RKCIF_ERR_ID0_MULTI_FS = 0x1000, |
|---|
| 776 | + RKCIF_ERR_ID1_MULTI_FS = 0x2000, |
|---|
| 777 | + RKCIF_ERR_ID2_MULTI_FS = 0x4000, |
|---|
| 778 | + RKCIF_ERR_ID3_MULTI_FS = 0x8000, |
|---|
| 779 | + RKCIF_ERR_PIXEL = 0x10000, |
|---|
| 780 | + RKCIF_ERR_LINE = 0x20000, |
|---|
| 781 | +}; |
|---|
| 782 | + |
|---|
| 783 | +struct rkcif_err_state_work { |
|---|
| 784 | + struct work_struct work; |
|---|
| 785 | + u64 last_timestamp; |
|---|
| 786 | + u32 err_state; |
|---|
| 787 | + u32 intstat; |
|---|
| 788 | + u32 lastline; |
|---|
| 789 | + u32 lastpixel; |
|---|
| 790 | +}; |
|---|
| 791 | + |
|---|
| 476 | 792 | /* |
|---|
| 477 | 793 | * struct rkcif_device - ISP platform device |
|---|
| 478 | 794 | * @base_addr: base register address |
|---|
| .. | .. |
|---|
| 492 | 808 | struct rkcif_sensor_info terminal_sensor; |
|---|
| 493 | 809 | |
|---|
| 494 | 810 | struct rkcif_stream stream[RKCIF_MULTI_STREAMS_NUM]; |
|---|
| 811 | + struct rkcif_scale_vdev scale_vdev[RKCIF_MULTI_STREAMS_NUM]; |
|---|
| 812 | + struct rkcif_tools_vdev tools_vdev[RKCIF_MAX_TOOLS_CH]; |
|---|
| 495 | 813 | struct rkcif_pipeline pipe; |
|---|
| 496 | 814 | |
|---|
| 497 | 815 | struct csi_channel_info channels[RKCIF_MAX_CSI_CHANNEL]; |
|---|
| 498 | 816 | int num_channels; |
|---|
| 499 | 817 | int chip_id; |
|---|
| 500 | 818 | atomic_t stream_cnt; |
|---|
| 501 | | - atomic_t fh_cnt; |
|---|
| 819 | + atomic_t power_cnt; |
|---|
| 502 | 820 | struct mutex stream_lock; /* lock between streams */ |
|---|
| 821 | + struct mutex scale_lock; /* lock between scale dev */ |
|---|
| 822 | + struct mutex tools_lock; /* lock between tools dev */ |
|---|
| 503 | 823 | enum rkcif_workmode workmode; |
|---|
| 504 | 824 | bool can_be_reset; |
|---|
| 505 | | - struct rkcif_hdr hdr; |
|---|
| 825 | + struct rkmodule_hdr_cfg hdr; |
|---|
| 506 | 826 | struct rkcif_buffer *rdbk_buf[RDBK_MAX]; |
|---|
| 827 | + struct rkcif_rx_buffer *rdbk_rx_buf[RDBK_MAX]; |
|---|
| 507 | 828 | struct rkcif_luma_vdev luma_vdev; |
|---|
| 508 | 829 | struct rkcif_lvds_subdev lvds_subdev; |
|---|
| 509 | 830 | struct rkcif_dvp_sof_subdev dvp_sof_subdev; |
|---|
| .. | .. |
|---|
| 511 | 832 | irqreturn_t (*isr_hdl)(int irq, struct rkcif_device *cif_dev); |
|---|
| 512 | 833 | int inf_id; |
|---|
| 513 | 834 | |
|---|
| 514 | | - struct sditf_priv *sditf; |
|---|
| 835 | + struct sditf_priv *sditf[RKCIF_MAX_SDITF]; |
|---|
| 515 | 836 | struct proc_dir_entry *proc_dir; |
|---|
| 516 | 837 | struct rkcif_irq_stats irq_stats; |
|---|
| 517 | 838 | spinlock_t hdr_lock; /* lock for hdr buf sync */ |
|---|
| 839 | + spinlock_t buffree_lock; |
|---|
| 518 | 840 | struct rkcif_timer reset_watchdog_timer; |
|---|
| 519 | | - struct notifier_block reset_notifier; /* reset for mipi csi crc err */ |
|---|
| 520 | 841 | struct rkcif_work_struct reset_work; |
|---|
| 842 | + int id_use_cnt; |
|---|
| 843 | + unsigned int csi_host_idx; |
|---|
| 521 | 844 | unsigned int dvp_sof_in_oneframe; |
|---|
| 522 | 845 | unsigned int wait_line; |
|---|
| 523 | 846 | unsigned int wait_line_bak; |
|---|
| 524 | 847 | unsigned int wait_line_cache; |
|---|
| 525 | | - struct rkcif_dummy_buffer dummy_buf; |
|---|
| 848 | + struct completion cmpl_ntf; |
|---|
| 849 | + struct csi2_dphy_hw *dphy_hw; |
|---|
| 850 | + phys_addr_t resmem_pa; |
|---|
| 851 | + size_t resmem_size; |
|---|
| 852 | + struct rk_tb_client tb_client; |
|---|
| 526 | 853 | bool is_start_hdr; |
|---|
| 854 | + bool reset_work_cancel; |
|---|
| 527 | 855 | bool iommu_en; |
|---|
| 528 | 856 | bool is_use_dummybuf; |
|---|
| 857 | + bool is_notifier_isp; |
|---|
| 858 | + bool is_thunderboot; |
|---|
| 859 | + bool is_rdbk_to_online; |
|---|
| 860 | + bool is_support_tools; |
|---|
| 861 | + int rdbk_debug; |
|---|
| 862 | + struct rkcif_sync_cfg sync_cfg; |
|---|
| 863 | + int sditf_cnt; |
|---|
| 864 | + u32 early_line; |
|---|
| 865 | + int isp_runtime_max; |
|---|
| 866 | + int sensor_linetime; |
|---|
| 867 | + u32 err_state; |
|---|
| 868 | + struct rkcif_err_state_work err_state_work; |
|---|
| 529 | 869 | }; |
|---|
| 530 | 870 | |
|---|
| 531 | 871 | extern struct platform_driver rkcif_plat_drv; |
|---|
| 872 | +void rkcif_set_fps(struct rkcif_stream *stream, struct rkcif_fps *fps); |
|---|
| 873 | +int rkcif_do_start_stream(struct rkcif_stream *stream, |
|---|
| 874 | + enum rkcif_stream_mode mode); |
|---|
| 875 | +void rkcif_do_stop_stream(struct rkcif_stream *stream, |
|---|
| 876 | + enum rkcif_stream_mode mode); |
|---|
| 877 | +void rkcif_irq_handle_scale(struct rkcif_device *cif_dev, |
|---|
| 878 | + unsigned int intstat_glb); |
|---|
| 879 | +void rkcif_buf_queue(struct vb2_buffer *vb); |
|---|
| 880 | + |
|---|
| 881 | +void rkcif_vb_done_tasklet(struct rkcif_stream *stream, struct rkcif_buffer *buf); |
|---|
| 882 | + |
|---|
| 883 | +int rkcif_scale_start(struct rkcif_scale_vdev *scale_vdev); |
|---|
| 884 | + |
|---|
| 885 | +const struct |
|---|
| 886 | +cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd, |
|---|
| 887 | + struct v4l2_rect *rect, |
|---|
| 888 | + u32 pad_id, struct csi_channel_info *csi_info); |
|---|
| 532 | 889 | |
|---|
| 533 | 890 | void rkcif_write_register(struct rkcif_device *dev, |
|---|
| 534 | 891 | enum cif_reg_index index, u32 val); |
|---|
| .. | .. |
|---|
| 551 | 908 | void rkcif_set_default_fmt(struct rkcif_device *cif_dev); |
|---|
| 552 | 909 | void rkcif_irq_oneframe(struct rkcif_device *cif_dev); |
|---|
| 553 | 910 | void rkcif_irq_pingpong(struct rkcif_device *cif_dev); |
|---|
| 554 | | -void rkcif_soft_reset(struct rkcif_device *cif_dev, |
|---|
| 555 | | - bool is_rst_iommu); |
|---|
| 911 | +void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev); |
|---|
| 912 | +unsigned int rkcif_irq_global(struct rkcif_device *cif_dev); |
|---|
| 913 | +void rkcif_irq_handle_toisp(struct rkcif_device *cif_dev, unsigned int intstat_glb); |
|---|
| 556 | 914 | int rkcif_register_lvds_subdev(struct rkcif_device *dev); |
|---|
| 557 | 915 | void rkcif_unregister_lvds_subdev(struct rkcif_device *dev); |
|---|
| 558 | 916 | int rkcif_register_dvp_sof_subdev(struct rkcif_device *dev); |
|---|
| 559 | 917 | void rkcif_unregister_dvp_sof_subdev(struct rkcif_device *dev); |
|---|
| 560 | 918 | void rkcif_irq_lite_lvds(struct rkcif_device *cif_dev); |
|---|
| 561 | | -u32 rkcif_get_sof(struct rkcif_device *cif_dev); |
|---|
| 562 | 919 | int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int inf_id); |
|---|
| 563 | 920 | int rkcif_plat_uninit(struct rkcif_device *cif_dev); |
|---|
| 564 | 921 | int rkcif_attach_hw(struct rkcif_device *cif_dev); |
|---|
| .. | .. |
|---|
| 569 | 926 | enum rkcif_clk_edge edge); |
|---|
| 570 | 927 | void rkcif_enable_dvp_clk_dual_edge(struct rkcif_device *dev, bool on); |
|---|
| 571 | 928 | void rkcif_reset_work(struct work_struct *work); |
|---|
| 572 | | -void rkcif_monitor_reset_event(struct rkcif_hw *hw); |
|---|
| 929 | + |
|---|
| 930 | +void rkcif_vb_done_oneframe(struct rkcif_stream *stream, |
|---|
| 931 | + struct vb2_v4l2_buffer *vb_done); |
|---|
| 932 | + |
|---|
| 933 | +int rkcif_init_rx_buf(struct rkcif_stream *stream, int buf_num); |
|---|
| 934 | +void rkcif_free_rx_buf(struct rkcif_stream *stream, int buf_num); |
|---|
| 935 | + |
|---|
| 936 | +int rkcif_set_fmt(struct rkcif_stream *stream, |
|---|
| 937 | + struct v4l2_pix_format_mplane *pixm, |
|---|
| 938 | + bool try); |
|---|
| 939 | +void rkcif_enable_dma_capture(struct rkcif_stream *stream, bool is_only_enable); |
|---|
| 940 | + |
|---|
| 941 | +void rkcif_do_soft_reset(struct rkcif_device *dev); |
|---|
| 942 | + |
|---|
| 943 | +u32 rkcif_mbus_pixelcode_to_v4l2(u32 pixelcode); |
|---|
| 944 | + |
|---|
| 945 | +void rkcif_config_dvp_pin(struct rkcif_device *dev, bool on); |
|---|
| 946 | + |
|---|
| 947 | +s32 rkcif_get_sensor_vblank_def(struct rkcif_device *dev); |
|---|
| 948 | +s32 rkcif_get_sensor_vblank(struct rkcif_device *dev); |
|---|
| 949 | +int rkcif_get_linetime(struct rkcif_stream *stream); |
|---|
| 950 | + |
|---|
| 951 | +void rkcif_assign_check_buffer_update_toisp(struct rkcif_stream *stream); |
|---|
| 952 | + |
|---|
| 953 | +struct rkcif_rx_buffer *to_cif_rx_buf(struct rkisp_rx_buf *dbufs); |
|---|
| 954 | + |
|---|
| 955 | +int rkcif_clr_unready_dev(void); |
|---|
| 956 | + |
|---|
| 957 | +const struct |
|---|
| 958 | +cif_output_fmt *rkcif_find_output_fmt(struct rkcif_stream *stream, u32 pixelfmt); |
|---|
| 959 | +/* Rockit */ |
|---|
| 960 | +int rkcif_rockit_buf_done(struct rkcif_stream *stream, struct rkcif_buffer *buf); |
|---|
| 961 | +void rkcif_rockit_dev_init(struct rkcif_device *dev); |
|---|
| 962 | +void rkcif_rockit_dev_deinit(void); |
|---|
| 963 | + |
|---|
| 964 | +void rkcif_err_print_work(struct work_struct *work); |
|---|
| 573 | 965 | |
|---|
| 574 | 966 | #endif |
|---|