diff --git a/drivers/Makefile b/drivers/Makefile index 7a7b0250f0..691b7c0446 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -64,9 +64,11 @@ camera-$(CONFIG_SPECTRA_ISP) += \ cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.o \ cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.o \ cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.o \ - cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.o \ - cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid17x.o \ - cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.o \ + cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.o \ + cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.o \ + cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.o \ + cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_mod.o \ + cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite_mod.o \ cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.o \ cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.o \ cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.o \ @@ -219,7 +221,6 @@ camera-$(CONFIG_SPECTRA_TFE) += \ cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.o \ cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.o - camera-y += camera_main.o obj-$(CONFIG_SPECTRA_CAMERA) += camera.o diff --git a/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid480.h b/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid480.h index da98ebf104..f3fd098598 100644 --- a/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid480.h +++ b/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid480.h @@ -6,253 +6,269 @@ #ifndef _CAM_CUSTOM_CSID_480_H_ #define _CAM_CUSTOM_CSID_480_H_ -#include "cam_ife_csid_core.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" #define CAM_CSID_VERSION_V480 0x40080000 -static struct cam_ife_csid_udi_reg_offset +static struct cam_ife_csid_ver1_path_reg_info cam_custom_csid_480_udi_0_reg_offset = { - .csid_udi_irq_status_addr = 0x30, - .csid_udi_irq_mask_addr = 0x34, - .csid_udi_irq_clear_addr = 0x38, - .csid_udi_irq_set_addr = 0x3c, - .csid_udi_cfg0_addr = 0x200, - .csid_udi_cfg1_addr = 0x204, - .csid_udi_ctrl_addr = 0x208, - .csid_udi_frm_drop_pattern_addr = 0x20c, - .csid_udi_frm_drop_period_addr = 0x210, - .csid_udi_irq_subsample_pattern_addr = 0x214, - .csid_udi_irq_subsample_period_addr = 0x218, - .csid_udi_rpp_hcrop_addr = 0x21c, - .csid_udi_rpp_vcrop_addr = 0x220, - .csid_udi_rpp_pix_drop_pattern_addr = 0x224, - .csid_udi_rpp_pix_drop_period_addr = 0x228, - .csid_udi_rpp_line_drop_pattern_addr = 0x22c, - .csid_udi_rpp_line_drop_period_addr = 0x230, - .csid_udi_rst_strobes_addr = 0x240, - .csid_udi_status_addr = 0x250, - .csid_udi_misr_val0_addr = 0x254, - .csid_udi_misr_val1_addr = 0x258, - .csid_udi_misr_val2_addr = 0x25c, - .csid_udi_misr_val3_addr = 0x260, - .csid_udi_format_measure_cfg0_addr = 0x270, - .csid_udi_format_measure_cfg1_addr = 0x274, - .csid_udi_format_measure0_addr = 0x278, - .csid_udi_format_measure1_addr = 0x27c, - .csid_udi_format_measure2_addr = 0x280, - .csid_udi_timestamp_curr0_sof_addr = 0x290, - .csid_udi_timestamp_curr1_sof_addr = 0x294, - .csid_udi_timestamp_prev0_sof_addr = 0x298, - .csid_udi_timestamp_prev1_sof_addr = 0x29c, - .csid_udi_timestamp_curr0_eof_addr = 0x2a0, - .csid_udi_timestamp_curr1_eof_addr = 0x2a4, - .csid_udi_timestamp_prev0_eof_addr = 0x2a8, - .csid_udi_timestamp_prev1_eof_addr = 0x2ac, - .csid_udi_err_recovery_cfg0_addr = 0x2b0, - .csid_udi_err_recovery_cfg1_addr = 0x2b4, - .csid_udi_err_recovery_cfg2_addr = 0x2b8, - .csid_udi_multi_vcdt_cfg0_addr = 0x2bc, - .csid_udi_byte_cntr_ping_addr = 0x2e0, - .csid_udi_byte_cntr_pong_addr = 0x2e4, + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x250, + .misr_val0_addr = 0x254, + .misr_val1_addr = 0x258, + .misr_val2_addr = 0x25c, + .misr_val3_addr = 0x260, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, + .err_recovery_cfg0_addr = 0x2b0, + .err_recovery_cfg1_addr = 0x2b4, + .err_recovery_cfg2_addr = 0x2b8, + .multi_vcdt_cfg0_addr = 0x2bc, + .byte_cntr_ping_addr = 0x2e0, + .byte_cntr_pong_addr = 0x2e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 0, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .ccif_violation_en = 1, + .overflow_ctrl_en = 0, }; -static struct cam_ife_csid_udi_reg_offset +static struct cam_ife_csid_ver1_path_reg_info cam_custom_csid_480_udi_1_reg_offset = { - .csid_udi_irq_status_addr = 0x40, - .csid_udi_irq_mask_addr = 0x44, - .csid_udi_irq_clear_addr = 0x48, - .csid_udi_irq_set_addr = 0x4c, - .csid_udi_cfg0_addr = 0x300, - .csid_udi_cfg1_addr = 0x304, - .csid_udi_ctrl_addr = 0x308, - .csid_udi_frm_drop_pattern_addr = 0x30c, - .csid_udi_frm_drop_period_addr = 0x310, - .csid_udi_irq_subsample_pattern_addr = 0x314, - .csid_udi_irq_subsample_period_addr = 0x318, - .csid_udi_rpp_hcrop_addr = 0x31c, - .csid_udi_rpp_vcrop_addr = 0x320, - .csid_udi_rpp_pix_drop_pattern_addr = 0x324, - .csid_udi_rpp_pix_drop_period_addr = 0x328, - .csid_udi_rpp_line_drop_pattern_addr = 0x32c, - .csid_udi_rpp_line_drop_period_addr = 0x330, - .csid_udi_rst_strobes_addr = 0x340, - .csid_udi_status_addr = 0x350, - .csid_udi_misr_val0_addr = 0x354, - .csid_udi_misr_val1_addr = 0x358, - .csid_udi_misr_val2_addr = 0x35c, - .csid_udi_misr_val3_addr = 0x360, - .csid_udi_format_measure_cfg0_addr = 0x370, - .csid_udi_format_measure_cfg1_addr = 0x374, - .csid_udi_format_measure0_addr = 0x378, - .csid_udi_format_measure1_addr = 0x37c, - .csid_udi_format_measure2_addr = 0x380, - .csid_udi_timestamp_curr0_sof_addr = 0x390, - .csid_udi_timestamp_curr1_sof_addr = 0x394, - .csid_udi_timestamp_prev0_sof_addr = 0x398, - .csid_udi_timestamp_prev1_sof_addr = 0x39c, - .csid_udi_timestamp_curr0_eof_addr = 0x3a0, - .csid_udi_timestamp_curr1_eof_addr = 0x3a4, - .csid_udi_timestamp_prev0_eof_addr = 0x3a8, - .csid_udi_timestamp_prev1_eof_addr = 0x3ac, - .csid_udi_err_recovery_cfg0_addr = 0x3b0, - .csid_udi_err_recovery_cfg1_addr = 0x3b4, - .csid_udi_err_recovery_cfg2_addr = 0x3b8, - .csid_udi_multi_vcdt_cfg0_addr = 0x3bc, - .csid_udi_byte_cntr_ping_addr = 0x3e0, - .csid_udi_byte_cntr_pong_addr = 0x3e4, + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .err_recovery_cfg0_addr = 0x3b0, + .err_recovery_cfg1_addr = 0x3b4, + .err_recovery_cfg2_addr = 0x3b8, + .multi_vcdt_cfg0_addr = 0x3bc, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 0, + .mipi_pack_supported = 1, + .packing_fmt_shift_val = 30, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .timestamp_en_shift_val = 2, + .ccif_violation_en = 1, + .format_measure_en_shift_val = 1, + .overflow_ctrl_en = 0, + .non_fatal_err_mask = 0x28000, + .non_fatal_err_mask = 0x4, + .overflow_ctrl_mode_val = 0x8, }; -static struct cam_ife_csid_udi_reg_offset +static struct cam_ife_csid_ver1_path_reg_info cam_custom_csid_480_udi_2_reg_offset = { - .csid_udi_irq_status_addr = 0x50, - .csid_udi_irq_mask_addr = 0x54, - .csid_udi_irq_clear_addr = 0x58, - .csid_udi_irq_set_addr = 0x5c, - .csid_udi_cfg0_addr = 0x400, - .csid_udi_cfg1_addr = 0x404, - .csid_udi_ctrl_addr = 0x408, - .csid_udi_frm_drop_pattern_addr = 0x40c, - .csid_udi_frm_drop_period_addr = 0x410, - .csid_udi_irq_subsample_pattern_addr = 0x414, - .csid_udi_irq_subsample_period_addr = 0x418, - .csid_udi_rpp_hcrop_addr = 0x41c, - .csid_udi_rpp_vcrop_addr = 0x420, - .csid_udi_rpp_pix_drop_pattern_addr = 0x424, - .csid_udi_rpp_pix_drop_period_addr = 0x428, - .csid_udi_rpp_line_drop_pattern_addr = 0x42c, - .csid_udi_rpp_line_drop_period_addr = 0x430, - .csid_udi_yuv_chroma_conversion_addr = 0x434, - .csid_udi_rst_strobes_addr = 0x440, - .csid_udi_status_addr = 0x450, - .csid_udi_misr_val0_addr = 0x454, - .csid_udi_misr_val1_addr = 0x458, - .csid_udi_misr_val2_addr = 0x45c, - .csid_udi_misr_val3_addr = 0x460, - .csid_udi_format_measure_cfg0_addr = 0x470, - .csid_udi_format_measure_cfg1_addr = 0x474, - .csid_udi_format_measure0_addr = 0x478, - .csid_udi_format_measure1_addr = 0x47c, - .csid_udi_format_measure2_addr = 0x480, - .csid_udi_timestamp_curr0_sof_addr = 0x490, - .csid_udi_timestamp_curr1_sof_addr = 0x494, - .csid_udi_timestamp_prev0_sof_addr = 0x498, - .csid_udi_timestamp_prev1_sof_addr = 0x49c, - .csid_udi_timestamp_curr0_eof_addr = 0x4a0, - .csid_udi_timestamp_curr1_eof_addr = 0x4a4, - .csid_udi_timestamp_prev0_eof_addr = 0x4a8, - .csid_udi_timestamp_prev1_eof_addr = 0x4ac, - .csid_udi_err_recovery_cfg0_addr = 0x4b0, - .csid_udi_err_recovery_cfg1_addr = 0x4b4, - .csid_udi_err_recovery_cfg2_addr = 0x4b8, - .csid_udi_multi_vcdt_cfg0_addr = 0x4bc, - .csid_udi_byte_cntr_ping_addr = 0x4e0, - .csid_udi_byte_cntr_pong_addr = 0x4e4, + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .yuv_chroma_conversion_addr = 0x434, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .err_recovery_cfg0_addr = 0x4b0, + .err_recovery_cfg1_addr = 0x4b4, + .err_recovery_cfg2_addr = 0x4b8, + .multi_vcdt_cfg0_addr = 0x4bc, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 0, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .ccif_violation_en = 1, + .overflow_ctrl_en = 0, }; -static struct cam_ife_csid_csi2_rx_reg_offset - cam_custom_csid_480_csi2_reg_offset = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, +static struct cam_ife_csid_csi2_rx_reg_info + cam_custom_csid_480_csi2_reg_info = { + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_de_scramble_cfg0_addr = 0x114, - .csid_csi2_rx_de_scramble_cfg1_addr = 0x118, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .de_scramble_cfg0_addr = 0x114, + .de_scramble_cfg1_addr = 0x118, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x3, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x3, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, }; -static struct cam_ife_csid_common_reg_offset +static struct cam_ife_csid_ver1_common_reg_info cam_custom_csid_480_cmn_reg_offset = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 1, - .minor_version = 7, - .version_incr = 0, - .num_udis = 3, - .num_rdis = 0, - .num_pix = 0, - .num_ppp = 0, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .crop_shift = 16, - .ipp_irq_mask_all = 0, - .rdi_irq_mask_all = 0, - .ppp_irq_mask_all = 0, - .udi_irq_mask_all = 0x7FFF, - .measure_en_hbi_vbi_cnt_mask = 0xC, - .format_measure_en_val = 1, - .num_bytes_out_shift_val = 3, + .major_version = 1, + .minor_version = 7, + .version_incr = 0, + .num_udis = 3, + .num_rdis = 0, + .num_pix = 0, + .num_ppp = 0, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .ipp_irq_mask_all = 0, + .rdi_irq_mask_all = 0, + .ppp_irq_mask_all = 0, + .udi_irq_mask_all = 0x7FFF, + .measure_en_hbi_vbi_cnt_mask = 0xC, + .num_bytes_out_shift_val = 3, }; -static struct cam_ife_csid_reg_offset cam_custom_csid_480_reg_offset = { +static struct cam_ife_csid_ver1_reg_info cam_custom_csid_480_reg_offset = { .cmn_reg = &cam_custom_csid_480_cmn_reg_offset, - .csi2_reg = &cam_custom_csid_480_csi2_reg_offset, + .csi2_reg = &cam_custom_csid_480_csi2_reg_info, .ipp_reg = NULL, .ppp_reg = NULL, .rdi_reg = { diff --git a/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid_dev.c b/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid_dev.c index a4cee0f200..a785bce05e 100644 --- a/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid_dev.c +++ b/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid_dev.c @@ -9,7 +9,7 @@ #include #include "linux/module.h" #include "cam_custom_csid_dev.h" -#include "cam_ife_csid_core.h" +#include "cam_ife_csid_common.h" #include "cam_hw.h" #include "cam_hw_intf.h" #include "cam_custom_csid480.h" @@ -23,20 +23,18 @@ static struct cam_hw_intf *cam_custom_csid_hw_list[CAM_IFE_CSID_HW_NUM_MAX] = { static char csid_dev_name[16]; -static struct cam_ife_csid_hw_info cam_custom_csid480_hw_info = { +static struct cam_ife_csid_core_info cam_custom_csid480_hw_info = { .csid_reg = &cam_custom_csid_480_reg_offset, - .hw_dts_version = CAM_CSID_VERSION_V480, + .sw_version = CAM_IFE_CSID_VER_1_0, }; static int cam_custom_csid_component_bind(struct device *dev, struct device *master_dev, void *data) { - struct cam_hw_intf *csid_hw_intf; struct cam_hw_info *csid_hw_info; - struct cam_ife_csid_hw *csid_dev = NULL; const struct of_device_id *match_dev = NULL; - struct cam_ife_csid_hw_info *csid_hw_data = NULL; + struct cam_ife_csid_core_info *csid_core_info = NULL; uint32_t csid_dev_idx; int rc = 0; struct platform_device *pdev = to_platform_device(dev); @@ -48,17 +46,12 @@ static int cam_custom_csid_component_bind(struct device *dev, } csid_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); + if (!csid_hw_info) { rc = -ENOMEM; goto free_hw_intf; } - csid_dev = kzalloc(sizeof(struct cam_ife_csid_hw), GFP_KERNEL); - if (!csid_dev) { - rc = -ENOMEM; - goto free_hw_info; - } - /* get custom csid hw index */ of_property_read_u32(pdev->dev.of_node, "cell-index", &csid_dev_idx); /* get custom csid hw information */ @@ -68,7 +61,7 @@ static int cam_custom_csid_component_bind(struct device *dev, CAM_ERR(CAM_CUSTOM, "No matching table for the CUSTOM CSID HW!"); rc = -EINVAL; - goto free_dev; + goto free_hw_info; } memset(csid_dev_name, 0, sizeof(csid_dev_name)); @@ -79,33 +72,36 @@ static int cam_custom_csid_component_bind(struct device *dev, csid_hw_intf->hw_type = CAM_ISP_HW_TYPE_IFE_CSID; csid_hw_intf->hw_priv = csid_hw_info; - csid_hw_info->core_info = csid_dev; csid_hw_info->soc_info.pdev = pdev; csid_hw_info->soc_info.dev = &pdev->dev; csid_hw_info->soc_info.dev_name = csid_dev_name; csid_hw_info->soc_info.index = csid_dev_idx; - csid_hw_data = (struct cam_ife_csid_hw_info *)match_dev->data; - csid_dev->csid_info = csid_hw_data; + csid_core_info = (struct cam_ife_csid_core_info *)match_dev->data; - rc = cam_ife_csid_hw_probe_init(csid_hw_intf, csid_dev_idx, true); - if (rc) - goto free_dev; + /* call the driver init and fill csid_hw_info->core_info */ + rc = cam_ife_csid_hw_probe_init(csid_hw_intf, csid_core_info, true); - platform_set_drvdata(pdev, csid_dev); + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] probe init failed", + csid_dev_idx); + goto free_hw_info; + } + + platform_set_drvdata(pdev, csid_hw_intf); + CAM_DBG(CAM_ISP, "CSID:%d component bound successfully", + csid_hw_intf->hw_idx); if (csid_hw_intf->hw_idx < CAM_IFE_CSID_HW_NUM_MAX) cam_custom_csid_hw_list[csid_hw_intf->hw_idx] = csid_hw_intf; else - goto free_dev; + goto free_hw_info; CAM_DBG(CAM_CUSTOM, "CSID:%d component bound successfully", csid_hw_intf->hw_idx); return 0; -free_dev: - kfree(csid_dev); free_hw_info: kfree(csid_hw_info); free_hw_intf: @@ -117,22 +113,30 @@ err: static void cam_custom_csid_component_unbind(struct device *dev, struct device *master_dev, void *data) { - struct cam_ife_csid_hw *csid_dev = NULL; struct cam_hw_intf *csid_hw_intf; struct cam_hw_info *csid_hw_info; + struct cam_ife_csid_core_info *core_info = NULL; struct platform_device *pdev = to_platform_device(dev); + const struct of_device_id *match_dev = NULL; - csid_dev = (struct cam_ife_csid_hw *)platform_get_drvdata(pdev); - csid_hw_intf = csid_dev->hw_intf; - csid_hw_info = csid_dev->hw_info; + csid_hw_intf = (struct cam_hw_intf *)platform_get_drvdata(pdev); + csid_hw_info = csid_hw_intf->hw_priv; CAM_DBG(CAM_CUSTOM, "CSID:%d component unbind", - csid_dev->hw_intf->hw_idx); + csid_hw_intf->hw_idx); - cam_ife_csid_hw_deinit(csid_dev); + match_dev = of_match_device(pdev->dev.driver->of_match_table, + &pdev->dev); + if (!match_dev) { + CAM_ERR(CAM_ISP, "No matching table for the IFE CSID HW!"); + goto free_mem; + } + + cam_ife_csid_hw_deinit(csid_hw_intf, core_info); + +free_mem: /*release the csid device memory */ - kfree(csid_dev); kfree(csid_hw_info); kfree(csid_hw_intf); } @@ -169,7 +173,7 @@ static const struct of_device_id cam_custom_csid_dt_match[] = { .compatible = "qcom,csid-custom580", .data = &cam_custom_csid480_hw_info }, - {} + {}, }; MODULE_DEVICE_TABLE(of, cam_custom_csid_dt_match); diff --git a/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c b/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c index 91a4e2ef26..b5a2f805e0 100644 --- a/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c +++ b/drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c @@ -777,7 +777,6 @@ static int cam_custom_hw_mgr_acquire_csid_res( memset(&custom_csid_acquire, 0, sizeof(custom_csid_acquire)); custom_csid_acquire.res_id = path_res_id; custom_csid_acquire.res_type = CAM_ISP_RESOURCE_PIX_PATH; - custom_csid_acquire.cid = cid_rsrc_node->res_id; custom_csid_acquire.in_port = in_port_info; custom_csid_acquire.out_port = out_port; custom_csid_acquire.sync_mode = 0; diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index b6e9cb1e41..63b1335154 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -325,36 +325,45 @@ static int cam_ife_hw_mgr_is_rdi_res(uint32_t res_id) return rc; } -static int cam_ife_hw_mgr_reset_csid_res( - struct cam_isp_hw_mgr_res *isp_hw_res) +static int cam_ife_hw_mgr_reset_csid( + struct cam_ife_hw_mgr_ctx *ctx, + int reset_type) { int i; int rc = 0; struct cam_hw_intf *hw_intf; - struct cam_csid_reset_cfg_args csid_reset_args; + struct cam_csid_reset_cfg_args reset_args; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_ife_hw_mgr *hw_mgr; + unsigned long hw_idx_bitmap[CAM_IFE_CSID_HW_NUM_MAX] = {0}; - csid_reset_args.reset_type = CAM_IFE_CSID_RESET_PATH; + hw_mgr = ctx->hw_mgr; - for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { - if (!isp_hw_res->hw_res[i]) - continue; - csid_reset_args.node_res = isp_hw_res->hw_res[i]; - hw_intf = isp_hw_res->hw_res[i]->hw_intf; - CAM_DBG(CAM_ISP, "Resetting csid hardware %d", - hw_intf->hw_idx); - if (hw_intf->hw_ops.reset) { - rc = hw_intf->hw_ops.reset(hw_intf->hw_priv, - &csid_reset_args, - sizeof(struct cam_csid_reset_cfg_args)); + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + + if (!hw_mgr_res->hw_res[i]) + continue; + + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + + if ((hw_mgr->csid_global_reset_en) && + (test_bit(hw_intf->hw_idx, hw_idx_bitmap))) + continue; + reset_args.reset_type = reset_type; + reset_args.node_res = hw_mgr_res->hw_res[i]; + rc = hw_intf->hw_ops.reset(hw_intf->hw_priv, + &reset_args, sizeof(reset_args)); + set_bit(hw_intf->hw_idx, hw_idx_bitmap); if (rc) goto err; } } - return 0; + return rc; err: CAM_ERR(CAM_ISP, "RESET HW res failed: (type:%d, id:%d)", - isp_hw_res->res_type, isp_hw_res->res_id); + hw_mgr_res->res_type, hw_mgr_res->res_id); return rc; } @@ -476,6 +485,7 @@ static void cam_ife_hw_mgr_deinit_hw( struct cam_ife_hw_mgr_ctx *ctx) { struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_ife_hw_mgr *hw_mgr; int i = 0; if (!ctx->init_done) { @@ -483,14 +493,13 @@ static void cam_ife_hw_mgr_deinit_hw( return; } + hw_mgr = ctx->hw_mgr; + if (ctx->is_tpg) cam_ife_hw_mgr_deinit_hw_res(&ctx->res_list_tpg); - /* Deinit IFE CID */ - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) { - CAM_DBG(CAM_ISP, "%s: Going to DeInit IFE CID\n", __func__); - cam_ife_hw_mgr_deinit_hw_res(hw_mgr_res); - } + if (hw_mgr->csid_global_reset_en) + cam_ife_hw_mgr_reset_csid(ctx, CAM_IFE_CSID_RESET_GLOBAL); /* Deinit IFE CSID */ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { @@ -519,6 +528,7 @@ static int cam_ife_hw_mgr_init_hw( struct cam_ife_hw_mgr_ctx *ctx) { struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_ife_hw_mgr *hw_mgr; int rc = 0, i; if (ctx->is_tpg) { @@ -532,31 +542,6 @@ static int cam_ife_hw_mgr_init_hw( } } - CAM_DBG(CAM_ISP, "INIT IFE CID ... in ctx id:%d", - ctx->ctx_index); - /* INIT IFE CID */ - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) { - rc = cam_ife_hw_mgr_init_hw_res(hw_mgr_res); - if (rc) { - CAM_ERR(CAM_ISP, "Can not INIT IFE CID(id :%d)", - hw_mgr_res->res_id); - goto deinit; - } - } - - CAM_DBG(CAM_ISP, "INIT IFE csid ... in ctx id:%d", - ctx->ctx_index); - - /* INIT IFE csid */ - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { - rc = cam_ife_hw_mgr_init_hw_res(hw_mgr_res); - if (rc) { - CAM_ERR(CAM_ISP, "Can not INIT IFE CSID(id :%d)", - hw_mgr_res->res_id); - goto deinit; - } - } - /* INIT IFE SRC */ CAM_DBG(CAM_ISP, "INIT IFE SRC in ctx id:%d", ctx->ctx_index); @@ -569,6 +554,9 @@ static int cam_ife_hw_mgr_init_hw( } } + CAM_DBG(CAM_ISP, "INIT IFE csid ... in ctx id:%d", + ctx->ctx_index); + /* INIT IFE BUS RD */ CAM_DBG(CAM_ISP, "INIT IFE BUS RD in ctx id:%d", ctx->ctx_index); @@ -594,6 +582,26 @@ static int cam_ife_hw_mgr_init_hw( } } + /* INIT IFE csid */ + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + rc = cam_ife_hw_mgr_init_hw_res(hw_mgr_res); + if (rc) { + CAM_ERR(CAM_ISP, "Can not INIT IFE CSID(id :%d)", + hw_mgr_res->res_id); + goto deinit; + } + } + + hw_mgr = ctx->hw_mgr; + + if (hw_mgr->csid_global_reset_en) { + rc = cam_ife_hw_mgr_reset_csid(ctx, CAM_IFE_CSID_RESET_GLOBAL); + if (rc) { + CAM_ERR(CAM_ISP, "CSID reset failed"); + goto deinit; + } + } + return rc; deinit: ctx->init_done = true; @@ -877,22 +885,6 @@ static void cam_ife_hw_mgr_dump_acq_data( (hwr_mgr_ctx->is_rdi_only_context ? "true" : "false"), (hwr_mgr_ctx->is_dual ? "true" : "false")); - /* Iterate over CID resources */ - list_for_each_entry_safe(hw_mgr_res, hw_mgr_res_temp, - &hwr_mgr_ctx->res_list_ife_cid, list) { - for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { - hw_res = hw_mgr_res->hw_res[i]; - if (hw_res && hw_res->hw_intf) { - CAM_INFO(CAM_ISP, - "CID split_id: %d res_id: %u hw_idx: %u state: %s", - i, hw_res->res_id, - hw_res->hw_intf->hw_idx, - cam_ife_hw_mgr_get_res_state - (hw_res->res_state)); - } - } - } - /* Iterate over CSID resources */ list_for_each_entry_safe(hw_mgr_res, hw_mgr_res_temp, &hwr_mgr_ctx->res_list_ife_csid, list) { @@ -1078,13 +1070,6 @@ static int cam_ife_hw_mgr_release_hw_for_ctx( cam_ife_hw_mgr_put_res(&ife_ctx->free_res_list, &hw_mgr_res); } - /* ife cid resource */ - list_for_each_entry_safe(hw_mgr_res, hw_mgr_res_temp, - &ife_ctx->res_list_ife_cid, list) { - cam_ife_hw_mgr_free_hw_res(hw_mgr_res); - cam_ife_hw_mgr_put_res(&ife_ctx->free_res_list, &hw_mgr_res); - } - /* ife phy tpg resource */ if (ife_ctx->is_tpg) cam_ife_hw_mgr_free_hw_res(&ife_ctx->res_list_tpg); @@ -1097,6 +1082,8 @@ static int cam_ife_hw_mgr_release_hw_for_ctx( ife_ctx->common.cb_priv = NULL; memset(ife_ctx->common.event_cb, 0, sizeof(ife_ctx->common.event_cb)); + ife_ctx->need_csid_top_cfg = false; + CAM_DBG(CAM_ISP, "release context completed ctx id:%d", ife_ctx->ctx_index); @@ -1348,6 +1335,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( vfe_acquire.vfe_out.is_dual = ife_src_res->is_dual_isp; vfe_acquire.vfe_out.unique_id = ife_ctx->ctx_index; vfe_acquire.event_cb = cam_ife_hw_mgr_event_handler; + vfe_acquire.buf_done_controller = ife_ctx->buf_done_controller; for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) { if (!ife_src_res->hw_res[j]) @@ -1696,22 +1684,78 @@ err: } static int cam_ife_hw_mgr_acquire_csid_hw( - struct cam_ife_hw_mgr *ife_hw_mgr, + struct cam_ife_hw_mgr_ctx *ife_ctx, struct cam_csid_hw_reserve_resource_args *csid_acquire, - bool is_start_lower_idx) + struct cam_isp_in_port_generic_info *in_port) { int i; int rc = -EINVAL; struct cam_hw_intf *hw_intf; + struct cam_ife_hw_mgr *ife_hw_mgr; + bool is_start_lower_idx = false; + struct cam_isp_hw_mgr_res *csid_res_iterator; + struct cam_isp_out_port_generic_info *out_port = NULL; - if (!ife_hw_mgr || !csid_acquire) { + if (!ife_ctx || !csid_acquire) { CAM_ERR(CAM_ISP, - "Invalid args ife hw mgr %pK csid_acquire %pK", - ife_hw_mgr, csid_acquire); + "Invalid args ife hw ctx %pK csid_acquire %pK", + ife_ctx, csid_acquire); return -EINVAL; } - CAM_DBG(CAM_ISP, "Acquire CSID HW lower_idx: %d", is_start_lower_idx); + if (ife_ctx->is_fe_enabled || ife_ctx->dsp_enabled) + is_start_lower_idx = true; + + ife_hw_mgr = ife_ctx->hw_mgr; + + if (ife_ctx->is_tpg) { + if (ife_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx == 0) + csid_acquire->phy_sel = CAM_ISP_IFE_IN_RES_PHY_0; + else + csid_acquire->phy_sel = CAM_ISP_IFE_IN_RES_PHY_1; + } + + if (ife_ctx->is_rdi_only_context) + csid_acquire->can_use_lite = true; + + if (in_port->num_out_res) + out_port = &(in_port->data[0]); + ife_ctx->is_dual = (bool)in_port->usage_type; + + /* Try acquiring CSID from previously acquired HW */ + list_for_each_entry(csid_res_iterator, &ife_ctx->res_list_ife_csid, + list) { + + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!csid_res_iterator->hw_res[i]) + continue; + if (in_port->num_out_res && + ((csid_res_iterator->is_secure == 1 && + out_port->secure_mode == 0) || + (csid_res_iterator->is_secure == 0 && + out_port->secure_mode == 1))) + continue; + if (!in_port->num_out_res && + csid_res_iterator->is_secure == 1) + continue; + + hw_intf = csid_res_iterator->hw_res[i]->hw_intf; + rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, + csid_acquire, sizeof(*csid_acquire)); + if (rc) { + CAM_DBG(CAM_ISP, + "No ife resource from hw %d", + hw_intf->hw_idx); + continue; + } + CAM_DBG(CAM_ISP, + "acquired from old csid(%s)=%d successfully", + (i == 0) ? "left" : "right", + hw_intf->hw_idx); + goto acquire_successful; + } + } + if (is_start_lower_idx) { for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { if (!ife_hw_mgr->csid_devices[i]) @@ -1741,208 +1785,8 @@ static int cam_ife_hw_mgr_acquire_csid_hw( return rc; } - return rc; -} - -static int cam_ife_mgr_acquire_cid_res( - struct cam_ife_hw_mgr_ctx *ife_ctx, - struct cam_isp_in_port_generic_info *in_port, - struct cam_isp_hw_mgr_res **cid_res, - enum cam_ife_pix_path_res_id path_res_id) -{ - int rc = -1; - int i, j; - struct cam_ife_hw_mgr *ife_hw_mgr; - struct cam_hw_intf *hw_intf; - struct cam_isp_hw_mgr_res *cid_res_temp, *cid_res_iterator; - struct cam_csid_hw_reserve_resource_args csid_acquire = {0}; - uint32_t acquired_cnt = 0; - struct cam_isp_out_port_generic_info *out_port = NULL; - - ife_hw_mgr = ife_ctx->hw_mgr; - *cid_res = NULL; - - rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, cid_res); - if (rc) { - CAM_ERR(CAM_ISP, "No more free hw mgr resource"); - goto end; - } - - cid_res_temp = *cid_res; - - csid_acquire.res_type = CAM_ISP_RESOURCE_CID; - csid_acquire.in_port = in_port; - csid_acquire.res_id = path_res_id; - csid_acquire.node_res = NULL; - - if (ife_ctx->is_rdi_only_context) - csid_acquire.can_use_lite = true; - - CAM_DBG(CAM_ISP, "path_res_id %d", path_res_id); - - if (in_port->num_out_res) - out_port = &(in_port->data[0]); - - if (ife_ctx->is_tpg) { - if (ife_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx == 0) - csid_acquire.phy_sel = CAM_ISP_IFE_IN_RES_PHY_0; - else - csid_acquire.phy_sel = CAM_ISP_IFE_IN_RES_PHY_1; - } - - /* Try acquiring CID resource from previously acquired HW */ - list_for_each_entry(cid_res_iterator, &ife_ctx->res_list_ife_cid, - list) { - - for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { - if (!cid_res_iterator->hw_res[i]) - continue; - - if (in_port->num_out_res && - ((cid_res_iterator->is_secure == 1 && - out_port->secure_mode == 0) || - (cid_res_iterator->is_secure == 0 && - out_port->secure_mode == 1))) - continue; - - if (!in_port->num_out_res && - cid_res_iterator->is_secure == 1) - continue; - - hw_intf = cid_res_iterator->hw_res[i]->hw_intf; - rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, - &csid_acquire, sizeof(csid_acquire)); - if (rc) { - CAM_DBG(CAM_ISP, - "No ife cid resource from hw %d", - hw_intf->hw_idx); - continue; - } - - cid_res_temp->hw_res[acquired_cnt++] = - csid_acquire.node_res; - - CAM_DBG(CAM_ISP, - "acquired from old csid(%s)=%d CID rsrc successfully", - (i == 0) ? "left" : "right", - hw_intf->hw_idx); - - if (in_port->usage_type && acquired_cnt == 1 && - path_res_id == CAM_IFE_PIX_PATH_RES_IPP) - /* - * Continue to acquire Right for IPP. - * Dual IFE for RDI and PPP is not currently - * supported. - */ - - continue; - - if (acquired_cnt) - /* - * If successfully acquired CID from - * previously acquired HW, skip the next - * part - */ - goto acquire_successful; - } - } - - /* Acquire Left if not already acquired */ - /* For dual IFE cases, start acquiring the lower idx first */ - CAM_DBG(CAM_ISP, "acquire new rsrc fe: %d usage_type %d dsp %d rsrc %p", - ife_ctx->is_fe_enabled, in_port->usage_type, - ife_ctx->dsp_enabled, csid_acquire.node_res); - - if (ife_ctx->is_fe_enabled || - ife_ctx->dsp_enabled) - rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr, - &csid_acquire, true); - else - rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr, - &csid_acquire, false); - - if (rc || !csid_acquire.node_res) { - CAM_ERR(CAM_ISP, "No %d paths available rc %d rsrc %p", - path_res_id, rc, csid_acquire.node_res); - goto put_res; - } - - if (in_port->usage_type) - cid_res_temp->hw_res[++acquired_cnt] = csid_acquire.node_res; - else - cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res; - acquire_successful: - CAM_DBG(CAM_ISP, "CID %s acquired success is_dual %d", - (in_port->usage_type ? "Right" : " Left"), - in_port->usage_type); - - cid_res_temp->res_type = CAM_ISP_RESOURCE_CID; - /* CID(DT_ID) value of acquire device, require for path */ - cid_res_temp->res_id = csid_acquire.node_res->res_id; - cid_res_temp->is_dual_isp = in_port->usage_type; - ife_ctx->is_dual = (bool)in_port->usage_type; - if (in_port->num_out_res) - cid_res_temp->is_secure = out_port->secure_mode; - - cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_cid, cid_res); - - /* - * Acquire left if not already acquired. - * Dual IFE for RDI and PPP is not currently supported. - */ - if (cid_res_temp->is_dual_isp && path_res_id - == CAM_IFE_PIX_PATH_RES_IPP && acquired_cnt == 1) { - csid_acquire.node_res = NULL; - csid_acquire.res_type = CAM_ISP_RESOURCE_CID; - csid_acquire.in_port = in_port; - - if (ife_ctx->is_tpg) { - if (ife_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx - == 0) - csid_acquire.phy_sel = CAM_ISP_IFE_IN_RES_PHY_0; - else - csid_acquire.phy_sel = CAM_ISP_IFE_IN_RES_PHY_1; - } - - for (j = CAM_IFE_CSID_HW_NUM_MAX - 1; j >= 0; j--) { - if (!ife_hw_mgr->csid_devices[j]) - continue; - - if (j == cid_res_temp->hw_res[1]->hw_intf->hw_idx) - continue; - - hw_intf = ife_hw_mgr->csid_devices[j]; - rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, - &csid_acquire, sizeof(csid_acquire)); - if (rc) - continue; - else - break; - } - - if (j == -1 || !csid_acquire.node_res) { - CAM_ERR(CAM_ISP, - "Can not acquire ife csid dual resource"); - goto end; - } - cid_res_temp->hw_res[0] = csid_acquire.node_res; - ife_ctx->slave_hw_idx = - cid_res_temp->hw_res[1]->hw_intf->hw_idx; - ife_ctx->master_hw_idx = - cid_res_temp->hw_res[0]->hw_intf->hw_idx; - CAM_DBG(CAM_ISP, "CID left acquired success is_dual %d [master %u: slave %u]", - in_port->usage_type, - ife_ctx->master_hw_idx, - ife_ctx->slave_hw_idx); - } - - return 0; -put_res: - cam_ife_hw_mgr_put_res(&ife_ctx->free_res_list, cid_res); -end: return rc; - } static int cam_ife_hw_mgr_acquire_tpg( @@ -1995,30 +1839,22 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( { int rc = -1; int i; - int master_idx = -1; + struct cam_isp_out_port_generic_info *out_port = NULL; struct cam_ife_hw_mgr *ife_hw_mgr; struct cam_isp_hw_mgr_res *csid_res; - struct cam_isp_hw_mgr_res *cid_res; struct cam_hw_intf *hw_intf; - struct cam_csid_hw_reserve_resource_args csid_acquire; + struct cam_csid_hw_reserve_resource_args csid_acquire = {0}; enum cam_ife_pix_path_res_id path_res_id; + struct cam_ife_csid_dual_sync_args dual_sync_args = {0}; ife_hw_mgr = ife_ctx->hw_mgr; - /* get cid resource */ + if (is_ipp) path_res_id = CAM_IFE_PIX_PATH_RES_IPP; else path_res_id = CAM_IFE_PIX_PATH_RES_PPP; - rc = cam_ife_mgr_acquire_cid_res(ife_ctx, in_port, &cid_res, - path_res_id); - - if (rc) { - CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed"); - goto end; - } - rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &csid_res); if (rc) { CAM_ERR(CAM_ISP, "No more free hw mgr resource"); @@ -2028,6 +1864,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( csid_res->res_type = CAM_ISP_RESOURCE_PIX_PATH; csid_res->res_id = path_res_id; + ife_ctx->is_dual = (bool)in_port->usage_type; if (in_port->usage_type && is_ipp) csid_res->is_dual_isp = 1; @@ -2036,43 +1873,40 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( csid_acquire.sync_mode = CAM_ISP_HW_SYNC_NONE; } + if (in_port->num_out_res) { + out_port = &(in_port->data[0]); + csid_res->is_secure = out_port->secure_mode; + } + CAM_DBG(CAM_ISP, "CSID Acq: E"); - /* IPP resource needs to be from same HW as CID resource */ - for (i = 0; i <= csid_res->is_dual_isp; i++) { + + /* for dual ife, acquire the right ife first */ + for (i = csid_res->is_dual_isp; i >= 0 ; i--) { CAM_DBG(CAM_ISP, "i %d is_dual %d", i, csid_res->is_dual_isp); csid_acquire.res_type = CAM_ISP_RESOURCE_PIX_PATH; csid_acquire.res_id = path_res_id; - csid_acquire.cid = cid_res->hw_res[i]->res_id; csid_acquire.in_port = in_port; csid_acquire.out_port = in_port->data; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_ife_hw_mgr_event_handler; - csid_acquire.priv = ife_ctx; + csid_acquire.cb_priv = ife_ctx; csid_acquire.crop_enable = crop_enable; csid_acquire.drop_enable = false; - hw_intf = cid_res->hw_res[i]->hw_intf; + if (csid_res->is_dual_isp) + csid_acquire.sync_mode = i == CAM_ISP_HW_SPLIT_LEFT ? + CAM_ISP_HW_SYNC_MASTER : CAM_ISP_HW_SYNC_SLAVE; - if (csid_res->is_dual_isp) { - if (i == CAM_ISP_HW_SPLIT_LEFT) { - master_idx = hw_intf->hw_idx; - csid_acquire.sync_mode = - CAM_ISP_HW_SYNC_MASTER; - } else { - if (master_idx == -1) { - CAM_ERR(CAM_ISP, - "No Master found"); - goto put_res; - } - csid_acquire.sync_mode = - CAM_ISP_HW_SYNC_SLAVE; - csid_acquire.master_idx = master_idx; - } - } + csid_acquire.event_cb = cam_ife_hw_mgr_event_handler; + csid_acquire.tasklet = ife_ctx->common.tasklet_info; + csid_acquire.cb_priv = ife_ctx; + csid_acquire.cdm_ops = ife_ctx->cdm_ops; + + rc = cam_ife_hw_mgr_acquire_csid_hw(ife_ctx, + &csid_acquire, + in_port); - rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, - &csid_acquire, sizeof(csid_acquire)); if (rc) { CAM_ERR(CAM_ISP, "Cannot acquire ife csid pxl path rsrc %s", @@ -2081,16 +1915,57 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( } csid_res->hw_res[i] = csid_acquire.node_res; + hw_intf = csid_res->hw_res[i]->hw_intf; + + if (i == CAM_ISP_HW_SPLIT_LEFT) { + ife_ctx->master_hw_idx = hw_intf->hw_idx; + ife_ctx->buf_done_controller = + csid_acquire.buf_done_controller; + } else { + ife_ctx->slave_hw_idx = hw_intf->hw_idx; + } + + ife_ctx->need_csid_top_cfg = csid_acquire.need_top_cfg; + CAM_DBG(CAM_ISP, "acquired csid(%s)=%d pxl path rsrc %s successfully", (i == 0) ? "left" : "right", hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP"); } cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_csid, &csid_res); - cid_res->num_children++; - CAM_DBG(CAM_ISP, "acquire res %d CID children = %d", - csid_acquire.res_id, cid_res->num_children); + if (!is_ipp) + goto end; + + if (csid_res->is_dual_isp && ife_ctx->need_csid_top_cfg) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + + if (!csid_res->hw_res[i]) + continue; + + hw_intf = csid_res->hw_res[i]->hw_intf; + + if (i == CAM_ISP_HW_SPLIT_LEFT) { + dual_sync_args.sync_mode = + CAM_ISP_HW_SYNC_MASTER; + dual_sync_args.dual_core_id = + ife_ctx->slave_hw_idx; + + } else if (i == CAM_ISP_HW_SPLIT_RIGHT) { + dual_sync_args.sync_mode = + CAM_ISP_HW_SYNC_SLAVE; + dual_sync_args.dual_core_id = + ife_ctx->master_hw_idx; + } + + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_SET_DUAL_SYNC_CONFIG, + &dual_sync_args, + sizeof( + struct cam_ife_csid_dual_sync_args)); + } + } return 0; put_res: @@ -2104,6 +1979,7 @@ static enum cam_ife_pix_path_res_id uint32_t out_port_type) { enum cam_ife_pix_path_res_id path_id; + CAM_DBG(CAM_ISP, "out_port_type %x", out_port_type); switch (out_port_type) { @@ -2137,11 +2013,9 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( int rc = -EINVAL; int i; + struct cam_isp_out_port_generic_info *out_port = NULL; struct cam_ife_hw_mgr *ife_hw_mgr; struct cam_isp_hw_mgr_res *csid_res; - struct cam_isp_hw_mgr_res *cid_res; - struct cam_hw_intf *hw_intf; - struct cam_isp_out_port_generic_info *out_port; struct cam_csid_hw_reserve_resource_args csid_acquire; enum cam_ife_pix_path_res_id path_res_id; @@ -2154,15 +2028,6 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( if (path_res_id == CAM_IFE_PIX_PATH_RES_MAX) continue; - /* get cid resource */ - rc = cam_ife_mgr_acquire_cid_res(ife_ctx, in_port, &cid_res, - path_res_id); - if (rc) { - CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed"); - goto end; - } - - /* For each RDI we need CID + PATH resource */ rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &csid_res); if (rc) { @@ -2170,15 +2035,17 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( goto end; } + csid_res->is_secure = out_port->secure_mode; memset(&csid_acquire, 0, sizeof(csid_acquire)); csid_acquire.res_id = path_res_id; csid_acquire.res_type = CAM_ISP_RESOURCE_PIX_PATH; - csid_acquire.cid = cid_res->hw_res[0]->res_id; csid_acquire.in_port = in_port; csid_acquire.out_port = out_port; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_ife_hw_mgr_event_handler; - csid_acquire.priv = ife_ctx; + csid_acquire.tasklet = ife_ctx->common.tasklet_info; + csid_acquire.cb_priv = ife_ctx; + csid_acquire.cdm_ops = ife_ctx->cdm_ops; /* * Enable RDI pixel drop by default. CSID will enable only for @@ -2192,14 +2059,15 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( else csid_acquire.sync_mode = CAM_ISP_HW_SYNC_NONE; - hw_intf = cid_res->hw_res[0]->hw_intf; - rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, - &csid_acquire, sizeof(csid_acquire)); + rc = cam_ife_hw_mgr_acquire_csid_hw(ife_ctx, + &csid_acquire, + in_port); + if (rc) { CAM_ERR(CAM_ISP, - "CSID Path reserve failed hw=%d rc=%d cid=%d", - hw_intf->hw_idx, rc, - cid_res->hw_res[0]->res_id); + "CSID Path reserve failed rc=%d res_id=%d", + rc, + path_res_id); goto put_res; } @@ -2210,13 +2078,15 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( goto put_res; } + if (ife_ctx->is_rdi_only_context) + ife_ctx->buf_done_controller = + csid_acquire.buf_done_controller; csid_res->res_type = CAM_ISP_RESOURCE_PIX_PATH; csid_res->res_id = csid_acquire.res_id; csid_res->is_dual_isp = 0; csid_res->hw_res[0] = csid_acquire.node_res; csid_res->hw_res[1] = NULL; cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_csid, &csid_res); - cid_res->num_children++; } return 0; @@ -2414,9 +2284,6 @@ static int cam_ife_hw_mgr_preprocess_port( { uint32_t i; struct cam_isp_out_port_generic_info *out_port; - struct cam_ife_hw_mgr *ife_hw_mgr; - - ife_hw_mgr = ife_ctx->hw_mgr; if (in_port->res_type == CAM_ISP_IFE_IN_RES_RD) in_port->ife_rd_count++; @@ -2664,20 +2531,21 @@ static int cam_ife_mgr_acquire_hw_for_offline_ctx( { int rc = -1; - ife_ctx->is_dual = (bool)in_port->usage_type; + cam_ife_hw_mgr_preprocess_port(ife_ctx, in_port); if ((!in_port->ipp_count && !in_port->lcr_count) || !in_port->ife_rd_count) { + CAM_ERR(CAM_ISP, "Invalid %d BUS RD %d PIX %d LCR ports for FE ctx"); return -EINVAL; } + ife_ctx->is_dual = (bool)in_port->usage_type; if (in_port->rdi_count || in_port->ppp_count) { CAM_ERR(CAM_ISP, "%d RDI %d PPP ports invalid for FE ctx", in_port->rdi_count, in_port->ppp_count); - return -EINVAL; } rc = cam_ife_hw_mgr_acquire_res_ife_bus_rd(ife_ctx, in_port); @@ -2739,8 +2607,11 @@ static int cam_ife_mgr_acquire_hw_for_ctx( goto err; } + cam_ife_hw_mgr_preprocess_port(ife_ctx, in_port); + if (!in_port->ipp_count && !in_port->rdi_count && !in_port->ppp_count && !in_port->lcr_count) { + CAM_ERR(CAM_ISP, "No PIX or RDI or PPP or LCR resource"); return -EINVAL; @@ -2788,6 +2659,7 @@ static int cam_ife_mgr_acquire_hw_for_ctx( rc = cam_ife_hw_mgr_acquire_res_ife_csid_pxl(ife_ctx, in_port, false, crop_enable); + if (rc) { CAM_ERR(CAM_ISP, "Acquire IFE CSID PPP resource Failed"); @@ -2820,6 +2692,7 @@ static int cam_ife_mgr_acquire_hw_for_ctx( CAM_DBG(CAM_ISP, "Acquiring IFE OUT resource..."); rc = cam_ife_hw_mgr_acquire_res_ife_out(ife_ctx, in_port); + if (rc) { CAM_ERR(CAM_ISP, "Acquire IFE OUT resource Failed"); goto err; @@ -4074,19 +3947,6 @@ static int cam_ife_mgr_stop_hw_in_overflow(void *stop_hw_args) if (i == ctx->num_base) master_base_idx = ctx->base[0].idx; - - /* stop the master CIDs first */ - cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid, - master_base_idx, CAM_CSID_HALT_IMMEDIATELY); - - /* stop rest of the CIDs */ - for (i = 0; i < ctx->num_base; i++) { - if (i == master_base_idx) - continue; - cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid, - ctx->base[i].idx, CAM_CSID_HALT_IMMEDIATELY); - } - /* stop the master CSID path first */ cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, master_base_idx, CAM_CSID_HALT_IMMEDIATELY); @@ -4230,6 +4090,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx); + /* Stop the master CSID path first */ cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, master_base_idx, csid_halt_type); @@ -4245,22 +4106,6 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) ctx->base[i].idx, csid_halt_type); } - CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx); - - /* Stop the master CIDs first */ - cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid, - master_base_idx, csid_halt_type); - - /* stop rest of the CIDs */ - for (i = 0; i < ctx->num_base; i++) { - if (ctx->base[i].idx == master_base_idx) - continue; - CAM_DBG(CAM_ISP, "Stopping CID idx %d i %d master %d", - ctx->base[i].idx, i, master_base_idx); - cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_cid, - ctx->base[i].idx, csid_halt_type); - } - CAM_DBG(CAM_ISP, "Going to stop IFE Out"); /* IFE out resources */ @@ -4449,7 +4294,6 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args) } } - CAM_DBG(CAM_ISP, "START CID SRC ... in ctx id:%d", ctx->ctx_index); /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Exit...(success)"); return 0; @@ -4462,17 +4306,21 @@ err: static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) { - int rc = -1; - struct cam_isp_start_args *start_isp = start_hw_args; - struct cam_hw_stop_args stop_args; - struct cam_isp_stop_args stop_isp; - struct cam_ife_hw_mgr_ctx *ctx; - struct cam_isp_hw_mgr_res *hw_mgr_res; - struct cam_isp_resource_node *rsrc_node = NULL; - uint32_t i, j, camif_debug, disable_ubwc_comp; - bool res_rdi_context_set = false; - uint32_t primary_rdi_src_res; - uint32_t primary_rdi_out_res; + int rc = -1; + struct cam_isp_start_args *start_isp = start_hw_args; + struct cam_hw_stop_args stop_args; + struct cam_isp_stop_args stop_isp; + struct cam_ife_hw_mgr_ctx *ctx; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_isp_resource_node *rsrc_node = NULL; + uint32_t i, j; + uint32_t camif_debug, disable_ubwc_comp; + bool res_rdi_context_set = false; + uint32_t primary_rdi_src_res; + uint32_t primary_rdi_out_res; + uint32_t primary_rdi_csid_res; + struct cam_ife_csid_top_config_args csid_top_args = {0}; + struct cam_hw_intf *hw_intf; primary_rdi_src_res = CAM_ISP_HW_VFE_IN_MAX; primary_rdi_out_res = g_ife_hw_mgr.max_vfe_out_res_type; @@ -4517,12 +4365,32 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) /* set current csid debug information to CSID HW */ for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { - if (g_ife_hw_mgr.csid_devices[i]) + if (g_ife_hw_mgr.csid_devices[i]) { rc = g_ife_hw_mgr.csid_devices[i]->hw_ops.process_cmd( g_ife_hw_mgr.csid_devices[i]->hw_priv, CAM_IFE_CSID_SET_CSID_DEBUG, &g_ife_hw_mgr.debug_cfg.csid_debug, sizeof(g_ife_hw_mgr.debug_cfg.csid_debug)); + } + } + + if (ctx->need_csid_top_cfg) { + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, + list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + /*To be updated based on sfe context*/ + csid_top_args.input_core_type = + CAM_IFE_CSID_INPUT_CORE_IFE; + if (!hw_mgr_res->hw_res[i]) + continue; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_TOP_CONFIG, + &csid_top_args, + sizeof(csid_top_args)); + } + } } camif_debug = g_ife_hw_mgr.debug_cfg.camif_debug; @@ -4633,9 +4501,13 @@ start_only: } } - if (primary_rdi_out_res < g_ife_hw_mgr.max_vfe_out_res_type) + if (primary_rdi_out_res < g_ife_hw_mgr.max_vfe_out_res_type) { primary_rdi_src_res = cam_convert_rdi_out_res_id_to_src(primary_rdi_out_res); + primary_rdi_csid_res = + cam_ife_hw_mgr_get_ife_csid_rdi_res_type( + primary_rdi_out_res); + } CAM_DBG(CAM_ISP, "START IFE SRC ... in ctx id:%d", ctx->ctx_index); @@ -4668,6 +4540,10 @@ start_only: ctx->ctx_index); /* Start the IFE CSID HW devices */ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + if (primary_rdi_csid_res == hw_mgr_res->res_id) { + hw_mgr_res->hw_res[0]->rdi_only_ctx = + ctx->is_rdi_only_context; + } rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx); if (rc) { CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)", @@ -4676,18 +4552,6 @@ start_only: } } - CAM_DBG(CAM_ISP, "START CID SRC ... in ctx id:%d", - ctx->ctx_index); - /* Start the IFE CID HW devices */ - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) { - rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx); - if (rc) { - CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)", - hw_mgr_res->res_id); - goto err; - } - } - if (ctx->is_tpg) { CAM_DBG(CAM_ISP, "START TPG HW ... in ctx id:%d", ctx->ctx_index); @@ -4743,7 +4607,6 @@ static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args) struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv; struct cam_hw_reset_args *reset_args = hw_reset_args; struct cam_ife_hw_mgr_ctx *ctx; - struct cam_isp_hw_mgr_res *hw_mgr_res; int rc = 0, i = 0; if (!hw_mgr_priv || !hw_reset_args) { @@ -4758,13 +4621,13 @@ static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args) } CAM_DBG(CAM_ISP, "Reset CSID and VFE"); - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { - rc = cam_ife_hw_mgr_reset_csid_res(hw_mgr_res); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to reset CSID:%d rc: %d", - hw_mgr_res->res_id, rc); - goto end; - } + + rc = cam_ife_hw_mgr_reset_csid(ctx, CAM_IFE_CSID_RESET_PATH); + + if (rc) { + CAM_ERR(CAM_ISP, "Failed to reset CSID:%d rc: %d", + rc); + goto end; } for (i = 0; i < ctx->num_base; i++) { @@ -5381,6 +5244,9 @@ static int cam_isp_blob_csid_qcfa_update( if (hw_intf && hw_intf->hw_ops.process_cmd) { csid_qcfa_upd_args.qcfa_binning = qcfa_config->csid_binning; + csid_qcfa_upd_args.res = + hw_mgr_res->hw_res[i]; + CAM_DBG(CAM_ISP, "i= %d QCFA binning=%d\n", i, csid_qcfa_upd_args.qcfa_binning); @@ -5606,8 +5472,8 @@ static int cam_isp_blob_sensor_config( struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_ife_sensor_dimension_update_args update_args; - int rc = -EINVAL, found = 0; - uint32_t i, j; + int rc = -EINVAL; + uint32_t i; struct cam_isp_sensor_dimension *path_config; ctx = prepare->ctxt_to_hw_map; @@ -5616,51 +5482,29 @@ static int cam_isp_blob_sensor_config( for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; - found = 1; + + path_config = &(dim_config->ipp_path); + + if (!path_config->measure_enabled) + continue; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; - if (hw_intf && hw_intf->hw_ops.process_cmd) { - path_config = &(dim_config->ipp_path); - update_args.ipp_path.width = - path_config->width; - update_args.ipp_path.height = - path_config->height; - update_args.ipp_path.measure_enabled = - path_config->measure_enabled; - path_config = &(dim_config->ppp_path); - update_args.ppp_path.width = - path_config->width; - update_args.ppp_path.height = - path_config->height; - update_args.ppp_path.measure_enabled = - path_config->measure_enabled; - for (j = 0; j < CAM_IFE_RDI_NUM_MAX; j++) { - path_config = - &(dim_config->rdi_path[j]); - update_args.rdi_path[j].width = - path_config->width; - update_args.rdi_path[j].height = - path_config->height; - update_args.rdi_path[j].measure_enabled = - path_config->measure_enabled; - } - rc = hw_intf->hw_ops.process_cmd( - hw_intf->hw_priv, - CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, - &update_args, - sizeof( - struct - cam_ife_sensor_dimension_update_args) - ); - if (rc) { - CAM_ERR(CAM_ISP, - "Dimension Update failed"); - break; - } - } else - CAM_ERR(CAM_ISP, "hw_intf is NULL"); + + update_args.sensor_data.width = path_config->width; + update_args.sensor_data.height = path_config->width; + update_args.sensor_data.measure_enabled = + path_config->measure_enabled; + update_args.res = hw_mgr_res->hw_res[i]; + + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, + &update_args, + sizeof(update_args)); + if (rc) + CAM_ERR(CAM_ISP, + "Dimension Update failed"); } - if (found) - break; } return rc; @@ -6468,6 +6312,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, struct cam_isp_prepare_hw_update_data *prepare_hw_data; struct cam_isp_frame_header_info frame_header_info; struct cam_isp_change_base_args change_base_info = {0}; + struct list_head *res_list; if (!hw_mgr_priv || !prepare_hw_update_args) { CAM_ERR(CAM_ISP, "Invalid args"); @@ -6661,28 +6506,40 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, /* add reg update commands */ for (i = 0; i < ctx->num_base; i++) { + + if (hw_mgr->csid_rup_en) + res_list = &ctx->res_list_ife_csid; + else + res_list = &ctx->res_list_ife_src; + change_base_info.base_idx = ctx->base[i].idx; change_base_info.cdm_id = ctx->cdm_id; + /* Add change base */ if (!ctx->internal_cdm) { rc = cam_isp_add_change_base(prepare, - &ctx->res_list_ife_src, + res_list, &change_base_info, &kmd_buf); if (rc) { CAM_ERR(CAM_ISP, - "Failed in change base adding reg_update cmd i=%d, idx=%d, rc=%d", + "Add Change base cmd Failed i=%d, idx=%d, rc=%d", i, ctx->base[i].idx, rc); goto end; } } - /*Add reg update */ - rc = cam_isp_add_reg_update(prepare, &ctx->res_list_ife_src, - ctx->base[i].idx, &kmd_buf); + if (hw_mgr->csid_rup_en) + rc = cam_isp_add_csid_reg_update(prepare, + &ctx->res_list_ife_csid, + ctx->base[i].idx, &kmd_buf); + else + rc = cam_isp_add_reg_update(prepare, + &ctx->res_list_ife_src, + ctx->base[i].idx, &kmd_buf); if (rc) { CAM_ERR(CAM_ISP, - "Add Reg_update cmd Failed i=%d, idx=%d, rc=%d", + "Add Change base cmd Failed i=%d, idx=%d, rc=%d", i, ctx->base[i].idx, rc); goto end; } @@ -7357,7 +7214,6 @@ static int cam_ife_mgr_process_recovery_cb(void *priv, void *data) struct cam_hw_start_args start_args; struct cam_hw_stop_args stop_args; struct cam_ife_hw_mgr *ife_hw_mgr = priv; - struct cam_isp_hw_mgr_res *hw_mgr_res; uint32_t i = 0; uint32_t error_type = recovery_data->error_type; @@ -7394,14 +7250,12 @@ static int cam_ife_mgr_process_recovery_cb(void *priv, void *data) CAM_DBG(CAM_ISP, "RESET: CSID PATH"); for (i = 0; i < recovery_data->no_of_context; i++) { ctx = recovery_data->affected_ctx[i]; - list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, - list) { - rc = cam_ife_hw_mgr_reset_csid_res(hw_mgr_res); - if (rc) { - CAM_ERR(CAM_ISP, "Failed RESET (%d)", - hw_mgr_res->res_id); - return rc; - } + rc = cam_ife_hw_mgr_reset_csid(ctx, + CAM_IFE_CSID_RESET_PATH); + + if (rc) { + CAM_ERR(CAM_ISP, "Failed RESET"); + return rc; } } @@ -7600,6 +7454,108 @@ end: return 0; } +static int cam_ife_hw_mgr_handle_csid_error( + struct cam_isp_hw_event_info *event_info) +{ + int rc = 0; + struct cam_isp_hw_error_event_data error_event_data = {0}; + struct cam_ife_hw_event_recovery_data recovery_data = {0}; + + switch (event_info->err_type) { + + case CAM_ISP_HW_ERROR_CSID_FATAL: + if (!g_ife_hw_mgr.debug_cfg.enable_csid_recovery) + break; + error_event_data.error_type = event_info->err_type; + cam_ife_hw_mgr_find_affected_ctx(&error_event_data, + event_info->hw_idx, &recovery_data); + break; + default: + CAM_ERR(CAM_ISP, "Invalid event ID %d", + event_info->err_type); + rc = -EINVAL; + break; + } + + return rc; +} + +static int cam_ife_hw_mgr_handle_csid_rup( + void *ctx, + void *evt_info) +{ + struct cam_isp_hw_event_info *event_info = evt_info; + struct cam_ife_hw_mgr_ctx *ife_hw_mgr_ctx = ctx; + cam_hw_event_cb_func ife_hwr_irq_rup_cb; + struct cam_isp_hw_reg_update_event_data rup_event_data; + + ife_hwr_irq_rup_cb = + ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_REG_UPDATE]; + + switch (event_info->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + if ((ife_hw_mgr_ctx->is_dual) && + (event_info->hw_idx != + ife_hw_mgr_ctx->master_hw_idx)) + break; + + if (atomic_read(&ife_hw_mgr_ctx->overflow_pending)) + break; + ife_hwr_irq_rup_cb(ife_hw_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_REG_UPDATE, &rup_event_data); + break; + + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + if (!ife_hw_mgr_ctx->is_rdi_only_context) + break; + if (atomic_read(&ife_hw_mgr_ctx->overflow_pending)) + break; + ife_hwr_irq_rup_cb(ife_hw_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_REG_UPDATE, &rup_event_data); + break; + + case CAM_IFE_PIX_PATH_RES_PPP: + break; + default: + CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d", + event_info->res_id); + break; + } + + CAM_DBG(CAM_ISP, "RUP done for CSID:%d source %d", event_info->hw_idx, + event_info->res_id); + + return 0; +} + +static int cam_ife_hw_mgr_handle_csid_event( + void *ctx, + struct cam_isp_hw_event_info *event_info, + uint32_t evt_id) +{ + int rc = 0; + + switch (evt_id) { + + case CAM_ISP_HW_EVENT_ERROR: + rc = cam_ife_hw_mgr_handle_csid_error(event_info); + break; + default: + CAM_ERR(CAM_ISP, "Invalid event ID %d", + event_info->err_type); + rc = -EINVAL; + break; + } + + CAM_DBG(CAM_ISP, "CSID event %u", evt_id); + + return rc; +} + static int cam_ife_hw_mgr_handle_hw_dump_info( void *ctx, void *evt_info) @@ -7679,34 +7635,8 @@ static int cam_ife_hw_mgr_handle_hw_dump_info( return rc; } -static int cam_ife_hw_mgr_handle_csid_event( - struct cam_isp_hw_event_info *event_info) -{ - struct cam_isp_hw_error_event_data error_event_data = {0}; - struct cam_ife_hw_event_recovery_data recovery_data = {0}; - - /* this can be extended based on the types of error - * received from CSID - */ - switch (event_info->err_type) { - case CAM_ISP_HW_ERROR_CSID_FATAL: { - - if (!g_ife_hw_mgr.debug_cfg.enable_csid_recovery) - break; - - error_event_data.error_type = event_info->err_type; - cam_ife_hw_mgr_find_affected_ctx(&error_event_data, - event_info->hw_idx, - &recovery_data); - break; - } - default: - break; - } - return 0; -} - static int cam_ife_hw_mgr_handle_hw_err( + uint32_t evt_id, void *ctx, void *evt_info) { @@ -7717,18 +7647,12 @@ static int cam_ife_hw_mgr_handle_hw_err( struct cam_ife_hw_event_recovery_data recovery_data = {0}; int rc = -EINVAL; - if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION) - error_event_data.error_type = CAM_ISP_HW_ERROR_VIOLATION; - else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_IN) - error_event_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW; - else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT) - error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW; - spin_lock(&g_ife_hw_mgr.ctx_lock); + if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) { - rc = cam_ife_hw_mgr_handle_csid_event(event_info); - spin_unlock(&g_ife_hw_mgr.ctx_lock); - return rc; + rc = cam_ife_hw_mgr_handle_csid_event(ctx, event_info, + evt_id); + goto end; } if (ctx) { @@ -7743,6 +7667,13 @@ static int cam_ife_hw_mgr_handle_hw_err( ife_hw_mgr_ctx, event_info); } + if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION) + error_event_data.error_type = CAM_ISP_HW_ERROR_VIOLATION; + else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_IN) + error_event_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW; + else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT) + error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW; + core_idx = event_info->hw_idx; if (g_ife_hw_mgr.debug_cfg.enable_recovery) @@ -7756,6 +7687,9 @@ static int cam_ife_hw_mgr_handle_hw_err( if ((rc != 0) || !(recovery_data.no_of_context)) goto end; + if (rc || !recovery_data.no_of_context) + goto end; + if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION) recovery_data.error_type = CAM_ISP_HW_ERROR_VIOLATION; else @@ -8023,6 +7957,8 @@ static int cam_ife_hw_mgr_event_handler( void *evt_info) { int rc = 0; + struct cam_ife_hw_mgr_ctx *ctx; + struct cam_ife_hw_mgr *hw_mgr; if (!evt_info) return -EINVAL; @@ -8031,7 +7967,9 @@ static int cam_ife_hw_mgr_event_handler( if (evt_id != CAM_ISP_HW_EVENT_ERROR) return -EINVAL; + ctx = (struct cam_ife_hw_mgr_ctx *)priv; CAM_DBG(CAM_ISP, "Event ID 0x%x", evt_id); + hw_mgr = ctx->hw_mgr; switch (evt_id) { case CAM_ISP_HW_EVENT_SOF: @@ -8039,7 +7977,10 @@ static int cam_ife_hw_mgr_event_handler( break; case CAM_ISP_HW_EVENT_REG_UPDATE: - rc = cam_ife_hw_mgr_handle_hw_rup(priv, evt_info); + if (hw_mgr->csid_rup_en) + rc = cam_ife_hw_mgr_handle_csid_rup(priv, evt_info); + else + rc = cam_ife_hw_mgr_handle_hw_rup(priv, evt_info); break; case CAM_ISP_HW_EVENT_EPOCH: @@ -8055,9 +7996,8 @@ static int cam_ife_hw_mgr_event_handler( break; case CAM_ISP_HW_EVENT_ERROR: - rc = cam_ife_hw_mgr_handle_hw_err(priv, evt_info); + rc = cam_ife_hw_mgr_handle_hw_err(evt_id, priv, evt_info); break; - default: CAM_ERR(CAM_ISP, "Invalid event ID %d", evt_id); break; @@ -8075,12 +8015,19 @@ static int cam_ife_hw_mgr_sort_dev_with_caps( for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { if (!ife_hw_mgr->csid_devices[i]) continue; - if (ife_hw_mgr->csid_devices[i]->hw_ops.get_hw_caps) { - ife_hw_mgr->csid_devices[i]->hw_ops.get_hw_caps( - ife_hw_mgr->csid_devices[i]->hw_priv, - &ife_hw_mgr->ife_csid_dev_caps[i], - sizeof(ife_hw_mgr->ife_csid_dev_caps[i])); - } + + if (!ife_hw_mgr->csid_devices[i]->hw_ops.get_hw_caps) + continue; + + ife_hw_mgr->csid_devices[i]->hw_ops.get_hw_caps( + ife_hw_mgr->csid_devices[i]->hw_priv, + &ife_hw_mgr->ife_csid_dev_caps[i], + sizeof(ife_hw_mgr->ife_csid_dev_caps[i])); + + ife_hw_mgr->csid_global_reset_en = + ife_hw_mgr->ife_csid_dev_caps[i].global_reset_en; + ife_hw_mgr->csid_rup_en = + ife_hw_mgr->ife_csid_dev_caps[i].rup_en; } /* get caps for ife devices */ @@ -8326,7 +8273,6 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_tpg.list); INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_in.list); - INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_cid); INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_csid); INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_src); INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_in_rd); diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h index a0bbf78b19..0389147d39 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h @@ -42,8 +42,8 @@ struct cam_ife_hw_mgr_debug { struct dentry *dentry; uint64_t csid_debug; uint32_t enable_recovery; - uint32_t enable_csid_recovery; uint32_t camif_debug; + uint32_t enable_csid_recovery; bool enable_req_dump; bool per_req_reg_dump; bool disable_ubwc_comp; @@ -105,6 +105,9 @@ struct cam_ife_hw_mgr_debug { * @hw_enabled Array to indicate active HW * @internal_cdm Indicate whether context uses internal CDM * @pf_mid_found in page fault, mid found for this ctx. + * @buf_done_controller Buf done controller. + * @need_csid_top_cfg Flag to indicate if CSID top cfg is needed. + * */ struct cam_ife_hw_mgr_ctx { struct list_head list; @@ -118,7 +121,6 @@ struct cam_ife_hw_mgr_ctx { struct cam_isp_hw_mgr_res res_list_ife_in; struct cam_isp_hw_mgr_res res_list_tpg; - struct list_head res_list_ife_cid; struct list_head res_list_ife_csid; struct list_head res_list_ife_src; struct list_head res_list_ife_in_rd; @@ -160,6 +162,8 @@ struct cam_ife_hw_mgr_ctx { bool dsp_enabled; bool internal_cdm; bool pf_mid_found; + bool need_csid_top_cfg; + void *buf_done_controller; }; /** @@ -182,6 +186,8 @@ struct cam_ife_hw_mgr_ctx { * @support_consumed_addr indicate whether hw supports last consumed address * @hw_pid_support hw pid support for this target * @max_vfe_out_res_type max ife out res type value from hw + * @csid_rup_en Reg update at CSID side + * @csid_global_reset_en CSID global reset enable */ struct cam_ife_hw_mgr { struct cam_isp_hw_mgr mgr_common; @@ -205,6 +211,8 @@ struct cam_ife_hw_mgr { bool support_consumed_addr; bool hw_pid_support; uint32_t max_vfe_out_res_type; + bool csid_rup_en; + bool csid_global_reset_en; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 4147efe58a..f8eeaa0c98 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -1304,3 +1304,112 @@ int cam_isp_add_wait_trigger( return rc; } +int cam_isp_add_csid_reg_update( + struct cam_hw_prepare_update_args *prepare, + struct list_head *res_list, + uint32_t base_idx, + struct cam_kmd_buf_info *kmd_buf_info) +{ + int rc = 0; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_isp_resource_node *res; + uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size, hw_idx; + struct cam_ife_csid_reg_update_args + rup_args[CAM_IFE_CSID_HW_NUM_MAX] = {0}; + + if (prepare->num_hw_update_entries + 1 >= + prepare->max_hw_update_entries) { + CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", + prepare->num_hw_update_entries, + prepare->max_hw_update_entries); + return -EINVAL; + } + + reg_update_size = 0; + list_for_each_entry(hw_mgr_res, res_list, list) { + if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT) + continue; + + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + if (i == CAM_ISP_HW_SPLIT_RIGHT) + continue; + res = hw_mgr_res->hw_res[i]; + if (res->hw_intf->hw_idx != base_idx) + continue; + hw_idx = res->hw_intf->hw_idx; + rup_args[hw_idx].res[rup_args[hw_idx].num_res] = res; + rup_args[hw_idx].num_res++; + + CAM_DBG(CAM_ISP, + "Reg update added for res %d hw_id %d cdm_idx %d", + res->res_id, res->hw_intf->hw_idx, base_idx); + } + } + + for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { + if (!rup_args[i].num_res) + continue; + + if (kmd_buf_info->size > (kmd_buf_info->used_bytes + + reg_update_size)) { + kmd_buf_remain_size = kmd_buf_info->size - + (kmd_buf_info->used_bytes + + reg_update_size); + } else { + CAM_ERR(CAM_ISP, "no free mem %d %d %d", + base_idx, kmd_buf_info->size, + kmd_buf_info->used_bytes + + reg_update_size); + rc = -EINVAL; + return rc; + } + + rup_args[i].cmd.cmd_buf_addr = kmd_buf_info->cpu_addr + + kmd_buf_info->used_bytes/4 + + reg_update_size/4; + rup_args[i].cmd.size = kmd_buf_remain_size; + res = rup_args[i].res[0]; + + rc = res->hw_intf->hw_ops.process_cmd( + res->hw_intf->hw_priv, + CAM_ISP_HW_CMD_GET_REG_UPDATE, &rup_args[i], + sizeof(struct cam_ife_csid_reg_update_args)); + if (rc) + return rc; + + CAM_DBG(CAM_ISP, + "Reg update added for res %d hw_id %d cdm_idx %d", + res->res_id, res->hw_intf->hw_idx, base_idx); + reg_update_size += rup_args[i].cmd.used_bytes; + } + + if (reg_update_size) { + /* Update the HW entries */ + num_ent = prepare->num_hw_update_entries; + prepare->hw_update_entries[num_ent].handle = + kmd_buf_info->handle; + prepare->hw_update_entries[num_ent].len = reg_update_size; + prepare->hw_update_entries[num_ent].offset = + kmd_buf_info->offset; + + /* Marking reg update as IOCFG to reapply on bubble */ + prepare->hw_update_entries[num_ent].flags = CAM_ISP_IOCFG_BL; + CAM_DBG(CAM_ISP, + "num_ent=%d handle=0x%x, len=%u, offset=%u", + num_ent, + prepare->hw_update_entries[num_ent].handle, + prepare->hw_update_entries[num_ent].len, + prepare->hw_update_entries[num_ent].offset); + num_ent++; + + kmd_buf_info->used_bytes += reg_update_size; + kmd_buf_info->offset += reg_update_size; + prepare->num_hw_update_entries = num_ent; + /* reg update is success return status 0 */ + rc = 0; + } + + return rc; +} diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h index ccd9907996..686ecd1afd 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h @@ -249,4 +249,22 @@ int cam_isp_add_go_cmd( uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info); +/* cam_isp_csid_add_reg_update() + * + * @brief Add csid reg update in the hw entries list + * processe the isp source list get the reg update from + * ISP HW instance + * + * @prepare: Contain the packet and HW update variables + * @res_list_isp_src: Resource list for IFE/VFE source + * @base_idx: Base or dev index of the IFE/VFE HW instance + * @kmd_buf_info: Kmd buffer to store the change base command + * @return: 0 for success + * -EINVAL for Fail + */ +int cam_isp_add_csid_reg_update( + struct cam_hw_prepare_update_args *prepare, + struct list_head *res_list, + uint32_t base_idx, + struct cam_kmd_buf_info *kmd_buf_info); #endif /*_CAM_ISP_HW_PARSER_H */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h index bc564b2e1f..fdb5f863f9 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h @@ -2,308 +2,404 @@ /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ - #ifndef _CAM_IFE_CSID_170_H_ #define _CAM_IFE_CSID_170_H_ -#include "cam_ife_csid_core.h" +#include +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" +#include "cam_ife_csid_dev.h" +#include "camera_main.h" -static struct cam_ife_csid_pxl_reg_offset cam_ife_csid_170_ipp_reg_offset = { - .csid_pxl_irq_status_addr = 0x30, - .csid_pxl_irq_mask_addr = 0x34, - .csid_pxl_irq_clear_addr = 0x38, - .csid_pxl_irq_set_addr = 0x3c, +#define CAM_CSID_VERSION_V170 0x10070000 - .csid_pxl_cfg0_addr = 0x200, - .csid_pxl_cfg1_addr = 0x204, - .csid_pxl_ctrl_addr = 0x208, - .csid_pxl_frm_drop_pattern_addr = 0x20c, - .csid_pxl_frm_drop_period_addr = 0x210, - .csid_pxl_irq_subsample_pattern_addr = 0x214, - .csid_pxl_irq_subsample_period_addr = 0x218, - .csid_pxl_hcrop_addr = 0x21c, - .csid_pxl_vcrop_addr = 0x220, - .csid_pxl_pix_drop_pattern_addr = 0x224, - .csid_pxl_pix_drop_period_addr = 0x228, - .csid_pxl_line_drop_pattern_addr = 0x22c, - .csid_pxl_line_drop_period_addr = 0x230, - .csid_pxl_rst_strobes_addr = 0x240, - .csid_pxl_status_addr = 0x254, - .csid_pxl_misr_val_addr = 0x258, - .csid_pxl_format_measure_cfg0_addr = 0x270, - .csid_pxl_format_measure_cfg1_addr = 0x274, - .csid_pxl_format_measure0_addr = 0x278, - .csid_pxl_format_measure1_addr = 0x27c, - .csid_pxl_format_measure2_addr = 0x280, - .csid_pxl_timestamp_curr0_sof_addr = 0x290, - .csid_pxl_timestamp_curr1_sof_addr = 0x294, - .csid_pxl_timestamp_perv0_sof_addr = 0x298, - .csid_pxl_timestamp_perv1_sof_addr = 0x29c, - .csid_pxl_timestamp_curr0_eof_addr = 0x2a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x2a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x2a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x2ac, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_ipp_reg_info = { + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x254, + .misr_val_addr = 0x258, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .pix_store_en_shift_val = 7, + .halt_master_sel_master_val = 0, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .early_eof_en_shift_val = 29, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_170_rdi_0_reg_offset = { - .csid_rdi_irq_status_addr = 0x40, - .csid_rdi_irq_mask_addr = 0x44, - .csid_rdi_irq_clear_addr = 0x48, - .csid_rdi_irq_set_addr = 0x4c, - .csid_rdi_cfg0_addr = 0x300, - .csid_rdi_cfg1_addr = 0x304, - .csid_rdi_ctrl_addr = 0x308, - .csid_rdi_frm_drop_pattern_addr = 0x30c, - .csid_rdi_frm_drop_period_addr = 0x310, - .csid_rdi_irq_subsample_pattern_addr = 0x314, - .csid_rdi_irq_subsample_period_addr = 0x318, - .csid_rdi_rpp_hcrop_addr = 0x31c, - .csid_rdi_rpp_vcrop_addr = 0x320, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x324, - .csid_rdi_rpp_pix_drop_period_addr = 0x328, - .csid_rdi_rpp_line_drop_pattern_addr = 0x32c, - .csid_rdi_rpp_line_drop_period_addr = 0x330, - .csid_rdi_rst_strobes_addr = 0x340, - .csid_rdi_status_addr = 0x350, - .csid_rdi_misr_val0_addr = 0x354, - .csid_rdi_misr_val1_addr = 0x358, - .csid_rdi_misr_val2_addr = 0x35c, - .csid_rdi_misr_val3_addr = 0x360, - .csid_rdi_format_measure_cfg0_addr = 0x370, - .csid_rdi_format_measure_cfg1_addr = 0x374, - .csid_rdi_format_measure0_addr = 0x378, - .csid_rdi_format_measure1_addr = 0x37c, - .csid_rdi_format_measure2_addr = 0x380, - .csid_rdi_timestamp_curr0_sof_addr = 0x390, - .csid_rdi_timestamp_curr1_sof_addr = 0x394, - .csid_rdi_timestamp_prev0_sof_addr = 0x398, - .csid_rdi_timestamp_prev1_sof_addr = 0x39c, - .csid_rdi_timestamp_curr0_eof_addr = 0x3a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x3a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x3a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x3ac, - .csid_rdi_byte_cntr_ping_addr = 0x3e0, - .csid_rdi_byte_cntr_pong_addr = 0x3e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_rdi_0_reg_info = { + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_170_rdi_1_reg_offset = { - .csid_rdi_irq_status_addr = 0x50, - .csid_rdi_irq_mask_addr = 0x54, - .csid_rdi_irq_clear_addr = 0x58, - .csid_rdi_irq_set_addr = 0x5c, - .csid_rdi_cfg0_addr = 0x400, - .csid_rdi_cfg1_addr = 0x404, - .csid_rdi_ctrl_addr = 0x408, - .csid_rdi_frm_drop_pattern_addr = 0x40c, - .csid_rdi_frm_drop_period_addr = 0x410, - .csid_rdi_irq_subsample_pattern_addr = 0x414, - .csid_rdi_irq_subsample_period_addr = 0x418, - .csid_rdi_rpp_hcrop_addr = 0x41c, - .csid_rdi_rpp_vcrop_addr = 0x420, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x424, - .csid_rdi_rpp_pix_drop_period_addr = 0x428, - .csid_rdi_rpp_line_drop_pattern_addr = 0x42c, - .csid_rdi_rpp_line_drop_period_addr = 0x430, - .csid_rdi_rst_strobes_addr = 0x440, - .csid_rdi_status_addr = 0x450, - .csid_rdi_misr_val0_addr = 0x454, - .csid_rdi_misr_val1_addr = 0x458, - .csid_rdi_misr_val2_addr = 0x45c, - .csid_rdi_misr_val3_addr = 0x460, - .csid_rdi_format_measure_cfg0_addr = 0x470, - .csid_rdi_format_measure_cfg1_addr = 0x474, - .csid_rdi_format_measure0_addr = 0x478, - .csid_rdi_format_measure1_addr = 0x47c, - .csid_rdi_format_measure2_addr = 0x480, - .csid_rdi_timestamp_curr0_sof_addr = 0x490, - .csid_rdi_timestamp_curr1_sof_addr = 0x494, - .csid_rdi_timestamp_prev0_sof_addr = 0x498, - .csid_rdi_timestamp_prev1_sof_addr = 0x49c, - .csid_rdi_timestamp_curr0_eof_addr = 0x4a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x4a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x4a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x4ac, - .csid_rdi_byte_cntr_ping_addr = 0x4e0, - .csid_rdi_byte_cntr_pong_addr = 0x4e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_rdi_1_reg_info = { + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_170_rdi_2_reg_offset = { - .csid_rdi_irq_status_addr = 0x60, - .csid_rdi_irq_mask_addr = 0x64, - .csid_rdi_irq_clear_addr = 0x68, - .csid_rdi_irq_set_addr = 0x6c, - .csid_rdi_cfg0_addr = 0x500, - .csid_rdi_cfg1_addr = 0x504, - .csid_rdi_ctrl_addr = 0x508, - .csid_rdi_frm_drop_pattern_addr = 0x50c, - .csid_rdi_frm_drop_period_addr = 0x510, - .csid_rdi_irq_subsample_pattern_addr = 0x514, - .csid_rdi_irq_subsample_period_addr = 0x518, - .csid_rdi_rpp_hcrop_addr = 0x51c, - .csid_rdi_rpp_vcrop_addr = 0x520, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x524, - .csid_rdi_rpp_pix_drop_period_addr = 0x528, - .csid_rdi_rpp_line_drop_pattern_addr = 0x52c, - .csid_rdi_rpp_line_drop_period_addr = 0x530, - .csid_rdi_yuv_chroma_conversion_addr = 0x534, - .csid_rdi_rst_strobes_addr = 0x540, - .csid_rdi_status_addr = 0x550, - .csid_rdi_misr_val0_addr = 0x554, - .csid_rdi_misr_val1_addr = 0x558, - .csid_rdi_misr_val2_addr = 0x55c, - .csid_rdi_misr_val3_addr = 0x560, - .csid_rdi_format_measure_cfg0_addr = 0x570, - .csid_rdi_format_measure_cfg1_addr = 0x574, - .csid_rdi_format_measure0_addr = 0x578, - .csid_rdi_format_measure1_addr = 0x57c, - .csid_rdi_format_measure2_addr = 0x580, - .csid_rdi_timestamp_curr0_sof_addr = 0x590, - .csid_rdi_timestamp_curr1_sof_addr = 0x594, - .csid_rdi_timestamp_prev0_sof_addr = 0x598, - .csid_rdi_timestamp_prev1_sof_addr = 0x59c, - .csid_rdi_timestamp_curr0_eof_addr = 0x5a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x5a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x5a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x5ac, - .csid_rdi_byte_cntr_ping_addr = 0x5e0, - .csid_rdi_byte_cntr_pong_addr = 0x5e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_rdi_2_reg_info = { + .irq_status_addr = 0x60, + .irq_mask_addr = 0x64, + .irq_clear_addr = 0x68, + .irq_set_addr = 0x6c, + .cfg0_addr = 0x500, + .cfg1_addr = 0x504, + .ctrl_addr = 0x508, + .frm_drop_pattern_addr = 0x50c, + .frm_drop_period_addr = 0x510, + .irq_subsample_pattern_addr = 0x514, + .irq_subsample_period_addr = 0x518, + .hcrop_addr = 0x51c, + .vcrop_addr = 0x520, + .pix_drop_pattern_addr = 0x524, + .pix_drop_period_addr = 0x528, + .line_drop_pattern_addr = 0x52c, + .line_drop_period_addr = 0x530, + .yuv_chroma_conversion_addr = 0x534, + .rst_strobes_addr = 0x540, + .status_addr = 0x550, + .misr_val0_addr = 0x554, + .misr_val1_addr = 0x558, + .misr_val2_addr = 0x55c, + .misr_val3_addr = 0x560, + .format_measure_cfg0_addr = 0x570, + .format_measure_cfg1_addr = 0x574, + .format_measure0_addr = 0x578, + .format_measure1_addr = 0x57c, + .format_measure2_addr = 0x580, + .timestamp_curr0_sof_addr = 0x590, + .timestamp_curr1_sof_addr = 0x594, + .timestamp_prev0_sof_addr = 0x598, + .timestamp_prev1_sof_addr = 0x59c, + .timestamp_curr0_eof_addr = 0x5a0, + .timestamp_curr1_eof_addr = 0x5a4, + .timestamp_prev0_eof_addr = 0x5a8, + .timestamp_prev1_eof_addr = 0x5ac, + .byte_cntr_ping_addr = 0x5e0, + .byte_cntr_pong_addr = 0x5e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_csi2_rx_reg_offset - cam_ife_csid_170_csi2_reg_offset = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, - +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_170_csi2_reg_info = { + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_de_scramble_cfg0_addr = 0x114, - .csid_csi2_rx_de_scramble_cfg1_addr = 0x118, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .de_scramble_cfg0_addr = 0x114, + .de_scramble_cfg1_addr = 0x118, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x3, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x3, + .vc_mask = 0x7C00000, + .dt_mask = 0x3f0000, + .wc_mask = 0xffff0000, + .calc_crc_mask = 0xffff, + .expected_crc_mask = 0xffff, + .ecc_correction_shift_en = 0, + .lane_num_shift = 0, + .lane_cfg_shift = 4, + .phy_type_shift = 24, + .phy_num_shift = 20, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, }; -static struct cam_ife_csid_csi2_tpg_reg_offset - cam_ife_csid_170_tpg_reg_offset = { +static struct cam_ife_csid_ver1_tpg_reg_info + cam_ife_csid_170_tpg_reg_info = { /*CSID TPG control */ - .csid_tpg_ctrl_addr = 0x600, - .csid_tpg_vc_cfg0_addr = 0x604, - .csid_tpg_vc_cfg1_addr = 0x608, - .csid_tpg_lfsr_seed_addr = 0x60c, - .csid_tpg_dt_n_cfg_0_addr = 0x610, - .csid_tpg_dt_n_cfg_1_addr = 0x614, - .csid_tpg_dt_n_cfg_2_addr = 0x618, - .csid_tpg_color_bars_cfg_addr = 0x640, - .csid_tpg_color_box_cfg_addr = 0x644, - .csid_tpg_common_gen_cfg_addr = 0x648, - .csid_tpg_cgen_n_cfg_addr = 0x650, - .csid_tpg_cgen_n_x0_addr = 0x654, - .csid_tpg_cgen_n_x1_addr = 0x658, - .csid_tpg_cgen_n_x2_addr = 0x65c, - .csid_tpg_cgen_n_xy_addr = 0x660, - .csid_tpg_cgen_n_y1_addr = 0x664, - .csid_tpg_cgen_n_y2_addr = 0x668, + .ctrl_addr = 0x600, + .vc_cfg0_addr = 0x604, + .vc_cfg1_addr = 0x608, + .lfsr_seed_addr = 0x60c, + .dt_n_cfg_0_addr = 0x610, + .dt_n_cfg_1_addr = 0x614, + .dt_n_cfg_2_addr = 0x618, + .color_bars_cfg_addr = 0x640, + .color_box_cfg_addr = 0x644, + .common_gen_cfg_addr = 0x648, + .cgen_n_cfg_addr = 0x650, + .cgen_n_x0_addr = 0x654, + .cgen_n_x1_addr = 0x658, + .cgen_n_x2_addr = 0x65c, + .cgen_n_xy_addr = 0x660, + .cgen_n_y1_addr = 0x664, + .cgen_n_y2_addr = 0x668, /* configurations */ - .tpg_dtn_cfg_offset = 0xc, - .tpg_cgen_cfg_offset = 0x20, - .tpg_cpas_ife_reg_offset = 0x28, + .dtn_cfg_offset = 0xc, + .cgen_cfg_offset = 0x20, + .cpas_ife_reg_offset = 0x28, + .hbi = 0x740, + .vbi = 0x3FF, + .lfsr_seed = 0x12345678, + .ctrl_cfg = 0x408007, + .line_interleave_mode = 0x1, + .color_bar = 1, + .num_frames = 0, + .num_active_dt = 0, + .payload_mode = 0x8, + .num_active_lanes_mask = 0x30, + .fmt_shift = 16, + .num_frame_shift = 16, + .width_shift = 16, + .vbi_shift = 12, + .line_interleave_shift = 10, + .num_active_dt_shift = 8, + .color_bar_shift = 5, + .height_shift = 0, + .hbi_shift = 0, }; -static struct cam_ife_csid_common_reg_offset - cam_ife_csid_170_cmn_reg_offset = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, +static struct cam_ife_csid_ver1_common_reg_info + cam_ife_csid_170_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 1, - .minor_version = 7, - .version_incr = 0, - .num_rdis = 3, - .num_pix = 1, - .num_ppp = 0, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .crop_shift = 16, - .ipp_irq_mask_all = 0x7FFF, - .rdi_irq_mask_all = 0x7FFF, - .ppp_irq_mask_all = 0x0, - .measure_en_hbi_vbi_cnt_mask = 0xC, - .format_measure_en_val = 1, - .format_measure_height_mask_val = 0xFFFF, - .format_measure_height_shift_val = 0x10, - .format_measure_width_mask_val = 0xFFFF, - .format_measure_width_shift_val = 0x0, + .major_version = 1, + .minor_version = 7, + .version_incr = 0, + .num_rdis = 3, + .num_pix = 1, + .num_ppp = 0, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .ipp_irq_mask_all = 0x7FFF, + .rdi_irq_mask_all = 0x7FFF, + .ppp_irq_mask_all = 0x0, + .measure_en_hbi_vbi_cnt_mask = 0xC, + .timestamp_strobe_val = 0x2, + .timestamp_stb_sel_shift_val = 0, }; -static struct cam_ife_csid_reg_offset cam_ife_csid_170_reg_offset = { - .cmn_reg = &cam_ife_csid_170_cmn_reg_offset, - .csi2_reg = &cam_ife_csid_170_csi2_reg_offset, - .ipp_reg = &cam_ife_csid_170_ipp_reg_offset, +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_170_reg_info = { + .cmn_reg = &cam_ife_csid_170_cmn_reg_info, + .csi2_reg = &cam_ife_csid_170_csi2_reg_info, + .ipp_reg = &cam_ife_csid_170_ipp_reg_info, .ppp_reg = NULL, .rdi_reg = { - &cam_ife_csid_170_rdi_0_reg_offset, - &cam_ife_csid_170_rdi_1_reg_offset, - &cam_ife_csid_170_rdi_2_reg_offset, + &cam_ife_csid_170_rdi_0_reg_info, + &cam_ife_csid_170_rdi_1_reg_info, + &cam_ife_csid_170_rdi_2_reg_info, NULL, }, - .tpg_reg = &cam_ife_csid_170_tpg_reg_offset, + .tpg_reg = &cam_ife_csid_170_tpg_reg_info, }; - #endif /*_CAM_IFE_CSID_170_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h index f7608a73fa..13aabf2c79 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h @@ -6,367 +6,480 @@ #ifndef _CAM_IFE_CSID_170_200_H_ #define _CAM_IFE_CSID_170_200_H_ -#include "cam_ife_csid_core.h" +#include +#include "camera_main.h" +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" -static struct cam_ife_csid_pxl_reg_offset - cam_ife_csid_170_200_ipp_reg_offset = { - .csid_pxl_irq_status_addr = 0x30, - .csid_pxl_irq_mask_addr = 0x34, - .csid_pxl_irq_clear_addr = 0x38, - .csid_pxl_irq_set_addr = 0x3c, +#define CAM_CSID_VERSION_V170 0x10070000 - .csid_pxl_cfg0_addr = 0x200, - .csid_pxl_cfg1_addr = 0x204, - .csid_pxl_ctrl_addr = 0x208, - .csid_pxl_frm_drop_pattern_addr = 0x20c, - .csid_pxl_frm_drop_period_addr = 0x210, - .csid_pxl_irq_subsample_pattern_addr = 0x214, - .csid_pxl_irq_subsample_period_addr = 0x218, - .csid_pxl_hcrop_addr = 0x21c, - .csid_pxl_vcrop_addr = 0x220, - .csid_pxl_pix_drop_pattern_addr = 0x224, - .csid_pxl_pix_drop_period_addr = 0x228, - .csid_pxl_line_drop_pattern_addr = 0x22c, - .csid_pxl_line_drop_period_addr = 0x230, - .csid_pxl_rst_strobes_addr = 0x240, - .csid_pxl_status_addr = 0x254, - .csid_pxl_misr_val_addr = 0x258, - .csid_pxl_format_measure_cfg0_addr = 0x270, - .csid_pxl_format_measure_cfg1_addr = 0x274, - .csid_pxl_format_measure0_addr = 0x278, - .csid_pxl_format_measure1_addr = 0x27c, - .csid_pxl_format_measure2_addr = 0x280, - .csid_pxl_timestamp_curr0_sof_addr = 0x290, - .csid_pxl_timestamp_curr1_sof_addr = 0x294, - .csid_pxl_timestamp_perv0_sof_addr = 0x298, - .csid_pxl_timestamp_perv1_sof_addr = 0x29c, - .csid_pxl_timestamp_curr0_eof_addr = 0x2a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x2a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x2a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x2ac, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_200_ipp_reg_info = { + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x254, + .misr_val_addr = 0x258, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, - .quad_cfa_bin_en_shift_val = 30, - .ccif_violation_en = 1, - .halt_master_sel_en = 1, - .halt_sel_internal_master_val = 3, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .bin_qcfa_en_shift_val = 30, + .bin_h_en_shift_val = 2, + .bin_en_shift_val = 2, + .binning_supported = 0x3, + .halt_master_sel_master_val = 0, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_pxl_reg_offset - cam_ife_csid_170_200_ppp_reg_offset = { - .csid_pxl_irq_status_addr = 0xa0, - .csid_pxl_irq_mask_addr = 0xa4, - .csid_pxl_irq_clear_addr = 0xa8, - .csid_pxl_irq_set_addr = 0xac, - - .csid_pxl_cfg0_addr = 0x700, - .csid_pxl_cfg1_addr = 0x704, - .csid_pxl_ctrl_addr = 0x708, - .csid_pxl_frm_drop_pattern_addr = 0x70c, - .csid_pxl_frm_drop_period_addr = 0x710, - .csid_pxl_irq_subsample_pattern_addr = 0x714, - .csid_pxl_irq_subsample_period_addr = 0x718, - .csid_pxl_hcrop_addr = 0x71c, - .csid_pxl_vcrop_addr = 0x720, - .csid_pxl_pix_drop_pattern_addr = 0x724, - .csid_pxl_pix_drop_period_addr = 0x728, - .csid_pxl_line_drop_pattern_addr = 0x72c, - .csid_pxl_line_drop_period_addr = 0x730, - .csid_pxl_rst_strobes_addr = 0x740, - .csid_pxl_status_addr = 0x754, - .csid_pxl_misr_val_addr = 0x758, - .csid_pxl_format_measure_cfg0_addr = 0x770, - .csid_pxl_format_measure_cfg1_addr = 0x774, - .csid_pxl_format_measure0_addr = 0x778, - .csid_pxl_format_measure1_addr = 0x77c, - .csid_pxl_format_measure2_addr = 0x780, - .csid_pxl_timestamp_curr0_sof_addr = 0x790, - .csid_pxl_timestamp_curr1_sof_addr = 0x794, - .csid_pxl_timestamp_perv0_sof_addr = 0x798, - .csid_pxl_timestamp_perv1_sof_addr = 0x79c, - .csid_pxl_timestamp_curr0_eof_addr = 0x7a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x7a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x7a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x7ac, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_200_ppp_reg_info = { + .irq_status_addr = 0xa0, + .irq_mask_addr = 0xa4, + .irq_clear_addr = 0xa8, + .irq_set_addr = 0xac, + .cfg0_addr = 0x700, + .cfg1_addr = 0x704, + .ctrl_addr = 0x708, + .frm_drop_pattern_addr = 0x70c, + .frm_drop_period_addr = 0x710, + .irq_subsample_pattern_addr = 0x714, + .irq_subsample_period_addr = 0x718, + .hcrop_addr = 0x71c, + .vcrop_addr = 0x720, + .pix_drop_pattern_addr = 0x724, + .pix_drop_period_addr = 0x728, + .line_drop_pattern_addr = 0x72c, + .line_drop_period_addr = 0x730, + .rst_strobes_addr = 0x740, + .status_addr = 0x754, + .misr_val_addr = 0x758, + .format_measure_cfg0_addr = 0x770, + .format_measure_cfg1_addr = 0x774, + .format_measure0_addr = 0x778, + .format_measure1_addr = 0x77c, + .format_measure2_addr = 0x780, + .timestamp_curr0_sof_addr = 0x790, + .timestamp_curr1_sof_addr = 0x794, + .timestamp_prev0_sof_addr = 0x798, + .timestamp_prev1_sof_addr = 0x79c, + .timestamp_curr0_eof_addr = 0x7a0, + .timestamp_curr1_eof_addr = 0x7a4, + .timestamp_prev0_eof_addr = 0x7a8, + .timestamp_prev1_eof_addr = 0x7ac, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, - .ccif_violation_en = 1, - .halt_master_sel_en = 1, - .halt_sel_internal_master_val = 3, + .halt_master_sel_master_val = 3, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; - -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_170_200_rdi_0_reg_offset = { - .csid_rdi_irq_status_addr = 0x40, - .csid_rdi_irq_mask_addr = 0x44, - .csid_rdi_irq_clear_addr = 0x48, - .csid_rdi_irq_set_addr = 0x4c, - .csid_rdi_cfg0_addr = 0x300, - .csid_rdi_cfg1_addr = 0x304, - .csid_rdi_ctrl_addr = 0x308, - .csid_rdi_frm_drop_pattern_addr = 0x30c, - .csid_rdi_frm_drop_period_addr = 0x310, - .csid_rdi_irq_subsample_pattern_addr = 0x314, - .csid_rdi_irq_subsample_period_addr = 0x318, - .csid_rdi_rpp_hcrop_addr = 0x31c, - .csid_rdi_rpp_vcrop_addr = 0x320, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x324, - .csid_rdi_rpp_pix_drop_period_addr = 0x328, - .csid_rdi_rpp_line_drop_pattern_addr = 0x32c, - .csid_rdi_rpp_line_drop_period_addr = 0x330, - .csid_rdi_rst_strobes_addr = 0x340, - .csid_rdi_status_addr = 0x350, - .csid_rdi_misr_val0_addr = 0x354, - .csid_rdi_misr_val1_addr = 0x358, - .csid_rdi_misr_val2_addr = 0x35c, - .csid_rdi_misr_val3_addr = 0x360, - .csid_rdi_format_measure_cfg0_addr = 0x370, - .csid_rdi_format_measure_cfg1_addr = 0x374, - .csid_rdi_format_measure0_addr = 0x378, - .csid_rdi_format_measure1_addr = 0x37c, - .csid_rdi_format_measure2_addr = 0x380, - .csid_rdi_timestamp_curr0_sof_addr = 0x390, - .csid_rdi_timestamp_curr1_sof_addr = 0x394, - .csid_rdi_timestamp_prev0_sof_addr = 0x398, - .csid_rdi_timestamp_prev1_sof_addr = 0x39c, - .csid_rdi_timestamp_curr0_eof_addr = 0x3a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x3a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x3a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x3ac, - .csid_rdi_byte_cntr_ping_addr = 0x3e0, - .csid_rdi_byte_cntr_pong_addr = 0x3e4, - .ccif_violation_en = 1, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_200_rdi_0_reg_info = { + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .ccif_violation_en = 1, + .plain_fmt_shift_val = 10, + .mipi_pack_supported = 1, + .packing_fmt_shift_val = 30, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_170_200_rdi_1_reg_offset = { - .csid_rdi_irq_status_addr = 0x50, - .csid_rdi_irq_mask_addr = 0x54, - .csid_rdi_irq_clear_addr = 0x58, - .csid_rdi_irq_set_addr = 0x5c, - .csid_rdi_cfg0_addr = 0x400, - .csid_rdi_cfg1_addr = 0x404, - .csid_rdi_ctrl_addr = 0x408, - .csid_rdi_frm_drop_pattern_addr = 0x40c, - .csid_rdi_frm_drop_period_addr = 0x410, - .csid_rdi_irq_subsample_pattern_addr = 0x414, - .csid_rdi_irq_subsample_period_addr = 0x418, - .csid_rdi_rpp_hcrop_addr = 0x41c, - .csid_rdi_rpp_vcrop_addr = 0x420, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x424, - .csid_rdi_rpp_pix_drop_period_addr = 0x428, - .csid_rdi_rpp_line_drop_pattern_addr = 0x42c, - .csid_rdi_rpp_line_drop_period_addr = 0x430, - .csid_rdi_rst_strobes_addr = 0x440, - .csid_rdi_status_addr = 0x450, - .csid_rdi_misr_val0_addr = 0x454, - .csid_rdi_misr_val1_addr = 0x458, - .csid_rdi_misr_val2_addr = 0x45c, - .csid_rdi_misr_val3_addr = 0x460, - .csid_rdi_format_measure_cfg0_addr = 0x470, - .csid_rdi_format_measure_cfg1_addr = 0x474, - .csid_rdi_format_measure0_addr = 0x478, - .csid_rdi_format_measure1_addr = 0x47c, - .csid_rdi_format_measure2_addr = 0x480, - .csid_rdi_timestamp_curr0_sof_addr = 0x490, - .csid_rdi_timestamp_curr1_sof_addr = 0x494, - .csid_rdi_timestamp_prev0_sof_addr = 0x498, - .csid_rdi_timestamp_prev1_sof_addr = 0x49c, - .csid_rdi_timestamp_curr0_eof_addr = 0x4a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x4a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x4a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x4ac, - .csid_rdi_byte_cntr_ping_addr = 0x4e0, - .csid_rdi_byte_cntr_pong_addr = 0x4e4, - .ccif_violation_en = 1, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_200_rdi_1_reg_info = { + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .ccif_violation_en = 1, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_170_200_rdi_2_reg_offset = { - .csid_rdi_irq_status_addr = 0x60, - .csid_rdi_irq_mask_addr = 0x64, - .csid_rdi_irq_clear_addr = 0x68, - .csid_rdi_irq_set_addr = 0x6c, - .csid_rdi_cfg0_addr = 0x500, - .csid_rdi_cfg1_addr = 0x504, - .csid_rdi_ctrl_addr = 0x508, - .csid_rdi_frm_drop_pattern_addr = 0x50c, - .csid_rdi_frm_drop_period_addr = 0x510, - .csid_rdi_irq_subsample_pattern_addr = 0x514, - .csid_rdi_irq_subsample_period_addr = 0x518, - .csid_rdi_rpp_hcrop_addr = 0x51c, - .csid_rdi_rpp_vcrop_addr = 0x520, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x524, - .csid_rdi_rpp_pix_drop_period_addr = 0x528, - .csid_rdi_rpp_line_drop_pattern_addr = 0x52c, - .csid_rdi_rpp_line_drop_period_addr = 0x530, - .csid_rdi_yuv_chroma_conversion_addr = 0x534, - .csid_rdi_rst_strobes_addr = 0x540, - .csid_rdi_status_addr = 0x550, - .csid_rdi_misr_val0_addr = 0x554, - .csid_rdi_misr_val1_addr = 0x558, - .csid_rdi_misr_val2_addr = 0x55c, - .csid_rdi_misr_val3_addr = 0x560, - .csid_rdi_format_measure_cfg0_addr = 0x570, - .csid_rdi_format_measure_cfg1_addr = 0x574, - .csid_rdi_format_measure0_addr = 0x578, - .csid_rdi_format_measure1_addr = 0x57c, - .csid_rdi_format_measure2_addr = 0x580, - .csid_rdi_timestamp_curr0_sof_addr = 0x590, - .csid_rdi_timestamp_curr1_sof_addr = 0x594, - .csid_rdi_timestamp_prev0_sof_addr = 0x598, - .csid_rdi_timestamp_prev1_sof_addr = 0x59c, - .csid_rdi_timestamp_curr0_eof_addr = 0x5a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x5a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x5a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x5ac, - .csid_rdi_byte_cntr_ping_addr = 0x5e0, - .csid_rdi_byte_cntr_pong_addr = 0x5e4, - .ccif_violation_en = 1, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_170_200_rdi_2_reg_info = { + .irq_status_addr = 0x60, + .irq_mask_addr = 0x64, + .irq_clear_addr = 0x68, + .irq_set_addr = 0x6c, + .cfg0_addr = 0x500, + .cfg1_addr = 0x504, + .ctrl_addr = 0x508, + .frm_drop_pattern_addr = 0x50c, + .frm_drop_period_addr = 0x510, + .irq_subsample_pattern_addr = 0x514, + .irq_subsample_period_addr = 0x518, + .hcrop_addr = 0x51c, + .vcrop_addr = 0x520, + .pix_drop_pattern_addr = 0x524, + .pix_drop_period_addr = 0x528, + .line_drop_pattern_addr = 0x52c, + .line_drop_period_addr = 0x530, + .yuv_chroma_conversion_addr = 0x534, + .rst_strobes_addr = 0x540, + .status_addr = 0x550, + .misr_val0_addr = 0x554, + .misr_val1_addr = 0x558, + .misr_val2_addr = 0x55c, + .misr_val3_addr = 0x560, + .format_measure_cfg0_addr = 0x570, + .format_measure_cfg1_addr = 0x574, + .format_measure0_addr = 0x578, + .format_measure1_addr = 0x57c, + .format_measure2_addr = 0x580, + .timestamp_curr0_sof_addr = 0x590, + .timestamp_curr1_sof_addr = 0x594, + .timestamp_prev0_sof_addr = 0x598, + .timestamp_prev1_sof_addr = 0x59c, + .timestamp_curr0_eof_addr = 0x5a0, + .timestamp_curr1_eof_addr = 0x5a4, + .timestamp_prev0_eof_addr = 0x5a8, + .timestamp_prev1_eof_addr = 0x5ac, + .byte_cntr_ping_addr = 0x5e0, + .byte_cntr_pong_addr = 0x5e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .ccif_violation_en = 1, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_csi2_rx_reg_offset - cam_ife_csid_170_200_csi2_reg_offset = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, - +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_170_200_csi2_reg_info = { + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, - .csid_csi2_rx_de_scramble_type3_cfg0_addr = 0x170, - .csid_csi2_rx_de_scramble_type3_cfg1_addr = 0x174, - .csid_csi2_rx_de_scramble_type2_cfg0_addr = 0x178, - .csid_csi2_rx_de_scramble_type2_cfg1_addr = 0x17c, - .csid_csi2_rx_de_scramble_type1_cfg0_addr = 0x180, - .csid_csi2_rx_de_scramble_type1_cfg1_addr = 0x184, - .csid_csi2_rx_de_scramble_type0_cfg0_addr = 0x188, - .csid_csi2_rx_de_scramble_type0_cfg1_addr = 0x18c, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, + .de_scramble_type3_cfg0_addr = 0x170, + .de_scramble_type3_cfg1_addr = 0x174, + .de_scramble_type2_cfg0_addr = 0x178, + .de_scramble_type2_cfg1_addr = 0x17c, + .de_scramble_type1_cfg0_addr = 0x180, + .de_scramble_type1_cfg1_addr = 0x184, + .de_scramble_type0_cfg0_addr = 0x188, + .de_scramble_type0_cfg1_addr = 0x18c, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x7, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x7, + .vc_mask = 0x7C00000, + .dt_mask = 0x3f0000, + .wc_mask = 0xffff0000, + .calc_crc_mask = 0xffff, + .expected_crc_mask = 0xffff, + .ecc_correction_shift_en = 0, + .lane_num_shift = 0, + .lane_cfg_shift = 4, + .phy_type_shift = 24, + .phy_num_shift = 20, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, }; -static struct cam_ife_csid_csi2_tpg_reg_offset - cam_ife_csid_170_200_tpg_reg_offset = { +static struct cam_ife_csid_ver1_tpg_reg_info + cam_ife_csid_170_200_tpg_reg_info = { /*CSID TPG control */ - .csid_tpg_ctrl_addr = 0x600, - .csid_tpg_vc_cfg0_addr = 0x604, - .csid_tpg_vc_cfg1_addr = 0x608, - .csid_tpg_lfsr_seed_addr = 0x60c, - .csid_tpg_dt_n_cfg_0_addr = 0x610, - .csid_tpg_dt_n_cfg_1_addr = 0x614, - .csid_tpg_dt_n_cfg_2_addr = 0x618, - .csid_tpg_color_bars_cfg_addr = 0x640, - .csid_tpg_color_box_cfg_addr = 0x644, - .csid_tpg_common_gen_cfg_addr = 0x648, - .csid_tpg_cgen_n_cfg_addr = 0x650, - .csid_tpg_cgen_n_x0_addr = 0x654, - .csid_tpg_cgen_n_x1_addr = 0x658, - .csid_tpg_cgen_n_x2_addr = 0x65c, - .csid_tpg_cgen_n_xy_addr = 0x660, - .csid_tpg_cgen_n_y1_addr = 0x664, - .csid_tpg_cgen_n_y2_addr = 0x668, + .ctrl_addr = 0x600, + .vc_cfg0_addr = 0x604, + .vc_cfg1_addr = 0x608, + .lfsr_seed_addr = 0x60c, + .dt_n_cfg_0_addr = 0x610, + .dt_n_cfg_1_addr = 0x614, + .dt_n_cfg_2_addr = 0x618, + .color_bars_cfg_addr = 0x640, + .color_box_cfg_addr = 0x644, + .common_gen_cfg_addr = 0x648, + .cgen_n_cfg_addr = 0x650, + .cgen_n_x0_addr = 0x654, + .cgen_n_x1_addr = 0x658, + .cgen_n_x2_addr = 0x65c, + .cgen_n_xy_addr = 0x660, + .cgen_n_y1_addr = 0x664, + .cgen_n_y2_addr = 0x668, /* configurations */ - .tpg_dtn_cfg_offset = 0xc, - .tpg_cgen_cfg_offset = 0x20, - .tpg_cpas_ife_reg_offset = 0x28, + .dtn_cfg_offset = 0xc, + .cgen_cfg_offset = 0x20, + .cpas_ife_reg_offset = 0x28, + .hbi = 0x740, + .vbi = 0x3FF, + .lfsr_seed = 0x12345678, + .ctrl_cfg = 0x408007, + .color_bar = 1, + .line_interleave_mode = 0x1, + .num_frames = 0, + .num_active_lanes_mask = 0x30, + .num_active_dt = 0, + .payload_mode = 0x8, + .fmt_shift = 16, + .num_frame_shift = 16, + .width_shift = 16, + .vbi_shift = 12, + .line_interleave_shift = 10, + .num_active_dt_shift = 8, + .color_bar_shift = 5, + .height_shift = 0, + .hbi_shift = 0, }; -static struct cam_ife_csid_common_reg_offset - cam_ife_csid_170_200_cmn_reg_offset = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, - - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, +static struct cam_ife_csid_ver1_common_reg_info + cam_ife_csid_170_200_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 1, - .minor_version = 7, - .version_incr = 0, - .num_rdis = 3, - .num_pix = 1, - .num_ppp = 1, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .packing_fmt_shift_val = 30, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .crop_shift = 16, - .ipp_irq_mask_all = 0xFFFF, - .rdi_irq_mask_all = 0xFFFF, - .ppp_irq_mask_all = 0xFFFF, - .measure_en_hbi_vbi_cnt_mask = 0xC, - .format_measure_en_val = 1, - .format_measure_height_mask_val = 0xFFFF, - .format_measure_height_shift_val = 0x10, - .format_measure_width_mask_val = 0xFFFF, - .format_measure_width_shift_val = 0x0, + .major_version = 1, + .minor_version = 7, + .version_incr = 0, + .num_rdis = 3, + .num_pix = 1, + .num_ppp = 1, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .crop_shift_val = 16, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .decode_format_shift_val = 12, + .ipp_irq_mask_all = 0xFFFF, + .rdi_irq_mask_all = 0xFFFF, + .ppp_irq_mask_all = 0xFFFF, + .measure_en_hbi_vbi_cnt_mask = 0xC, + .timestamp_strobe_val = 0x2, + .timestamp_stb_sel_shift_val = 0, }; -static struct cam_ife_csid_reg_offset cam_ife_csid_170_200_reg_offset = { - .cmn_reg = &cam_ife_csid_170_200_cmn_reg_offset, - .csi2_reg = &cam_ife_csid_170_200_csi2_reg_offset, - .ipp_reg = &cam_ife_csid_170_200_ipp_reg_offset, - .ppp_reg = &cam_ife_csid_170_200_ppp_reg_offset, +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_170_200_reg_info = { + .cmn_reg = &cam_ife_csid_170_200_cmn_reg_info, + .csi2_reg = &cam_ife_csid_170_200_csi2_reg_info, + .ipp_reg = &cam_ife_csid_170_200_ipp_reg_info, + .ppp_reg = &cam_ife_csid_170_200_ppp_reg_info, .rdi_reg = { - &cam_ife_csid_170_200_rdi_0_reg_offset, - &cam_ife_csid_170_200_rdi_1_reg_offset, - &cam_ife_csid_170_200_rdi_2_reg_offset, + &cam_ife_csid_170_200_rdi_0_reg_info, + &cam_ife_csid_170_200_rdi_1_reg_info, + &cam_ife_csid_170_200_rdi_2_reg_info, NULL, }, - .tpg_reg = &cam_ife_csid_170_200_tpg_reg_offset, + .tpg_reg = &cam_ife_csid_170_200_tpg_reg_info, }; - #endif /*_CAM_IFE_CSID_170_200_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h index 734218bf51..5ca30b2291 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h @@ -6,345 +6,463 @@ #ifndef _CAM_IFE_CSID_175_H_ #define _CAM_IFE_CSID_175_H_ -#include "cam_ife_csid_core.h" +#include +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" +#include "cam_ife_csid_dev.h" +#include "camera_main.h" -static struct cam_ife_csid_pxl_reg_offset cam_ife_csid_175_ipp_reg_offset = { - .csid_pxl_irq_status_addr = 0x30, - .csid_pxl_irq_mask_addr = 0x34, - .csid_pxl_irq_clear_addr = 0x38, - .csid_pxl_irq_set_addr = 0x3c, - - .csid_pxl_cfg0_addr = 0x200, - .csid_pxl_cfg1_addr = 0x204, - .csid_pxl_ctrl_addr = 0x208, - .csid_pxl_frm_drop_pattern_addr = 0x20c, - .csid_pxl_frm_drop_period_addr = 0x210, - .csid_pxl_irq_subsample_pattern_addr = 0x214, - .csid_pxl_irq_subsample_period_addr = 0x218, - .csid_pxl_hcrop_addr = 0x21c, - .csid_pxl_vcrop_addr = 0x220, - .csid_pxl_pix_drop_pattern_addr = 0x224, - .csid_pxl_pix_drop_period_addr = 0x228, - .csid_pxl_line_drop_pattern_addr = 0x22c, - .csid_pxl_line_drop_period_addr = 0x230, - .csid_pxl_rst_strobes_addr = 0x240, - .csid_pxl_status_addr = 0x254, - .csid_pxl_misr_val_addr = 0x258, - .csid_pxl_format_measure_cfg0_addr = 0x270, - .csid_pxl_format_measure_cfg1_addr = 0x274, - .csid_pxl_format_measure0_addr = 0x278, - .csid_pxl_format_measure1_addr = 0x27c, - .csid_pxl_format_measure2_addr = 0x280, - .csid_pxl_timestamp_curr0_sof_addr = 0x290, - .csid_pxl_timestamp_curr1_sof_addr = 0x294, - .csid_pxl_timestamp_perv0_sof_addr = 0x298, - .csid_pxl_timestamp_perv1_sof_addr = 0x29c, - .csid_pxl_timestamp_curr0_eof_addr = 0x2a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x2a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x2a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x2ac, +#define CAM_CSID_VERSION_V175 0x10070050 +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_ipp_reg_info = { + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x254, + .misr_val_addr = 0x258, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, + .halt_master_sel_master_val = 0, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_pxl_reg_offset cam_ife_csid_175_ppp_reg_offset = { - .csid_pxl_irq_status_addr = 0xa0, - .csid_pxl_irq_mask_addr = 0xa4, - .csid_pxl_irq_clear_addr = 0xa8, - .csid_pxl_irq_set_addr = 0xac, - - .csid_pxl_cfg0_addr = 0x700, - .csid_pxl_cfg1_addr = 0x704, - .csid_pxl_ctrl_addr = 0x708, - .csid_pxl_frm_drop_pattern_addr = 0x70c, - .csid_pxl_frm_drop_period_addr = 0x710, - .csid_pxl_irq_subsample_pattern_addr = 0x714, - .csid_pxl_irq_subsample_period_addr = 0x718, - .csid_pxl_hcrop_addr = 0x71c, - .csid_pxl_vcrop_addr = 0x720, - .csid_pxl_pix_drop_pattern_addr = 0x724, - .csid_pxl_pix_drop_period_addr = 0x728, - .csid_pxl_line_drop_pattern_addr = 0x72c, - .csid_pxl_line_drop_period_addr = 0x730, - .csid_pxl_rst_strobes_addr = 0x740, - .csid_pxl_status_addr = 0x754, - .csid_pxl_misr_val_addr = 0x758, - .csid_pxl_format_measure_cfg0_addr = 0x770, - .csid_pxl_format_measure_cfg1_addr = 0x774, - .csid_pxl_format_measure0_addr = 0x778, - .csid_pxl_format_measure1_addr = 0x77c, - .csid_pxl_format_measure2_addr = 0x780, - .csid_pxl_timestamp_curr0_sof_addr = 0x790, - .csid_pxl_timestamp_curr1_sof_addr = 0x794, - .csid_pxl_timestamp_perv0_sof_addr = 0x798, - .csid_pxl_timestamp_perv1_sof_addr = 0x79c, - .csid_pxl_timestamp_curr0_eof_addr = 0x7a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x7a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x7a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x7ac, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_ppp_reg_info = { + .irq_status_addr = 0xa0, + .irq_mask_addr = 0xa4, + .irq_clear_addr = 0xa8, + .irq_set_addr = 0xac, + .cfg0_addr = 0x700, + .cfg1_addr = 0x704, + .ctrl_addr = 0x708, + .frm_drop_pattern_addr = 0x70c, + .frm_drop_period_addr = 0x710, + .irq_subsample_pattern_addr = 0x714, + .irq_subsample_period_addr = 0x718, + .hcrop_addr = 0x71c, + .vcrop_addr = 0x720, + .pix_drop_pattern_addr = 0x724, + .pix_drop_period_addr = 0x728, + .line_drop_pattern_addr = 0x72c, + .line_drop_period_addr = 0x730, + .rst_strobes_addr = 0x740, + .status_addr = 0x754, + .misr_val_addr = 0x758, + .format_measure_cfg0_addr = 0x770, + .format_measure_cfg1_addr = 0x774, + .format_measure0_addr = 0x778, + .format_measure1_addr = 0x77c, + .format_measure2_addr = 0x780, + .timestamp_curr0_sof_addr = 0x790, + .timestamp_curr1_sof_addr = 0x794, + .timestamp_prev0_sof_addr = 0x798, + .timestamp_prev1_sof_addr = 0x79c, + .timestamp_curr0_eof_addr = 0x7a0, + .timestamp_curr1_eof_addr = 0x7a4, + .timestamp_prev0_eof_addr = 0x7a8, + .timestamp_prev1_eof_addr = 0x7ac, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, + .halt_master_sel_master_val = 3, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_175_rdi_0_reg_offset = { - .csid_rdi_irq_status_addr = 0x40, - .csid_rdi_irq_mask_addr = 0x44, - .csid_rdi_irq_clear_addr = 0x48, - .csid_rdi_irq_set_addr = 0x4c, - .csid_rdi_cfg0_addr = 0x300, - .csid_rdi_cfg1_addr = 0x304, - .csid_rdi_ctrl_addr = 0x308, - .csid_rdi_frm_drop_pattern_addr = 0x30c, - .csid_rdi_frm_drop_period_addr = 0x310, - .csid_rdi_irq_subsample_pattern_addr = 0x314, - .csid_rdi_irq_subsample_period_addr = 0x318, - .csid_rdi_rpp_hcrop_addr = 0x31c, - .csid_rdi_rpp_vcrop_addr = 0x320, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x324, - .csid_rdi_rpp_pix_drop_period_addr = 0x328, - .csid_rdi_rpp_line_drop_pattern_addr = 0x32c, - .csid_rdi_rpp_line_drop_period_addr = 0x330, - .csid_rdi_rst_strobes_addr = 0x340, - .csid_rdi_status_addr = 0x350, - .csid_rdi_misr_val0_addr = 0x354, - .csid_rdi_misr_val1_addr = 0x358, - .csid_rdi_misr_val2_addr = 0x35c, - .csid_rdi_misr_val3_addr = 0x360, - .csid_rdi_format_measure_cfg0_addr = 0x370, - .csid_rdi_format_measure_cfg1_addr = 0x374, - .csid_rdi_format_measure0_addr = 0x378, - .csid_rdi_format_measure1_addr = 0x37c, - .csid_rdi_format_measure2_addr = 0x380, - .csid_rdi_timestamp_curr0_sof_addr = 0x390, - .csid_rdi_timestamp_curr1_sof_addr = 0x394, - .csid_rdi_timestamp_prev0_sof_addr = 0x398, - .csid_rdi_timestamp_prev1_sof_addr = 0x39c, - .csid_rdi_timestamp_curr0_eof_addr = 0x3a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x3a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x3a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x3ac, - .csid_rdi_byte_cntr_ping_addr = 0x3e0, - .csid_rdi_byte_cntr_pong_addr = 0x3e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_rdi_0_reg_info = { + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, + .plain_fmt_shift_val = 10, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_175_rdi_1_reg_offset = { - .csid_rdi_irq_status_addr = 0x50, - .csid_rdi_irq_mask_addr = 0x54, - .csid_rdi_irq_clear_addr = 0x58, - .csid_rdi_irq_set_addr = 0x5c, - .csid_rdi_cfg0_addr = 0x400, - .csid_rdi_cfg1_addr = 0x404, - .csid_rdi_ctrl_addr = 0x408, - .csid_rdi_frm_drop_pattern_addr = 0x40c, - .csid_rdi_frm_drop_period_addr = 0x410, - .csid_rdi_irq_subsample_pattern_addr = 0x414, - .csid_rdi_irq_subsample_period_addr = 0x418, - .csid_rdi_rpp_hcrop_addr = 0x41c, - .csid_rdi_rpp_vcrop_addr = 0x420, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x424, - .csid_rdi_rpp_pix_drop_period_addr = 0x428, - .csid_rdi_rpp_line_drop_pattern_addr = 0x42c, - .csid_rdi_rpp_line_drop_period_addr = 0x430, - .csid_rdi_rst_strobes_addr = 0x440, - .csid_rdi_status_addr = 0x450, - .csid_rdi_misr_val0_addr = 0x454, - .csid_rdi_misr_val1_addr = 0x458, - .csid_rdi_misr_val2_addr = 0x45c, - .csid_rdi_misr_val3_addr = 0x460, - .csid_rdi_format_measure_cfg0_addr = 0x470, - .csid_rdi_format_measure_cfg1_addr = 0x474, - .csid_rdi_format_measure0_addr = 0x478, - .csid_rdi_format_measure1_addr = 0x47c, - .csid_rdi_format_measure2_addr = 0x480, - .csid_rdi_timestamp_curr0_sof_addr = 0x490, - .csid_rdi_timestamp_curr1_sof_addr = 0x494, - .csid_rdi_timestamp_prev0_sof_addr = 0x498, - .csid_rdi_timestamp_prev1_sof_addr = 0x49c, - .csid_rdi_timestamp_curr0_eof_addr = 0x4a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x4a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x4a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x4ac, - .csid_rdi_byte_cntr_ping_addr = 0x4e0, - .csid_rdi_byte_cntr_pong_addr = 0x4e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_rdi_1_reg_info = { + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_175_rdi_2_reg_offset = { - .csid_rdi_irq_status_addr = 0x60, - .csid_rdi_irq_mask_addr = 0x64, - .csid_rdi_irq_clear_addr = 0x68, - .csid_rdi_irq_set_addr = 0x6c, - .csid_rdi_cfg0_addr = 0x500, - .csid_rdi_cfg1_addr = 0x504, - .csid_rdi_ctrl_addr = 0x508, - .csid_rdi_frm_drop_pattern_addr = 0x50c, - .csid_rdi_frm_drop_period_addr = 0x510, - .csid_rdi_irq_subsample_pattern_addr = 0x514, - .csid_rdi_irq_subsample_period_addr = 0x518, - .csid_rdi_rpp_hcrop_addr = 0x51c, - .csid_rdi_rpp_vcrop_addr = 0x520, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x524, - .csid_rdi_rpp_pix_drop_period_addr = 0x528, - .csid_rdi_rpp_line_drop_pattern_addr = 0x52c, - .csid_rdi_rpp_line_drop_period_addr = 0x530, - .csid_rdi_yuv_chroma_conversion_addr = 0x534, - .csid_rdi_rst_strobes_addr = 0x540, - .csid_rdi_status_addr = 0x550, - .csid_rdi_misr_val0_addr = 0x554, - .csid_rdi_misr_val1_addr = 0x558, - .csid_rdi_misr_val2_addr = 0x55c, - .csid_rdi_misr_val3_addr = 0x560, - .csid_rdi_format_measure_cfg0_addr = 0x570, - .csid_rdi_format_measure_cfg1_addr = 0x574, - .csid_rdi_format_measure0_addr = 0x578, - .csid_rdi_format_measure1_addr = 0x57c, - .csid_rdi_format_measure2_addr = 0x580, - .csid_rdi_timestamp_curr0_sof_addr = 0x590, - .csid_rdi_timestamp_curr1_sof_addr = 0x594, - .csid_rdi_timestamp_prev0_sof_addr = 0x598, - .csid_rdi_timestamp_prev1_sof_addr = 0x59c, - .csid_rdi_timestamp_curr0_eof_addr = 0x5a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x5a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x5a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x5ac, - .csid_rdi_byte_cntr_ping_addr = 0x5e0, - .csid_rdi_byte_cntr_pong_addr = 0x5e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_rdi_2_reg_info = { + .irq_status_addr = 0x60, + .irq_mask_addr = 0x64, + .irq_clear_addr = 0x68, + .irq_set_addr = 0x6c, + .cfg0_addr = 0x500, + .cfg1_addr = 0x504, + .ctrl_addr = 0x508, + .frm_drop_pattern_addr = 0x50c, + .frm_drop_period_addr = 0x510, + .irq_subsample_pattern_addr = 0x514, + .irq_subsample_period_addr = 0x518, + .hcrop_addr = 0x51c, + .vcrop_addr = 0x520, + .pix_drop_pattern_addr = 0x524, + .pix_drop_period_addr = 0x528, + .line_drop_pattern_addr = 0x52c, + .line_drop_period_addr = 0x530, + .yuv_chroma_conversion_addr = 0x534, + .rst_strobes_addr = 0x540, + .status_addr = 0x550, + .misr_val0_addr = 0x554, + .misr_val1_addr = 0x558, + .misr_val2_addr = 0x55c, + .misr_val3_addr = 0x560, + .format_measure_cfg0_addr = 0x570, + .format_measure_cfg1_addr = 0x574, + .format_measure0_addr = 0x578, + .format_measure1_addr = 0x57c, + .format_measure2_addr = 0x580, + .timestamp_curr0_sof_addr = 0x590, + .timestamp_curr1_sof_addr = 0x594, + .timestamp_prev0_sof_addr = 0x598, + .timestamp_prev1_sof_addr = 0x59c, + .timestamp_curr0_eof_addr = 0x5a0, + .timestamp_curr1_eof_addr = 0x5a4, + .timestamp_prev0_eof_addr = 0x5a8, + .timestamp_prev1_eof_addr = 0x5ac, + .byte_cntr_ping_addr = 0x5e0, + .byte_cntr_pong_addr = 0x5e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_csi2_rx_reg_offset - cam_ife_csid_175_csi2_reg_offset = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, - +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_175_csi2_reg_info = { + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_de_scramble_cfg0_addr = 0x114, - .csid_csi2_rx_de_scramble_cfg1_addr = 0x118, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .de_scramble_cfg0_addr = 0x114, + .de_scramble_cfg1_addr = 0x118, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x3, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x3, + .vc_mask = 0x7C00000, + .dt_mask = 0x3f0000, + .wc_mask = 0xffff0000, + .calc_crc_mask = 0xffff, + .expected_crc_mask = 0xffff, + .ecc_correction_shift_en = 0, + .lane_num_shift = 0, + .lane_cfg_shift = 4, + .phy_type_shift = 24, + .phy_num_shift = 20, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, }; -static struct cam_ife_csid_csi2_tpg_reg_offset - cam_ife_csid_175_tpg_reg_offset = { +static struct cam_ife_csid_ver1_tpg_reg_info + cam_ife_csid_175_tpg_reg_info = { /*CSID TPG control */ - .csid_tpg_ctrl_addr = 0x600, - .csid_tpg_vc_cfg0_addr = 0x604, - .csid_tpg_vc_cfg1_addr = 0x608, - .csid_tpg_lfsr_seed_addr = 0x60c, - .csid_tpg_dt_n_cfg_0_addr = 0x610, - .csid_tpg_dt_n_cfg_1_addr = 0x614, - .csid_tpg_dt_n_cfg_2_addr = 0x618, - .csid_tpg_color_bars_cfg_addr = 0x640, - .csid_tpg_color_box_cfg_addr = 0x644, - .csid_tpg_common_gen_cfg_addr = 0x648, - .csid_tpg_cgen_n_cfg_addr = 0x650, - .csid_tpg_cgen_n_x0_addr = 0x654, - .csid_tpg_cgen_n_x1_addr = 0x658, - .csid_tpg_cgen_n_x2_addr = 0x65c, - .csid_tpg_cgen_n_xy_addr = 0x660, - .csid_tpg_cgen_n_y1_addr = 0x664, - .csid_tpg_cgen_n_y2_addr = 0x668, + .ctrl_addr = 0x600, + .vc_cfg0_addr = 0x604, + .vc_cfg1_addr = 0x608, + .lfsr_seed_addr = 0x60c, + .dt_n_cfg_0_addr = 0x610, + .dt_n_cfg_1_addr = 0x614, + .dt_n_cfg_2_addr = 0x618, + .color_bars_cfg_addr = 0x640, + .color_box_cfg_addr = 0x644, + .common_gen_cfg_addr = 0x648, + .cgen_n_cfg_addr = 0x650, + .cgen_n_x0_addr = 0x654, + .cgen_n_x1_addr = 0x658, + .cgen_n_x2_addr = 0x65c, + .cgen_n_xy_addr = 0x660, + .cgen_n_y1_addr = 0x664, + .cgen_n_y2_addr = 0x668, /* configurations */ - .tpg_dtn_cfg_offset = 0xc, - .tpg_cgen_cfg_offset = 0x20, - .tpg_cpas_ife_reg_offset = 0x28, + .dtn_cfg_offset = 0xc, + .cgen_cfg_offset = 0x20, + .cpas_ife_reg_offset = 0x28, + .hbi = 0x740, + .vbi = 0x3FF, + .lfsr_seed = 0x12345678, + .ctrl_cfg = 0x408007, + .color_bar = 1, + .num_frames = 0, + .line_interleave_mode = 0x1, + .payload_mode = 0x8, + .num_active_lanes_mask = 0x30, + .num_active_dt = 0, + .fmt_shift = 16, + .num_frame_shift = 16, + .width_shift = 16, + .vbi_shift = 12, + .line_interleave_shift = 10, + .num_active_dt_shift = 8, + .color_bar_shift = 5, + .height_shift = 0, + .hbi_shift = 0, }; -static struct cam_ife_csid_common_reg_offset - cam_ife_csid_175_cmn_reg_offset = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, - - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, +static struct cam_ife_csid_ver1_common_reg_info + cam_ife_csid_175_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 1, - .minor_version = 7, - .version_incr = 0, - .num_rdis = 3, - .num_pix = 1, - .num_ppp = 1, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .crop_shift = 16, - .ipp_irq_mask_all = 0x7FFF, - .rdi_irq_mask_all = 0x7FFF, - .ppp_irq_mask_all = 0xFFFF, - .measure_en_hbi_vbi_cnt_mask = 0xC, - .format_measure_en_val = 1, - .format_measure_height_mask_val = 0xFFFF, - .format_measure_height_shift_val = 0x10, - .format_measure_width_mask_val = 0xFFFF, - .format_measure_width_shift_val = 0x0, + .major_version = 1, + .minor_version = 7, + .version_incr = 0, + .num_rdis = 3, + .num_pix = 1, + .num_ppp = 1, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .ipp_irq_mask_all = 0x7FFF, + .rdi_irq_mask_all = 0x7FFF, + .ppp_irq_mask_all = 0xFFFF, + .measure_en_hbi_vbi_cnt_mask = 0xC, + .timestamp_stb_sel_shift_val = 0, + .timestamp_strobe_val = 0x2, }; -static struct cam_ife_csid_reg_offset cam_ife_csid_175_reg_offset = { - .cmn_reg = &cam_ife_csid_175_cmn_reg_offset, - .csi2_reg = &cam_ife_csid_175_csi2_reg_offset, - .ipp_reg = &cam_ife_csid_175_ipp_reg_offset, - .ppp_reg = &cam_ife_csid_175_ppp_reg_offset, +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_175_reg_info = { + .cmn_reg = &cam_ife_csid_175_cmn_reg_info, + .csi2_reg = &cam_ife_csid_175_csi2_reg_info, + .ipp_reg = &cam_ife_csid_175_ipp_reg_info, + .ppp_reg = &cam_ife_csid_175_ppp_reg_info, .rdi_reg = { - &cam_ife_csid_175_rdi_0_reg_offset, - &cam_ife_csid_175_rdi_1_reg_offset, - &cam_ife_csid_175_rdi_2_reg_offset, + &cam_ife_csid_175_rdi_0_reg_info, + &cam_ife_csid_175_rdi_1_reg_info, + &cam_ife_csid_175_rdi_2_reg_info, NULL, }, - .tpg_reg = &cam_ife_csid_175_tpg_reg_offset, + .tpg_reg = &cam_ife_csid_175_tpg_reg_info, }; - #endif /*_CAM_IFE_CSID_175_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h index 1794a860b8..527b512c93 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h @@ -6,363 +6,481 @@ #ifndef _CAM_IFE_CSID_175_200_H_ #define _CAM_IFE_CSID_175_200_H_ -#include "cam_ife_csid_core.h" +#include +#include "camera_main.h" +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" -static struct cam_ife_csid_pxl_reg_offset - cam_ife_csid_175_200_ipp_reg_offset = { - .csid_pxl_irq_status_addr = 0x30, - .csid_pxl_irq_mask_addr = 0x34, - .csid_pxl_irq_clear_addr = 0x38, - .csid_pxl_irq_set_addr = 0x3c, +#define CAM_CSID_DRV_NAME "csid" +#define CAM_CSID_VERSION_V175 0x10070050 - .csid_pxl_cfg0_addr = 0x200, - .csid_pxl_cfg1_addr = 0x204, - .csid_pxl_ctrl_addr = 0x208, - .csid_pxl_frm_drop_pattern_addr = 0x20c, - .csid_pxl_frm_drop_period_addr = 0x210, - .csid_pxl_irq_subsample_pattern_addr = 0x214, - .csid_pxl_irq_subsample_period_addr = 0x218, - .csid_pxl_hcrop_addr = 0x21c, - .csid_pxl_vcrop_addr = 0x220, - .csid_pxl_pix_drop_pattern_addr = 0x224, - .csid_pxl_pix_drop_period_addr = 0x228, - .csid_pxl_line_drop_pattern_addr = 0x22c, - .csid_pxl_line_drop_period_addr = 0x230, - .csid_pxl_rst_strobes_addr = 0x240, - .csid_pxl_status_addr = 0x254, - .csid_pxl_misr_val_addr = 0x258, - .csid_pxl_format_measure_cfg0_addr = 0x270, - .csid_pxl_format_measure_cfg1_addr = 0x274, - .csid_pxl_format_measure0_addr = 0x278, - .csid_pxl_format_measure1_addr = 0x27c, - .csid_pxl_format_measure2_addr = 0x280, - .csid_pxl_timestamp_curr0_sof_addr = 0x290, - .csid_pxl_timestamp_curr1_sof_addr = 0x294, - .csid_pxl_timestamp_perv0_sof_addr = 0x298, - .csid_pxl_timestamp_perv1_sof_addr = 0x29c, - .csid_pxl_timestamp_curr0_eof_addr = 0x2a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x2a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x2a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x2ac, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_200_ipp_reg_info = { + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x254, + .misr_val_addr = 0x258, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, - .quad_cfa_bin_en_shift_val = 30, - .ccif_violation_en = 1, + .halt_master_sel_master_val = 0, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .bin_qcfa_en_shift_val = 30, + .bin_h_en_shift_val = 2, + .bin_en_shift_val = 2, + .binning_supported = 0x3, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_pxl_reg_offset - cam_ife_csid_175_200_ppp_reg_offset = { - .csid_pxl_irq_status_addr = 0xa0, - .csid_pxl_irq_mask_addr = 0xa4, - .csid_pxl_irq_clear_addr = 0xa8, - .csid_pxl_irq_set_addr = 0xac, - - .csid_pxl_cfg0_addr = 0x700, - .csid_pxl_cfg1_addr = 0x704, - .csid_pxl_ctrl_addr = 0x708, - .csid_pxl_frm_drop_pattern_addr = 0x70c, - .csid_pxl_frm_drop_period_addr = 0x710, - .csid_pxl_irq_subsample_pattern_addr = 0x714, - .csid_pxl_irq_subsample_period_addr = 0x718, - .csid_pxl_hcrop_addr = 0x71c, - .csid_pxl_vcrop_addr = 0x720, - .csid_pxl_pix_drop_pattern_addr = 0x724, - .csid_pxl_pix_drop_period_addr = 0x728, - .csid_pxl_line_drop_pattern_addr = 0x72c, - .csid_pxl_line_drop_period_addr = 0x730, - .csid_pxl_rst_strobes_addr = 0x740, - .csid_pxl_status_addr = 0x754, - .csid_pxl_misr_val_addr = 0x758, - .csid_pxl_format_measure_cfg0_addr = 0x770, - .csid_pxl_format_measure_cfg1_addr = 0x774, - .csid_pxl_format_measure0_addr = 0x778, - .csid_pxl_format_measure1_addr = 0x77c, - .csid_pxl_format_measure2_addr = 0x780, - .csid_pxl_timestamp_curr0_sof_addr = 0x790, - .csid_pxl_timestamp_curr1_sof_addr = 0x794, - .csid_pxl_timestamp_perv0_sof_addr = 0x798, - .csid_pxl_timestamp_perv1_sof_addr = 0x79c, - .csid_pxl_timestamp_curr0_eof_addr = 0x7a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x7a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x7a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x7ac, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_200_ppp_reg_info = { + .irq_status_addr = 0xa0, + .irq_mask_addr = 0xa4, + .irq_clear_addr = 0xa8, + .irq_set_addr = 0xac, + .cfg0_addr = 0x700, + .cfg1_addr = 0x704, + .ctrl_addr = 0x708, + .frm_drop_pattern_addr = 0x70c, + .frm_drop_period_addr = 0x710, + .irq_subsample_pattern_addr = 0x714, + .irq_subsample_period_addr = 0x718, + .hcrop_addr = 0x71c, + .vcrop_addr = 0x720, + .pix_drop_pattern_addr = 0x724, + .pix_drop_period_addr = 0x728, + .line_drop_pattern_addr = 0x72c, + .line_drop_period_addr = 0x730, + .rst_strobes_addr = 0x740, + .status_addr = 0x754, + .misr_val_addr = 0x758, + .format_measure_cfg0_addr = 0x770, + .format_measure_cfg1_addr = 0x774, + .format_measure0_addr = 0x778, + .format_measure1_addr = 0x77c, + .format_measure2_addr = 0x780, + .timestamp_curr0_sof_addr = 0x790, + .timestamp_curr1_sof_addr = 0x794, + .timestamp_prev0_sof_addr = 0x798, + .timestamp_prev1_sof_addr = 0x79c, + .timestamp_curr0_eof_addr = 0x7a0, + .timestamp_curr1_eof_addr = 0x7a4, + .timestamp_prev0_eof_addr = 0x7a8, + .timestamp_prev1_eof_addr = 0x7ac, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, - .ccif_violation_en = 1, + .halt_master_sel_master_val = 3, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_175_200_rdi_0_reg_offset = { - .csid_rdi_irq_status_addr = 0x40, - .csid_rdi_irq_mask_addr = 0x44, - .csid_rdi_irq_clear_addr = 0x48, - .csid_rdi_irq_set_addr = 0x4c, - .csid_rdi_cfg0_addr = 0x300, - .csid_rdi_cfg1_addr = 0x304, - .csid_rdi_ctrl_addr = 0x308, - .csid_rdi_frm_drop_pattern_addr = 0x30c, - .csid_rdi_frm_drop_period_addr = 0x310, - .csid_rdi_irq_subsample_pattern_addr = 0x314, - .csid_rdi_irq_subsample_period_addr = 0x318, - .csid_rdi_rpp_hcrop_addr = 0x31c, - .csid_rdi_rpp_vcrop_addr = 0x320, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x324, - .csid_rdi_rpp_pix_drop_period_addr = 0x328, - .csid_rdi_rpp_line_drop_pattern_addr = 0x32c, - .csid_rdi_rpp_line_drop_period_addr = 0x330, - .csid_rdi_rst_strobes_addr = 0x340, - .csid_rdi_status_addr = 0x350, - .csid_rdi_misr_val0_addr = 0x354, - .csid_rdi_misr_val1_addr = 0x358, - .csid_rdi_misr_val2_addr = 0x35c, - .csid_rdi_misr_val3_addr = 0x360, - .csid_rdi_format_measure_cfg0_addr = 0x370, - .csid_rdi_format_measure_cfg1_addr = 0x374, - .csid_rdi_format_measure0_addr = 0x378, - .csid_rdi_format_measure1_addr = 0x37c, - .csid_rdi_format_measure2_addr = 0x380, - .csid_rdi_timestamp_curr0_sof_addr = 0x390, - .csid_rdi_timestamp_curr1_sof_addr = 0x394, - .csid_rdi_timestamp_prev0_sof_addr = 0x398, - .csid_rdi_timestamp_prev1_sof_addr = 0x39c, - .csid_rdi_timestamp_curr0_eof_addr = 0x3a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x3a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x3a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x3ac, - .csid_rdi_byte_cntr_ping_addr = 0x3e0, - .csid_rdi_byte_cntr_pong_addr = 0x3e4, - .ccif_violation_en = 1, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_200_rdi_0_reg_info = { + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .ccif_violation_en = 1, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_175_200_rdi_1_reg_offset = { - .csid_rdi_irq_status_addr = 0x50, - .csid_rdi_irq_mask_addr = 0x54, - .csid_rdi_irq_clear_addr = 0x58, - .csid_rdi_irq_set_addr = 0x5c, - .csid_rdi_cfg0_addr = 0x400, - .csid_rdi_cfg1_addr = 0x404, - .csid_rdi_ctrl_addr = 0x408, - .csid_rdi_frm_drop_pattern_addr = 0x40c, - .csid_rdi_frm_drop_period_addr = 0x410, - .csid_rdi_irq_subsample_pattern_addr = 0x414, - .csid_rdi_irq_subsample_period_addr = 0x418, - .csid_rdi_rpp_hcrop_addr = 0x41c, - .csid_rdi_rpp_vcrop_addr = 0x420, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x424, - .csid_rdi_rpp_pix_drop_period_addr = 0x428, - .csid_rdi_rpp_line_drop_pattern_addr = 0x42c, - .csid_rdi_rpp_line_drop_period_addr = 0x430, - .csid_rdi_rst_strobes_addr = 0x440, - .csid_rdi_status_addr = 0x450, - .csid_rdi_misr_val0_addr = 0x454, - .csid_rdi_misr_val1_addr = 0x458, - .csid_rdi_misr_val2_addr = 0x45c, - .csid_rdi_misr_val3_addr = 0x460, - .csid_rdi_format_measure_cfg0_addr = 0x470, - .csid_rdi_format_measure_cfg1_addr = 0x474, - .csid_rdi_format_measure0_addr = 0x478, - .csid_rdi_format_measure1_addr = 0x47c, - .csid_rdi_format_measure2_addr = 0x480, - .csid_rdi_timestamp_curr0_sof_addr = 0x490, - .csid_rdi_timestamp_curr1_sof_addr = 0x494, - .csid_rdi_timestamp_prev0_sof_addr = 0x498, - .csid_rdi_timestamp_prev1_sof_addr = 0x49c, - .csid_rdi_timestamp_curr0_eof_addr = 0x4a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x4a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x4a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x4ac, - .csid_rdi_byte_cntr_ping_addr = 0x4e0, - .csid_rdi_byte_cntr_pong_addr = 0x4e4, - .ccif_violation_en = 1, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_200_rdi_1_reg_info = { + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .ccif_violation_en = 1, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_175_200_rdi_2_reg_offset = { - .csid_rdi_irq_status_addr = 0x60, - .csid_rdi_irq_mask_addr = 0x64, - .csid_rdi_irq_clear_addr = 0x68, - .csid_rdi_irq_set_addr = 0x6c, - .csid_rdi_cfg0_addr = 0x500, - .csid_rdi_cfg1_addr = 0x504, - .csid_rdi_ctrl_addr = 0x508, - .csid_rdi_frm_drop_pattern_addr = 0x50c, - .csid_rdi_frm_drop_period_addr = 0x510, - .csid_rdi_irq_subsample_pattern_addr = 0x514, - .csid_rdi_irq_subsample_period_addr = 0x518, - .csid_rdi_rpp_hcrop_addr = 0x51c, - .csid_rdi_rpp_vcrop_addr = 0x520, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x524, - .csid_rdi_rpp_pix_drop_period_addr = 0x528, - .csid_rdi_rpp_line_drop_pattern_addr = 0x52c, - .csid_rdi_rpp_line_drop_period_addr = 0x530, - .csid_rdi_yuv_chroma_conversion_addr = 0x534, - .csid_rdi_rst_strobes_addr = 0x540, - .csid_rdi_status_addr = 0x550, - .csid_rdi_misr_val0_addr = 0x554, - .csid_rdi_misr_val1_addr = 0x558, - .csid_rdi_misr_val2_addr = 0x55c, - .csid_rdi_misr_val3_addr = 0x560, - .csid_rdi_format_measure_cfg0_addr = 0x570, - .csid_rdi_format_measure_cfg1_addr = 0x574, - .csid_rdi_format_measure0_addr = 0x578, - .csid_rdi_format_measure1_addr = 0x57c, - .csid_rdi_format_measure2_addr = 0x580, - .csid_rdi_timestamp_curr0_sof_addr = 0x590, - .csid_rdi_timestamp_curr1_sof_addr = 0x594, - .csid_rdi_timestamp_prev0_sof_addr = 0x598, - .csid_rdi_timestamp_prev1_sof_addr = 0x59c, - .csid_rdi_timestamp_curr0_eof_addr = 0x5a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x5a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x5a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x5ac, - .csid_rdi_byte_cntr_ping_addr = 0x5e0, - .csid_rdi_byte_cntr_pong_addr = 0x5e4, - .ccif_violation_en = 1, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_175_200_rdi_2_reg_info = { + .irq_status_addr = 0x60, + .irq_mask_addr = 0x64, + .irq_clear_addr = 0x68, + .irq_set_addr = 0x6c, + .cfg0_addr = 0x500, + .cfg1_addr = 0x504, + .ctrl_addr = 0x508, + .frm_drop_pattern_addr = 0x50c, + .frm_drop_period_addr = 0x510, + .irq_subsample_pattern_addr = 0x514, + .irq_subsample_period_addr = 0x518, + .hcrop_addr = 0x51c, + .vcrop_addr = 0x520, + .pix_drop_pattern_addr = 0x524, + .pix_drop_period_addr = 0x528, + .line_drop_pattern_addr = 0x52c, + .line_drop_period_addr = 0x530, + .yuv_chroma_conversion_addr = 0x534, + .rst_strobes_addr = 0x540, + .status_addr = 0x550, + .misr_val0_addr = 0x554, + .misr_val1_addr = 0x558, + .misr_val2_addr = 0x55c, + .misr_val3_addr = 0x560, + .format_measure_cfg0_addr = 0x570, + .format_measure_cfg1_addr = 0x574, + .format_measure0_addr = 0x578, + .format_measure1_addr = 0x57c, + .format_measure2_addr = 0x580, + .timestamp_curr0_sof_addr = 0x590, + .timestamp_curr1_sof_addr = 0x594, + .timestamp_prev0_sof_addr = 0x598, + .timestamp_prev1_sof_addr = 0x59c, + .timestamp_curr0_eof_addr = 0x5a0, + .timestamp_curr1_eof_addr = 0x5a4, + .timestamp_prev0_eof_addr = 0x5a8, + .timestamp_prev1_eof_addr = 0x5ac, + .byte_cntr_ping_addr = 0x5e0, + .byte_cntr_pong_addr = 0x5e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .ccif_violation_en = 1, + .plain_fmt_shift_val = 10, + .mipi_pack_supported = 1, + .packing_fmt_shift_val = 30, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static struct cam_ife_csid_csi2_rx_reg_offset - cam_ife_csid_175_200_csi2_reg_offset = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, - +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_175_200_csi2_reg_info = { + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, - .csid_csi2_rx_de_scramble_type3_cfg0_addr = 0x170, - .csid_csi2_rx_de_scramble_type3_cfg1_addr = 0x174, - .csid_csi2_rx_de_scramble_type2_cfg0_addr = 0x178, - .csid_csi2_rx_de_scramble_type2_cfg1_addr = 0x17c, - .csid_csi2_rx_de_scramble_type1_cfg0_addr = 0x180, - .csid_csi2_rx_de_scramble_type1_cfg1_addr = 0x184, - .csid_csi2_rx_de_scramble_type0_cfg0_addr = 0x188, - .csid_csi2_rx_de_scramble_type0_cfg1_addr = 0x18c, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, + .de_scramble_type3_cfg0_addr = 0x170, + .de_scramble_type3_cfg1_addr = 0x174, + .de_scramble_type2_cfg0_addr = 0x178, + .de_scramble_type2_cfg1_addr = 0x17c, + .de_scramble_type1_cfg0_addr = 0x180, + .de_scramble_type1_cfg1_addr = 0x184, + .de_scramble_type0_cfg0_addr = 0x188, + .de_scramble_type0_cfg1_addr = 0x18c, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x7, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x7, + .vc_mask = 0x7C00000, + .dt_mask = 0x3f0000, + .wc_mask = 0xffff0000, + .calc_crc_mask = 0xffff, + .expected_crc_mask = 0xffff, + .ecc_correction_shift_en = 0, + .lane_num_shift = 0, + .lane_cfg_shift = 4, + .phy_type_shift = 24, + .phy_num_shift = 20, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, }; -static struct cam_ife_csid_csi2_tpg_reg_offset - cam_ife_csid_175_200_tpg_reg_offset = { +static struct cam_ife_csid_ver1_tpg_reg_info + cam_ife_csid_175_200_tpg_reg_info = { /*CSID TPG control */ - .csid_tpg_ctrl_addr = 0x600, - .csid_tpg_vc_cfg0_addr = 0x604, - .csid_tpg_vc_cfg1_addr = 0x608, - .csid_tpg_lfsr_seed_addr = 0x60c, - .csid_tpg_dt_n_cfg_0_addr = 0x610, - .csid_tpg_dt_n_cfg_1_addr = 0x614, - .csid_tpg_dt_n_cfg_2_addr = 0x618, - .csid_tpg_color_bars_cfg_addr = 0x640, - .csid_tpg_color_box_cfg_addr = 0x644, - .csid_tpg_common_gen_cfg_addr = 0x648, - .csid_tpg_cgen_n_cfg_addr = 0x650, - .csid_tpg_cgen_n_x0_addr = 0x654, - .csid_tpg_cgen_n_x1_addr = 0x658, - .csid_tpg_cgen_n_x2_addr = 0x65c, - .csid_tpg_cgen_n_xy_addr = 0x660, - .csid_tpg_cgen_n_y1_addr = 0x664, - .csid_tpg_cgen_n_y2_addr = 0x668, - + .ctrl_addr = 0x600, + .vc_cfg0_addr = 0x604, + .vc_cfg1_addr = 0x608, + .lfsr_seed_addr = 0x60c, + .dt_n_cfg_0_addr = 0x610, + .dt_n_cfg_1_addr = 0x614, + .dt_n_cfg_2_addr = 0x618, + .color_bars_cfg_addr = 0x640, + .color_box_cfg_addr = 0x644, + .common_gen_cfg_addr = 0x648, + .cgen_n_cfg_addr = 0x650, + .cgen_n_x0_addr = 0x654, + .cgen_n_x1_addr = 0x658, + .cgen_n_x2_addr = 0x65c, + .cgen_n_xy_addr = 0x660, + .cgen_n_y1_addr = 0x664, + .cgen_n_y2_addr = 0x668, /* configurations */ - .tpg_dtn_cfg_offset = 0xc, - .tpg_cgen_cfg_offset = 0x20, - .tpg_cpas_ife_reg_offset = 0x28, + .dtn_cfg_offset = 0xc, + .cgen_cfg_offset = 0x20, + .cpas_ife_reg_offset = 0x28, + .hbi = 0x740, + .vbi = 0x3FF, + .ctrl_cfg = 0x408007, + .lfsr_seed = 0x12345678, + .color_bar = 1, + .num_frames = 0, + .line_interleave_mode = 0x1, + .payload_mode = 0x8, + .num_active_lanes_mask = 0x30, + .num_active_dt = 0, + .fmt_shift = 16, + .num_frame_shift = 16, + .width_shift = 16, + .vbi_shift = 12, + .line_interleave_shift = 10, + .num_active_dt_shift = 8, + .color_bar_shift = 5, + .height_shift = 0, + .hbi_shift = 0, }; -static struct cam_ife_csid_common_reg_offset - cam_ife_csid_175_200_cmn_reg_offset = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, - - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, +static struct cam_ife_csid_ver1_common_reg_info + cam_ife_csid_175_200_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 1, - .minor_version = 7, - .version_incr = 5, - .num_rdis = 3, - .num_pix = 1, - .num_ppp = 1, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .packing_fmt_shift_val = 30, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .crop_shift = 16, - .ipp_irq_mask_all = 0xFFFF, - .rdi_irq_mask_all = 0xFFFF, - .ppp_irq_mask_all = 0xFFFF, - .measure_en_hbi_vbi_cnt_mask = 0xC, - .format_measure_en_val = 1, - .format_measure_height_mask_val = 0xFFFF, - .format_measure_height_shift_val = 0x10, - .format_measure_width_mask_val = 0xFFFF, - .format_measure_width_shift_val = 0x0, + .major_version = 1, + .minor_version = 7, + .version_incr = 5, + .num_rdis = 3, + .num_pix = 1, + .num_ppp = 1, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .ipp_irq_mask_all = 0xFFFF, + .rdi_irq_mask_all = 0xFFFF, + .ppp_irq_mask_all = 0xFFFF, + .measure_en_hbi_vbi_cnt_mask = 0xC, + .timestamp_strobe_val = 0x2, + .timestamp_stb_sel_shift_val = 0, }; -static struct cam_ife_csid_reg_offset cam_ife_csid_175_200_reg_offset = { - .cmn_reg = &cam_ife_csid_175_200_cmn_reg_offset, - .csi2_reg = &cam_ife_csid_175_200_csi2_reg_offset, - .ipp_reg = &cam_ife_csid_175_200_ipp_reg_offset, - .ppp_reg = &cam_ife_csid_175_200_ppp_reg_offset, +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_175_200_reg_info = { + .cmn_reg = &cam_ife_csid_175_200_cmn_reg_info, + .csi2_reg = &cam_ife_csid_175_200_csi2_reg_info, + .ipp_reg = &cam_ife_csid_175_200_ipp_reg_info, + .ppp_reg = &cam_ife_csid_175_200_ppp_reg_info, .rdi_reg = { - &cam_ife_csid_175_200_rdi_0_reg_offset, - &cam_ife_csid_175_200_rdi_1_reg_offset, - &cam_ife_csid_175_200_rdi_2_reg_offset, + &cam_ife_csid_175_200_rdi_0_reg_info, + &cam_ife_csid_175_200_rdi_1_reg_info, + &cam_ife_csid_175_200_rdi_2_reg_info, NULL, }, - .tpg_reg = &cam_ife_csid_175_200_tpg_reg_offset, + .tpg_reg = &cam_ife_csid_175_200_tpg_reg_info, }; - #endif /*_CAM_IFE_CSID_175_200_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid17x.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid17x.c deleted file mode 100644 index a599030402..0000000000 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid17x.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - */ - - -#include -#include "cam_ife_csid_core.h" -#include "cam_ife_csid170.h" -#include "cam_ife_csid170_200.h" -#include "cam_ife_csid175.h" -#include "cam_ife_csid175_200.h" -#include "cam_ife_csid480.h" -#include "cam_ife_csid_dev.h" -#include "camera_main.h" - -#define CAM_CSID_DRV_NAME "csid_17x" -#define CAM_CSID_VERSION_V170 0x10070000 -#define CAM_CSID_VERSION_V175 0x10070050 -#define CAM_CSID_VERSION_V480 0x40080000 - -static struct cam_ife_csid_hw_info cam_ife_csid170_hw_info = { - .csid_reg = &cam_ife_csid_170_reg_offset, - .hw_dts_version = CAM_CSID_VERSION_V170, -}; - -static struct cam_ife_csid_hw_info cam_ife_csid170_200_hw_info = { - .csid_reg = &cam_ife_csid_170_200_reg_offset, - .hw_dts_version = CAM_CSID_VERSION_V170, -}; - -static struct cam_ife_csid_hw_info cam_ife_csid175_hw_info = { - .csid_reg = &cam_ife_csid_175_reg_offset, - .hw_dts_version = CAM_CSID_VERSION_V175, -}; - -static struct cam_ife_csid_hw_info cam_ife_csid175_200_hw_info = { - .csid_reg = &cam_ife_csid_175_200_reg_offset, - .hw_dts_version = CAM_CSID_VERSION_V175, -}; - -static struct cam_ife_csid_hw_info cam_ife_csid480_hw_info = { - .csid_reg = &cam_ife_csid_480_reg_offset, - .hw_dts_version = CAM_CSID_VERSION_V480, -}; - -static const struct of_device_id cam_ife_csid17x_dt_match[] = { - { - .compatible = "qcom,csid170", - .data = &cam_ife_csid170_hw_info, - }, - { - .compatible = "qcom,csid170_200", - .data = &cam_ife_csid170_200_hw_info, - }, - { - .compatible = "qcom,csid175", - .data = &cam_ife_csid175_hw_info, - }, - { - .compatible = "qcom,csid175_200", - .data = &cam_ife_csid175_200_hw_info, - }, - { - .compatible = "qcom,csid480", - .data = &cam_ife_csid480_hw_info, - }, - { - .compatible = "qcom,csid580", - .data = &cam_ife_csid480_hw_info, - }, - {} -}; - -MODULE_DEVICE_TABLE(of, cam_ife_csid17x_dt_match); - -struct platform_driver cam_ife_csid17x_driver = { - .probe = cam_ife_csid_probe, - .remove = cam_ife_csid_remove, - .driver = { - .name = CAM_CSID_DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = cam_ife_csid17x_dt_match, - .suppress_bind_attrs = true, - }, -}; - -int cam_ife_csid17x_init_module(void) -{ - return platform_driver_register(&cam_ife_csid17x_driver); -} - -void cam_ife_csid17x_exit_module(void) -{ - platform_driver_unregister(&cam_ife_csid17x_driver); -} - -MODULE_DESCRIPTION("CAM IFE_CSID17X driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h index f9a3e8bc4b..93151f13ea 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h @@ -6,384 +6,525 @@ #ifndef _CAM_IFE_CSID_480_H_ #define _CAM_IFE_CSID_480_H_ -#include "cam_ife_csid_core.h" +#include +#include "camera_main.h" +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" -static struct cam_ife_csid_pxl_reg_offset cam_ife_csid_480_ipp_reg_offset = { - .csid_pxl_irq_status_addr = 0x30, - .csid_pxl_irq_mask_addr = 0x34, - .csid_pxl_irq_clear_addr = 0x38, - .csid_pxl_irq_set_addr = 0x3c, +#define CAM_CSID_VERSION_V480 0x40080000 - .csid_pxl_cfg0_addr = 0x200, - .csid_pxl_cfg1_addr = 0x204, - .csid_pxl_ctrl_addr = 0x208, - .csid_pxl_frm_drop_pattern_addr = 0x20c, - .csid_pxl_frm_drop_period_addr = 0x210, - .csid_pxl_irq_subsample_pattern_addr = 0x214, - .csid_pxl_irq_subsample_period_addr = 0x218, - .csid_pxl_hcrop_addr = 0x21c, - .csid_pxl_vcrop_addr = 0x220, - .csid_pxl_pix_drop_pattern_addr = 0x224, - .csid_pxl_pix_drop_period_addr = 0x228, - .csid_pxl_line_drop_pattern_addr = 0x22c, - .csid_pxl_line_drop_period_addr = 0x230, - .csid_pxl_rst_strobes_addr = 0x240, - .csid_pxl_status_addr = 0x254, - .csid_pxl_misr_val_addr = 0x258, - .csid_pxl_format_measure_cfg0_addr = 0x270, - .csid_pxl_format_measure_cfg1_addr = 0x274, - .csid_pxl_format_measure0_addr = 0x278, - .csid_pxl_format_measure1_addr = 0x27c, - .csid_pxl_format_measure2_addr = 0x280, - .csid_pxl_timestamp_curr0_sof_addr = 0x290, - .csid_pxl_timestamp_curr1_sof_addr = 0x294, - .csid_pxl_timestamp_perv0_sof_addr = 0x298, - .csid_pxl_timestamp_perv1_sof_addr = 0x29c, - .csid_pxl_timestamp_curr0_eof_addr = 0x2a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x2a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x2a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x2ac, - .csid_pxl_err_recovery_cfg0_addr = 0x2d0, - .csid_pxl_err_recovery_cfg1_addr = 0x2d4, - .csid_pxl_err_recovery_cfg2_addr = 0x2d8, - .csid_pxl_multi_vcdt_cfg0_addr = 0x2dc, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_480_ipp_reg_info = { + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x254, + .misr_val_addr = 0x258, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, + .err_recovery_cfg0_addr = 0x2d0, + .err_recovery_cfg1_addr = 0x2d4, + .err_recovery_cfg2_addr = 0x2d8, + .multi_vcdt_cfg0_addr = 0x2dc, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, - .horizontal_bin_en_shift_val = 2, - .quad_cfa_bin_en_shift_val = 30, - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, - .hblank_cfg_shift_val = 4, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + //.hblank_cfg_shift_val = 4, + .halt_master_sel_master_val = 0, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .bin_h_en_shift_val = 2, + .bin_en_shift_val = 2, + .bin_qcfa_en_shift_val = 30, + .binning_supported = 0x3, + .overflow_ctrl_mode_val = 0x8, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_pxl_reg_offset cam_ife_csid_480_ppp_reg_offset = { - .csid_pxl_irq_status_addr = 0xa0, - .csid_pxl_irq_mask_addr = 0xa4, - .csid_pxl_irq_clear_addr = 0xa8, - .csid_pxl_irq_set_addr = 0xac, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_480_ppp_reg_info = { + .irq_status_addr = 0xa0, + .irq_mask_addr = 0xa4, + .irq_clear_addr = 0xa8, + .irq_set_addr = 0xac, - .csid_pxl_cfg0_addr = 0x700, - .csid_pxl_cfg1_addr = 0x704, - .csid_pxl_ctrl_addr = 0x708, - .csid_pxl_frm_drop_pattern_addr = 0x70c, - .csid_pxl_frm_drop_period_addr = 0x710, - .csid_pxl_irq_subsample_pattern_addr = 0x714, - .csid_pxl_irq_subsample_period_addr = 0x718, - .csid_pxl_hcrop_addr = 0x71c, - .csid_pxl_vcrop_addr = 0x720, - .csid_pxl_pix_drop_pattern_addr = 0x724, - .csid_pxl_pix_drop_period_addr = 0x728, - .csid_pxl_line_drop_pattern_addr = 0x72c, - .csid_pxl_line_drop_period_addr = 0x730, - .csid_pxl_rst_strobes_addr = 0x740, - .csid_pxl_status_addr = 0x754, - .csid_pxl_misr_val_addr = 0x758, - .csid_pxl_format_measure_cfg0_addr = 0x770, - .csid_pxl_format_measure_cfg1_addr = 0x774, - .csid_pxl_format_measure0_addr = 0x778, - .csid_pxl_format_measure1_addr = 0x77c, - .csid_pxl_format_measure2_addr = 0x780, - .csid_pxl_timestamp_curr0_sof_addr = 0x790, - .csid_pxl_timestamp_curr1_sof_addr = 0x794, - .csid_pxl_timestamp_perv0_sof_addr = 0x798, - .csid_pxl_timestamp_perv1_sof_addr = 0x79c, - .csid_pxl_timestamp_curr0_eof_addr = 0x7a0, - .csid_pxl_timestamp_curr1_eof_addr = 0x7a4, - .csid_pxl_timestamp_perv0_eof_addr = 0x7a8, - .csid_pxl_timestamp_perv1_eof_addr = 0x7ac, - .csid_pxl_err_recovery_cfg0_addr = 0x7d0, - .csid_pxl_err_recovery_cfg1_addr = 0x7d4, - .csid_pxl_err_recovery_cfg2_addr = 0x7d8, - .csid_pxl_multi_vcdt_cfg0_addr = 0x7dc, + .cfg0_addr = 0x700, + .cfg1_addr = 0x704, + .ctrl_addr = 0x708, + .frm_drop_pattern_addr = 0x70c, + .frm_drop_period_addr = 0x710, + .irq_subsample_pattern_addr = 0x714, + .irq_subsample_period_addr = 0x718, + .hcrop_addr = 0x71c, + .vcrop_addr = 0x720, + .pix_drop_pattern_addr = 0x724, + .pix_drop_period_addr = 0x728, + .line_drop_pattern_addr = 0x72c, + .line_drop_period_addr = 0x730, + .rst_strobes_addr = 0x740, + .status_addr = 0x754, + .misr_val_addr = 0x758, + .format_measure_cfg0_addr = 0x770, + .format_measure_cfg1_addr = 0x774, + .format_measure0_addr = 0x778, + .format_measure1_addr = 0x77c, + .format_measure2_addr = 0x780, + .timestamp_curr0_sof_addr = 0x790, + .timestamp_curr1_sof_addr = 0x794, + .timestamp_prev0_sof_addr = 0x798, + .timestamp_prev1_sof_addr = 0x79c, + .timestamp_curr0_eof_addr = 0x7a0, + .timestamp_curr1_eof_addr = 0x7a4, + .timestamp_prev0_eof_addr = 0x7a8, + .timestamp_prev1_eof_addr = 0x7ac, + .err_recovery_cfg0_addr = 0x7d0, + .err_recovery_cfg1_addr = 0x7d4, + .err_recovery_cfg2_addr = 0x7d8, + .multi_vcdt_cfg0_addr = 0x7dc, /* configurations */ - .pix_store_en_shift_val = 7, - .early_eof_en_shift_val = 29, - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_master_sel_master_val = 3, + .halt_master_sel_shift = 4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_master = 2, + .halt_mode_slave = 3, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .pix_store_en_shift_val = 7, + .early_eof_en_shift_val = 29, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .timestamp_en_shift_val = 1, + .format_measure_en_shift_val = 0, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; - -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_480_rdi_0_reg_offset = { - .csid_rdi_irq_status_addr = 0x40, - .csid_rdi_irq_mask_addr = 0x44, - .csid_rdi_irq_clear_addr = 0x48, - .csid_rdi_irq_set_addr = 0x4c, - .csid_rdi_cfg0_addr = 0x300, - .csid_rdi_cfg1_addr = 0x304, - .csid_rdi_ctrl_addr = 0x308, - .csid_rdi_frm_drop_pattern_addr = 0x30c, - .csid_rdi_frm_drop_period_addr = 0x310, - .csid_rdi_irq_subsample_pattern_addr = 0x314, - .csid_rdi_irq_subsample_period_addr = 0x318, - .csid_rdi_rpp_hcrop_addr = 0x31c, - .csid_rdi_rpp_vcrop_addr = 0x320, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x324, - .csid_rdi_rpp_pix_drop_period_addr = 0x328, - .csid_rdi_rpp_line_drop_pattern_addr = 0x32c, - .csid_rdi_rpp_line_drop_period_addr = 0x330, - .csid_rdi_rst_strobes_addr = 0x340, - .csid_rdi_status_addr = 0x350, - .csid_rdi_misr_val0_addr = 0x354, - .csid_rdi_misr_val1_addr = 0x358, - .csid_rdi_misr_val2_addr = 0x35c, - .csid_rdi_misr_val3_addr = 0x360, - .csid_rdi_format_measure_cfg0_addr = 0x370, - .csid_rdi_format_measure_cfg1_addr = 0x374, - .csid_rdi_format_measure0_addr = 0x378, - .csid_rdi_format_measure1_addr = 0x37c, - .csid_rdi_format_measure2_addr = 0x380, - .csid_rdi_timestamp_curr0_sof_addr = 0x390, - .csid_rdi_timestamp_curr1_sof_addr = 0x394, - .csid_rdi_timestamp_prev0_sof_addr = 0x398, - .csid_rdi_timestamp_prev1_sof_addr = 0x39c, - .csid_rdi_timestamp_curr0_eof_addr = 0x3a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x3a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x3a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x3ac, - .csid_rdi_err_recovery_cfg0_addr = 0x3b0, - .csid_rdi_err_recovery_cfg1_addr = 0x3b4, - .csid_rdi_err_recovery_cfg2_addr = 0x3b8, - .csid_rdi_multi_vcdt_cfg0_addr = 0x3bc, - .csid_rdi_byte_cntr_ping_addr = 0x3e0, - .csid_rdi_byte_cntr_pong_addr = 0x3e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_480_rdi_0_reg_info = { + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .err_recovery_cfg0_addr = 0x3b0, + .err_recovery_cfg1_addr = 0x3b4, + .err_recovery_cfg2_addr = 0x3b8, + .multi_vcdt_cfg0_addr = 0x3bc, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .plain_fmt_shift_val = 10, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_480_rdi_1_reg_offset = { - .csid_rdi_irq_status_addr = 0x50, - .csid_rdi_irq_mask_addr = 0x54, - .csid_rdi_irq_clear_addr = 0x58, - .csid_rdi_irq_set_addr = 0x5c, - .csid_rdi_cfg0_addr = 0x400, - .csid_rdi_cfg1_addr = 0x404, - .csid_rdi_ctrl_addr = 0x408, - .csid_rdi_frm_drop_pattern_addr = 0x40c, - .csid_rdi_frm_drop_period_addr = 0x410, - .csid_rdi_irq_subsample_pattern_addr = 0x414, - .csid_rdi_irq_subsample_period_addr = 0x418, - .csid_rdi_rpp_hcrop_addr = 0x41c, - .csid_rdi_rpp_vcrop_addr = 0x420, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x424, - .csid_rdi_rpp_pix_drop_period_addr = 0x428, - .csid_rdi_rpp_line_drop_pattern_addr = 0x42c, - .csid_rdi_rpp_line_drop_period_addr = 0x430, - .csid_rdi_rst_strobes_addr = 0x440, - .csid_rdi_status_addr = 0x450, - .csid_rdi_misr_val0_addr = 0x454, - .csid_rdi_misr_val1_addr = 0x458, - .csid_rdi_misr_val2_addr = 0x45c, - .csid_rdi_misr_val3_addr = 0x460, - .csid_rdi_format_measure_cfg0_addr = 0x470, - .csid_rdi_format_measure_cfg1_addr = 0x474, - .csid_rdi_format_measure0_addr = 0x478, - .csid_rdi_format_measure1_addr = 0x47c, - .csid_rdi_format_measure2_addr = 0x480, - .csid_rdi_timestamp_curr0_sof_addr = 0x490, - .csid_rdi_timestamp_curr1_sof_addr = 0x494, - .csid_rdi_timestamp_prev0_sof_addr = 0x498, - .csid_rdi_timestamp_prev1_sof_addr = 0x49c, - .csid_rdi_timestamp_curr0_eof_addr = 0x4a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x4a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x4a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x4ac, - .csid_rdi_err_recovery_cfg0_addr = 0x4b0, - .csid_rdi_err_recovery_cfg1_addr = 0x4b4, - .csid_rdi_err_recovery_cfg2_addr = 0x4b8, - .csid_rdi_multi_vcdt_cfg0_addr = 0x4bc, - .csid_rdi_byte_cntr_ping_addr = 0x4e0, - .csid_rdi_byte_cntr_pong_addr = 0x4e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_480_rdi_1_reg_info = { + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .err_recovery_cfg0_addr = 0x4b0, + .err_recovery_cfg1_addr = 0x4b4, + .err_recovery_cfg2_addr = 0x4b8, + .multi_vcdt_cfg0_addr = 0x4bc, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .plain_fmt_shift_val = 10, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_rdi_reg_offset cam_ife_csid_480_rdi_2_reg_offset = { - .csid_rdi_irq_status_addr = 0x60, - .csid_rdi_irq_mask_addr = 0x64, - .csid_rdi_irq_clear_addr = 0x68, - .csid_rdi_irq_set_addr = 0x6c, - .csid_rdi_cfg0_addr = 0x500, - .csid_rdi_cfg1_addr = 0x504, - .csid_rdi_ctrl_addr = 0x508, - .csid_rdi_frm_drop_pattern_addr = 0x50c, - .csid_rdi_frm_drop_period_addr = 0x510, - .csid_rdi_irq_subsample_pattern_addr = 0x514, - .csid_rdi_irq_subsample_period_addr = 0x518, - .csid_rdi_rpp_hcrop_addr = 0x51c, - .csid_rdi_rpp_vcrop_addr = 0x520, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x524, - .csid_rdi_rpp_pix_drop_period_addr = 0x528, - .csid_rdi_rpp_line_drop_pattern_addr = 0x52c, - .csid_rdi_rpp_line_drop_period_addr = 0x530, - .csid_rdi_yuv_chroma_conversion_addr = 0x534, - .csid_rdi_rst_strobes_addr = 0x540, - .csid_rdi_status_addr = 0x550, - .csid_rdi_misr_val0_addr = 0x554, - .csid_rdi_misr_val1_addr = 0x558, - .csid_rdi_misr_val2_addr = 0x55c, - .csid_rdi_misr_val3_addr = 0x560, - .csid_rdi_format_measure_cfg0_addr = 0x570, - .csid_rdi_format_measure_cfg1_addr = 0x574, - .csid_rdi_format_measure0_addr = 0x578, - .csid_rdi_format_measure1_addr = 0x57c, - .csid_rdi_format_measure2_addr = 0x580, - .csid_rdi_timestamp_curr0_sof_addr = 0x590, - .csid_rdi_timestamp_curr1_sof_addr = 0x594, - .csid_rdi_timestamp_prev0_sof_addr = 0x598, - .csid_rdi_timestamp_prev1_sof_addr = 0x59c, - .csid_rdi_timestamp_curr0_eof_addr = 0x5a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x5a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x5a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x5ac, - .csid_rdi_err_recovery_cfg0_addr = 0x5b0, - .csid_rdi_err_recovery_cfg1_addr = 0x5b4, - .csid_rdi_err_recovery_cfg2_addr = 0x5b8, - .csid_rdi_multi_vcdt_cfg0_addr = 0x5bc, - .csid_rdi_byte_cntr_ping_addr = 0x5e0, - .csid_rdi_byte_cntr_pong_addr = 0x5e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_480_rdi_2_reg_info = { + .irq_status_addr = 0x60, + .irq_mask_addr = 0x64, + .irq_clear_addr = 0x68, + .irq_set_addr = 0x6c, + .cfg0_addr = 0x500, + .cfg1_addr = 0x504, + .ctrl_addr = 0x508, + .frm_drop_pattern_addr = 0x50c, + .frm_drop_period_addr = 0x510, + .irq_subsample_pattern_addr = 0x514, + .irq_subsample_period_addr = 0x518, + .hcrop_addr = 0x51c, + .vcrop_addr = 0x520, + .pix_drop_pattern_addr = 0x524, + .pix_drop_period_addr = 0x528, + .line_drop_pattern_addr = 0x52c, + .line_drop_period_addr = 0x530, + .yuv_chroma_conversion_addr = 0x534, + .rst_strobes_addr = 0x540, + .status_addr = 0x550, + .misr_val0_addr = 0x554, + .misr_val1_addr = 0x558, + .misr_val2_addr = 0x55c, + .misr_val3_addr = 0x560, + .format_measure_cfg0_addr = 0x570, + .format_measure_cfg1_addr = 0x574, + .format_measure0_addr = 0x578, + .format_measure1_addr = 0x57c, + .format_measure2_addr = 0x580, + .timestamp_curr0_sof_addr = 0x590, + .timestamp_curr1_sof_addr = 0x594, + .timestamp_prev0_sof_addr = 0x598, + .timestamp_prev1_sof_addr = 0x59c, + .timestamp_curr0_eof_addr = 0x5a0, + .timestamp_curr1_eof_addr = 0x5a4, + .timestamp_prev0_eof_addr = 0x5a8, + .timestamp_prev1_eof_addr = 0x5ac, + .err_recovery_cfg0_addr = 0x5b0, + .err_recovery_cfg1_addr = 0x5b4, + .err_recovery_cfg2_addr = 0x5b8, + .multi_vcdt_cfg0_addr = 0x5bc, + .byte_cntr_ping_addr = 0x5e0, + .byte_cntr_pong_addr = 0x5e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .plain_fmt_shift_val = 10, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_csi2_rx_reg_offset - cam_ife_csid_480_csi2_reg_offset = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_480_csi2_reg_info = { + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_de_scramble_cfg0_addr = 0x114, - .csid_csi2_rx_de_scramble_cfg1_addr = 0x118, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .de_scramble_cfg0_addr = 0x114, + .de_scramble_cfg1_addr = 0x118, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x7, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x7, + .vc_mask = 0x7C00000, + .dt_mask = 0x3f0000, + .wc_mask = 0xffff0000, + .calc_crc_mask = 0xffff, + .expected_crc_mask = 0xffff, + .ecc_correction_shift_en = 0, + .lane_num_shift = 0, + .lane_cfg_shift = 4, + .phy_type_shift = 24, + .phy_num_shift = 20, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, }; -static struct cam_ife_csid_csi2_tpg_reg_offset - cam_ife_csid_480_tpg_reg_offset = { +static struct cam_ife_csid_ver1_tpg_reg_info + cam_ife_csid_480_tpg_reg_info = { /*CSID TPG control */ - .csid_tpg_ctrl_addr = 0x600, - .csid_tpg_vc_cfg0_addr = 0x604, - .csid_tpg_vc_cfg1_addr = 0x608, - .csid_tpg_lfsr_seed_addr = 0x60c, - .csid_tpg_dt_n_cfg_0_addr = 0x610, - .csid_tpg_dt_n_cfg_1_addr = 0x614, - .csid_tpg_dt_n_cfg_2_addr = 0x618, - .csid_tpg_color_bars_cfg_addr = 0x640, - .csid_tpg_color_box_cfg_addr = 0x644, - .csid_tpg_common_gen_cfg_addr = 0x648, - .csid_tpg_cgen_n_cfg_addr = 0x650, - .csid_tpg_cgen_n_x0_addr = 0x654, - .csid_tpg_cgen_n_x1_addr = 0x658, - .csid_tpg_cgen_n_x2_addr = 0x65c, - .csid_tpg_cgen_n_xy_addr = 0x660, - .csid_tpg_cgen_n_y1_addr = 0x664, - .csid_tpg_cgen_n_y2_addr = 0x668, + .ctrl_addr = 0x600, + .vc_cfg0_addr = 0x604, + .vc_cfg1_addr = 0x608, + .lfsr_seed_addr = 0x60c, + .dt_n_cfg_0_addr = 0x610, + .dt_n_cfg_1_addr = 0x614, + .dt_n_cfg_2_addr = 0x618, + .color_bars_cfg_addr = 0x640, + .color_box_cfg_addr = 0x644, + .common_gen_cfg_addr = 0x648, + .cgen_n_cfg_addr = 0x650, + .cgen_n_x0_addr = 0x654, + .cgen_n_x1_addr = 0x658, + .cgen_n_x2_addr = 0x65c, + .cgen_n_xy_addr = 0x660, + .cgen_n_y1_addr = 0x664, + .cgen_n_y2_addr = 0x668, /* configurations */ - .tpg_dtn_cfg_offset = 0xc, - .tpg_cgen_cfg_offset = 0x20, - .tpg_cpas_ife_reg_offset = 0x28, + .dtn_cfg_offset = 0xc, + .cgen_cfg_offset = 0x20, + .cpas_ife_reg_offset = 0x28, + .hbi = 0x740, + .vbi = 0x3FF, + .ctrl_cfg = 0x408007, + .lfsr_seed = 0x12345678, + .color_bar = 1, + .num_frames = 0, + .line_interleave_mode = 0x1, + .payload_mode = 0x8, + .num_active_lanes_mask = 0x30, + .num_active_dt = 0, + .fmt_shift = 16, + .num_frame_shift = 16, + .width_shift = 16, + .vbi_shift = 12, + .line_interleave_shift = 10, + .num_active_dt_shift = 8, + .color_bar_shift = 5, + .height_shift = 0, + .hbi_shift = 0, }; -static struct cam_ife_csid_common_reg_offset - cam_ife_csid_480_cmn_reg_offset = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, +static struct cam_ife_csid_ver1_common_reg_info + cam_ife_csid_480_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 1, - .minor_version = 7, - .version_incr = 0, - .num_rdis = 3, - .num_pix = 1, - .num_ppp = 1, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .packing_fmt_shift_val = 30, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .drop_v_en_shift_val = 4, - .drop_h_en_shift_val = 3, - .crop_shift = 16, - .ipp_irq_mask_all = 0x7FFF, - .rdi_irq_mask_all = 0x7FFF, - .ppp_irq_mask_all = 0xFFFF, - .measure_en_hbi_vbi_cnt_mask = 0xC, - .format_measure_en_val = 1, - .format_measure_height_mask_val = 0xFFFF, - .format_measure_height_shift_val = 0x10, - .format_measure_width_mask_val = 0xFFFF, - .format_measure_width_shift_val = 0x0, + .major_version = 1, + .minor_version = 7, + .version_incr = 0, + .num_rdis = 3, + .num_pix = 1, + .num_ppp = 1, + .drop_supported = 1, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .multi_vcdt_vc1_shift_val = 2, + .multi_vcdt_dt1_shift_val = 7, + .timestamp_strobe_val = 0x2, + .timestamp_stb_sel_shift_val = 0, + .multi_vcdt_en_shift_val = 0, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .ipp_irq_mask_all = 0x7FFF, + .rdi_irq_mask_all = 0x7FFF, + .ppp_irq_mask_all = 0xFFFF, + .measure_en_hbi_vbi_cnt_mask = 0xC, }; -static struct cam_ife_csid_reg_offset cam_ife_csid_480_reg_offset = { - .cmn_reg = &cam_ife_csid_480_cmn_reg_offset, - .csi2_reg = &cam_ife_csid_480_csi2_reg_offset, - .ipp_reg = &cam_ife_csid_480_ipp_reg_offset, - .ppp_reg = &cam_ife_csid_480_ppp_reg_offset, +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_480_reg_info = { + .cmn_reg = &cam_ife_csid_480_cmn_reg_info, + .csi2_reg = &cam_ife_csid_480_csi2_reg_info, + .ipp_reg = &cam_ife_csid_480_ipp_reg_info, + .ppp_reg = &cam_ife_csid_480_ppp_reg_info, .rdi_reg = { - &cam_ife_csid_480_rdi_0_reg_offset, - &cam_ife_csid_480_rdi_1_reg_offset, - &cam_ife_csid_480_rdi_2_reg_offset, + &cam_ife_csid_480_rdi_0_reg_info, + &cam_ife_csid_480_rdi_1_reg_info, + &cam_ife_csid_480_rdi_2_reg_info, NULL, }, - .tpg_reg = &cam_ife_csid_480_tpg_reg_offset, + .tpg_reg = &cam_ife_csid_480_tpg_reg_info, + .csid_cust_node_map = {0x2, 0x4}, }; - #endif /*_CAM_IFE_CSID_480_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid580.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid580.h new file mode 100644 index 0000000000..dcf11c985f --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid580.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_IFE_CSID_580_H_ +#define _CAM_IFE_CSID_580_H_ + +#include +#include "camera_main.h" +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" + + +/* Settings for 580 CSID are leveraged from 480 */ +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_580_reg_info = { + .cmn_reg = &cam_ife_csid_480_cmn_reg_info, + .csi2_reg = &cam_ife_csid_480_csi2_reg_info, + .ipp_reg = &cam_ife_csid_480_ipp_reg_info, + .ppp_reg = &cam_ife_csid_480_ppp_reg_info, + .rdi_reg = { + &cam_ife_csid_480_rdi_0_reg_info, + &cam_ife_csid_480_rdi_1_reg_info, + &cam_ife_csid_480_rdi_2_reg_info, + NULL, + }, + .tpg_reg = &cam_ife_csid_480_tpg_reg_info, + .csid_cust_node_map = {0x2, 0x4}, + .width_fuse_max_val = 3, + .fused_max_width = {5612, 6048, 7308, UINT_MAX}, +}; +#endif /*_CAM_IFE_CSID_580_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid680.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid680.h new file mode 100644 index 0000000000..1b8a2d7f15 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid680.h @@ -0,0 +1,978 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_IFE_CSID_680_H_ +#define _CAM_IFE_CSID_680_H_ + +#include +#include "cam_ife_csid_dev.h" +#include "camera_main.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver2.h" +#include "cam_irq_controller.h" + +#define CAM_CSID_VERSION_V680 0x60080000 + +static struct cam_irq_register_set cam_ife_csid_680_irq_reg_set[9] = { + /* Top */ + { + .mask_reg_offset = 0x00000080, + .clear_reg_offset = 0x00000084, + .status_reg_offset = 0x0000007C, + }, + /* RX */ + { + .mask_reg_offset = 0x000000A0, + .clear_reg_offset = 0x000000A4, + .status_reg_offset = 0x0000009C, + }, + /* RDI0 */ + { + .mask_reg_offset = 0x000000F0, + .clear_reg_offset = 0x000000F4, + .status_reg_offset = 0x000000EC, + }, + /* RDI1 */ + { + .mask_reg_offset = 0x00000100, + .clear_reg_offset = 0x00000104, + .status_reg_offset = 0x000000FC, + }, + /* RDI2 */ + { + .mask_reg_offset = 0x00000110, + .clear_reg_offset = 0x00000114, + .status_reg_offset = 0x0000010C, + }, + /* RDI3 */ + { + .mask_reg_offset = 0x00000120, + .clear_reg_offset = 0x00000124, + .status_reg_offset = 0x0000011C, + }, + /* RDI4 */ + { + .mask_reg_offset = 0x00000130, + .clear_reg_offset = 0x00000134, + .status_reg_offset = 0x0000012C, + }, + /* IPP */ + { + .mask_reg_offset = 0x000000B0, + .clear_reg_offset = 0x000000B4, + .status_reg_offset = 0x000000AC, + }, + /* PPP */ + { + .mask_reg_offset = 0x000000D0, + .clear_reg_offset = 0x000000D4, + .status_reg_offset = 0x000000CC, + }, +}; + +static struct cam_irq_controller_reg_info cam_ife_csid_680_irq_reg_info = { + .num_registers = 9, + .irq_reg_set = cam_ife_csid_680_irq_reg_set, + .global_clear_offset = 0x00000014, + .global_clear_bitmask = 0x00000001, +}; + +static struct cam_irq_register_set cam_ife_csid_680_buf_done_irq_reg_set[9] = { + { + .mask_reg_offset = 0x00000090, + .clear_reg_offset = 0x00000094, + .status_reg_offset = 0x0000008C, + }, +}; + +static struct cam_irq_controller_reg_info + cam_ife_csid_680_buf_done_irq_reg_info = { + .num_registers = 1, + .irq_reg_set = cam_ife_csid_680_buf_done_irq_reg_set, + .global_clear_offset = 0x00000014, + .global_clear_bitmask = 0x00000001, +}; + +static struct cam_ife_csid_ver2_pxl_reg_info + cam_ife_csid_680_ipp_reg_info = { + .irq_status_addr = 0xAC, + .irq_mask_addr = 0xB0, + .irq_clear_addr = 0xB4, + .irq_set_addr = 0xB8, + .cfg0_addr = 0x300, + .ctrl_addr = 0x304, + .debug_clr_cmd_addr = 0x308, + .multi_vcdt_cfg0_addr = 0x30c, + .cfg1_addr = 0x310, + .err_recovery_cfg0_addr = 0x318, + .err_recovery_cfg1_addr = 0x31C, + .err_recovery_cfg2_addr = 0x320, + .bin_pd_detect_cfg0_addr = 0x324, + .bin_pd_detect_cfg1_addr = 0x328, + .bin_pd_detect_cfg2_addr = 0x32C, + .camif_frame_cfg_addr = 0x330, + .epoch_irq_cfg_addr = 0x334, + .epoch0_subsample_ptrn_addr = 0x338, + .epoch1_subsample_ptrn_addr = 0x33C, + .debug_camif_1_addr = 0x340, + .debug_camif_0_addr = 0x344, + .debug_halt_status_addr = 0x348, + .debug_misr_val0_addr = 0x34C, + .debug_misr_val1_addr = 0x350, + .debug_misr_val2_addr = 0x354, + .debug_misr_val3_addr = 0x358, + .hcrop_addr = 0x35c, + .vcrop_addr = 0x360, + .pix_drop_pattern_addr = 0x364, + .pix_drop_period_addr = 0x368, + .line_drop_pattern_addr = 0x36C, + .line_drop_period_addr = 0x370, + .frm_drop_pattern_addr = 0x374, + .frm_drop_period_addr = 0x378, + .irq_subsample_pattern_addr = 0x37C, + .irq_subsample_period_addr = 0x380, + .format_measure_cfg0_addr = 0x384, + .format_measure_cfg1_addr = 0x388, + .format_measure0_addr = 0x38C, + .format_measure1_addr = 0x390, + .format_measure2_addr = 0x394, + .timestamp_curr0_sof_addr = 0x398, + .timestamp_curr1_sof_addr = 0x39C, + .timestamp_perv0_sof_addr = 0x3A0, + .timestamp_perv1_sof_addr = 0x3A4, + .timestamp_curr0_eof_addr = 0x3A8, + .timestamp_curr1_eof_addr = 0x3AC, + .timestamp_perv0_eof_addr = 0x3B0, + .timestamp_perv1_eof_addr = 0x3B4, + .lut_bank_cfg_addr = 0x3B8, + .batch_id_cfg0_addr = 0x3BC, + .batch_id_cfg1_addr = 0x3C0, + .batch_period_cfg_addr = 0x3C4, + .batch_stream_id_cfg_addr = 0x3C8, + .epoch0_cfg_batch_id0_addr = 0x3CC, + .epoch1_cfg_batch_id0_addr = 0x3D0, + .epoch0_cfg_batch_id1_addr = 0x3D4, + .epoch1_cfg_batch_id1_addr = 0x3D8, + .epoch0_cfg_batch_id2_addr = 0x3DC, + .epoch1_cfg_batch_id2_addr = 0x3E0, + .epoch0_cfg_batch_id3_addr = 0x3E4, + .epoch1_cfg_batch_id3_addr = 0x3E8, + .epoch0_cfg_batch_id4_addr = 0x3EC, + .epoch1_cfg_batch_id4_addr = 0x3F0, + .epoch0_cfg_batch_id5_addr = 0x3F4, + .epoch1_cfg_batch_id5_addr = 0x3F8, + /* configurations */ + .resume_frame_boundary = 1, + .binning_supported = 0x7, + .start_mode_internal = 0x0, + .start_mode_global = 0x1, + .start_mode_master = 0x2, + .start_mode_slave = 0x3, + .start_mode_shift = 2, + .start_master_sel_val = 0, + .start_master_sel_shift = 4, + .crop_v_en_shift_val = 13, + .crop_h_en_shift_val = 12, + .drop_v_en_shift_val = 11, + .drop_h_en_shift_val = 10, + .pix_store_en_shift_val = 14, + .early_eof_en_shift_val = 16, + .bin_h_en_shift_val = 20, + .bin_v_en_shift_val = 21, + .bin_en_shift_val = 18, + .bin_qcfa_en_shift_val = 19, + .format_measure_en_shift_val = 8, + .timestamp_en_shift_val = 9, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .min_hbi_shift_val = 4, + .start_master_sel_shift_val = 4, + .bin_pd_en_shift_val = 0, + .bin_pd_blk_w_shift_val = 8, + .bin_pd_blk_h_shift_val = 24, + .bin_pd_detect_x_offset_shift_val = 0, + .bin_pd_detect_x_end_shift_val = 16, + .bin_pd_detect_y_offset_shift_val = 0, + .bin_pd_detect_y_end_shift_val = 16, + .pix_pattern_shift_val = 24, + .stripe_loc_shift_val = 20, + .lut_bank_0_sel_val = 0, + .lut_bank_1_sel_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, + .camif_irq_mask = 0x800000, + .rup_aup_mask = 0x10001, +}; + +static struct cam_ife_csid_ver2_pxl_reg_info + cam_ife_csid_680_ppp_reg_info = { + .irq_status_addr = 0xCC, + .irq_mask_addr = 0xD0, + .irq_clear_addr = 0xD4, + .irq_set_addr = 0xD8, + .cfg0_addr = 0xB00, + .ctrl_addr = 0xB04, + .debug_clr_cmd_addr = 0xB08, + .multi_vcdt_cfg0_addr = 0xB0c, + .cfg1_addr = 0xB10, + .sparse_pd_extractor_cfg_addr = 0xB14, + .err_recovery_cfg0_addr = 0xB18, + .err_recovery_cfg1_addr = 0xB1C, + .err_recovery_cfg2_addr = 0xB20, + .camif_frame_cfg_addr = 0xB30, + .epoch_irq_cfg_addr = 0xB34, + .epoch0_subsample_ptrn_addr = 0xB38, + .epoch1_subsample_ptrn_addr = 0xB3C, + .debug_camif_1_addr = 0xB40, + .debug_camif_0_addr = 0xB44, + .debug_halt_status_addr = 0xB48, + .debug_misr_val0_addr = 0xB4C, + .debug_misr_val1_addr = 0xB50, + .debug_misr_val2_addr = 0xB54, + .debug_misr_val3_addr = 0xB58, + .hcrop_addr = 0xB5c, + .vcrop_addr = 0xB60, + .pix_drop_pattern_addr = 0xB64, + .pix_drop_period_addr = 0xB68, + .line_drop_pattern_addr = 0xB6C, + .line_drop_period_addr = 0xB70, + .frm_drop_pattern_addr = 0xB74, + .frm_drop_period_addr = 0xB78, + .irq_subsample_pattern_addr = 0xB7C, + .irq_subsample_period_addr = 0xB80, + .format_measure_cfg0_addr = 0xB84, + .format_measure_cfg1_addr = 0xB88, + .format_measure0_addr = 0xB8C, + .format_measure1_addr = 0xB90, + .format_measure2_addr = 0xB94, + .timestamp_curr0_sof_addr = 0xB98, + .timestamp_curr1_sof_addr = 0xB9C, + .timestamp_perv0_sof_addr = 0xBA0, + .timestamp_perv1_sof_addr = 0xBA4, + .timestamp_curr0_eof_addr = 0xBA8, + .timestamp_curr1_eof_addr = 0xBAC, + .timestamp_perv0_eof_addr = 0xBB0, + .timestamp_perv1_eof_addr = 0xBB4, + .lut_bank_cfg_addr = 0xBB8, + .batch_id_cfg0_addr = 0xBBC, + .batch_id_cfg1_addr = 0xBC0, + .batch_period_cfg_addr = 0xBC4, + .batch_stream_id_cfg_addr = 0xBC8, + .epoch0_cfg_batch_id0_addr = 0xBCC, + .epoch1_cfg_batch_id0_addr = 0xBD0, + .epoch0_cfg_batch_id1_addr = 0xBD4, + .epoch1_cfg_batch_id1_addr = 0xBD8, + .epoch0_cfg_batch_id2_addr = 0xBDC, + .epoch1_cfg_batch_id2_addr = 0xBE0, + .epoch0_cfg_batch_id3_addr = 0xBE4, + .epoch1_cfg_batch_id3_addr = 0xBE8, + .epoch0_cfg_batch_id4_addr = 0xBEC, + .epoch1_cfg_batch_id4_addr = 0xBF0, + .epoch0_cfg_batch_id5_addr = 0xBF4, + .epoch1_cfg_batch_id5_addr = 0xBF8, + /* configurations */ + .resume_frame_boundary = 1, + .start_mode_shift = 2, + .start_mode_internal = 0x0, + .start_mode_global = 0x1, + .start_mode_master = 0x2, + .start_mode_slave = 0x3, + .start_master_sel_val = 3, + .start_master_sel_shift = 4, + .binning_supported = 0x1, + .bin_h_en_shift_val = 18, + .bin_en_shift_val = 18, + .early_eof_en_shift_val = 16, + .pix_store_en_shift_val = 14, + .crop_v_en_shift_val = 13, + .crop_h_en_shift_val = 12, + .drop_v_en_shift_val = 11, + .drop_h_en_shift_val = 10, + .format_measure_en_shift_val = 8, + .timestamp_en_shift_val = 9, + .min_hbi_shift_val = 4, + .start_master_sel_shift_val = 4, + .lut_bank_0_sel_val = 0, + .lut_bank_1_sel_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, + .rup_aup_mask = 0x40004, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_680_rdi_0_reg_info = { + .irq_status_addr = 0xEC, + .irq_mask_addr = 0xF0, + .irq_clear_addr = 0xF4, + .irq_set_addr = 0xF8, + .cfg0_addr = 0x500, + .ctrl_addr = 0x504, + .debug_clr_cmd_addr = 0x508, + .multi_vcdt_cfg0_addr = 0x50c, + .cfg1_addr = 0x510, + .err_recovery_cfg0_addr = 0x514, + .err_recovery_cfg1_addr = 0x518, + .err_recovery_cfg2_addr = 0x51C, + .debug_byte_cntr_ping_addr = 0x520, + .debug_byte_cntr_pong_addr = 0x524, + .camif_frame_cfg_addr = 0x528, + .epoch_irq_cfg_addr = 0x52C, + .epoch0_subsample_ptrn_addr = 0x530, + .epoch1_subsample_ptrn_addr = 0x534, + .debug_camif_1_addr = 0x538, + .debug_camif_0_addr = 0x53C, + .frm_drop_pattern_addr = 0x540, + .frm_drop_period_addr = 0x540, + .irq_subsample_pattern_addr = 0x548, + .irq_subsample_period_addr = 0x54C, + .hcrop_addr = 0x550, + .vcrop_addr = 0x554, + .pix_drop_pattern_addr = 0x558, + .pix_drop_period_addr = 0x55C, + .line_drop_pattern_addr = 0x560, + .line_drop_period_addr = 0x564, + .debug_halt_status_addr = 0x568, + .debug_misr_val0_addr = 0x570, + .debug_misr_val1_addr = 0x574, + .debug_misr_val2_addr = 0x578, + .debug_misr_val3_addr = 0x57C, + .format_measure_cfg0_addr = 0x580, + .format_measure_cfg1_addr = 0x584, + .format_measure0_addr = 0x588, + .format_measure1_addr = 0x58C, + .format_measure2_addr = 0x590, + .timestamp_curr0_sof_addr = 0x594, + .timestamp_curr1_sof_addr = 0x598, + .timestamp_perv0_sof_addr = 0x59C, + .timestamp_perv1_sof_addr = 0x5A0, + .timestamp_curr0_eof_addr = 0x5A4, + .timestamp_curr1_eof_addr = 0x5A8, + .timestamp_perv0_eof_addr = 0x5AC, + .timestamp_perv1_eof_addr = 0x5B0, + .batch_id_cfg0_addr = 0x5B4, + .batch_id_cfg1_addr = 0x5B8, + .batch_period_cfg_addr = 0x5BC, + .batch_stream_id_cfg_addr = 0x5C0, + .epoch0_cfg_batch_id0_addr = 0x5C4, + .epoch1_cfg_batch_id0_addr = 0x5C8, + .epoch0_cfg_batch_id1_addr = 0x5CC, + .epoch1_cfg_batch_id1_addr = 0x5D0, + .epoch0_cfg_batch_id2_addr = 0x5D4, + .epoch1_cfg_batch_id2_addr = 0x5D8, + .epoch0_cfg_batch_id3_addr = 0x5DC, + .epoch1_cfg_batch_id3_addr = 0x5E0, + .epoch0_cfg_batch_id4_addr = 0x5E4, + .epoch1_cfg_batch_id4_addr = 0x5E8, + .epoch0_cfg_batch_id5_addr = 0x5EC, + .epoch1_cfg_batch_id5_addr = 0x5F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .offline_mode_supported = 1, + .mipi_pack_supported = 1, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .offline_mode_en_shift_val = 2, + .pix_pattern_shift_val = 24, + .stripe_loc_shift_val = 20, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, + .camif_irq_mask = 0x800000, + .rup_aup_mask = 0x100010, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_680_rdi_1_reg_info = { + .irq_status_addr = 0xFC, + .irq_mask_addr = 0x100, + .irq_clear_addr = 0x104, + .irq_set_addr = 0x108, + .cfg0_addr = 0x600, + .ctrl_addr = 0x604, + .debug_clr_cmd_addr = 0x608, + .multi_vcdt_cfg0_addr = 0x60c, + .cfg1_addr = 0x610, + .err_recovery_cfg0_addr = 0x614, + .err_recovery_cfg1_addr = 0x618, + .err_recovery_cfg2_addr = 0x61C, + .debug_byte_cntr_ping_addr = 0x620, + .debug_byte_cntr_pong_addr = 0x624, + .camif_frame_cfg_addr = 0x628, + .epoch_irq_cfg_addr = 0x62C, + .epoch0_subsample_ptrn_addr = 0x630, + .epoch1_subsample_ptrn_addr = 0x634, + .debug_camif_1_addr = 0x638, + .debug_camif_0_addr = 0x63C, + .frm_drop_pattern_addr = 0x640, + .frm_drop_period_addr = 0x644, + .irq_subsample_pattern_addr = 0x648, + .irq_subsample_period_addr = 0x64C, + .hcrop_addr = 0x650, + .vcrop_addr = 0x654, + .pix_drop_pattern_addr = 0x658, + .pix_drop_period_addr = 0x65C, + .line_drop_pattern_addr = 0x660, + .line_drop_period_addr = 0x664, + .debug_halt_status_addr = 0x66C, + .debug_misr_val0_addr = 0x670, + .debug_misr_val1_addr = 0x674, + .debug_misr_val2_addr = 0x678, + .debug_misr_val3_addr = 0x67C, + .format_measure_cfg0_addr = 0x680, + .format_measure_cfg1_addr = 0x684, + .format_measure0_addr = 0x688, + .format_measure1_addr = 0x68C, + .format_measure2_addr = 0x690, + .timestamp_curr0_sof_addr = 0x694, + .timestamp_curr1_sof_addr = 0x698, + .timestamp_perv0_sof_addr = 0x69C, + .timestamp_perv1_sof_addr = 0x6A0, + .timestamp_curr0_eof_addr = 0x6A4, + .timestamp_curr1_eof_addr = 0x6A8, + .timestamp_perv0_eof_addr = 0x6AC, + .timestamp_perv1_eof_addr = 0x6B0, + .batch_id_cfg0_addr = 0x6B4, + .batch_id_cfg1_addr = 0x6B8, + .batch_period_cfg_addr = 0x6BC, + .batch_stream_id_cfg_addr = 0x6C0, + .epoch0_cfg_batch_id0_addr = 0x6C4, + .epoch1_cfg_batch_id0_addr = 0x6C8, + .epoch0_cfg_batch_id1_addr = 0x6CC, + .epoch1_cfg_batch_id1_addr = 0x6D0, + .epoch0_cfg_batch_id2_addr = 0x6D4, + .epoch1_cfg_batch_id2_addr = 0x6D8, + .epoch0_cfg_batch_id3_addr = 0x6DC, + .epoch1_cfg_batch_id3_addr = 0x6E0, + .epoch0_cfg_batch_id4_addr = 0x6E4, + .epoch1_cfg_batch_id4_addr = 0x6E8, + .epoch0_cfg_batch_id5_addr = 0x6EC, + .epoch1_cfg_batch_id5_addr = 0x6F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .offline_mode_supported = 1, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .offline_mode_en_shift_val = 2, + .pix_pattern_shift_val = 24, + .stripe_loc_shift_val = 20, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, + .camif_irq_mask = 0x800000, + .rup_aup_mask = 0x200020, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_680_rdi_2_reg_info = { + .irq_status_addr = 0x10C, + .irq_mask_addr = 0x110, + .irq_clear_addr = 0x114, + .irq_set_addr = 0x118, + .cfg0_addr = 0x700, + .ctrl_addr = 0x704, + .debug_clr_cmd_addr = 0x708, + .multi_vcdt_cfg0_addr = 0x70c, + .cfg1_addr = 0x710, + .err_recovery_cfg0_addr = 0x714, + .err_recovery_cfg1_addr = 0x718, + .err_recovery_cfg2_addr = 0x71C, + .debug_byte_cntr_ping_addr = 0x720, + .debug_byte_cntr_pong_addr = 0x724, + .camif_frame_cfg_addr = 0x728, + .epoch_irq_cfg_addr = 0x72C, + .epoch0_subsample_ptrn_addr = 0x730, + .epoch1_subsample_ptrn_addr = 0x734, + .debug_camif_1_addr = 0x738, + .debug_camif_0_addr = 0x73C, + .frm_drop_pattern_addr = 0x740, + .frm_drop_period_addr = 0x744, + .irq_subsample_pattern_addr = 0x748, + .irq_subsample_period_addr = 0x74C, + .hcrop_addr = 0x750, + .vcrop_addr = 0x754, + .pix_drop_pattern_addr = 0x758, + .pix_drop_period_addr = 0x75C, + .line_drop_pattern_addr = 0x760, + .line_drop_period_addr = 0x764, + .debug_halt_status_addr = 0x76C, + .debug_misr_val0_addr = 0x770, + .debug_misr_val1_addr = 0x774, + .debug_misr_val2_addr = 0x778, + .debug_misr_val3_addr = 0x77C, + .format_measure_cfg0_addr = 0x780, + .format_measure_cfg1_addr = 0x784, + .format_measure0_addr = 0x788, + .format_measure1_addr = 0x78C, + .format_measure2_addr = 0x790, + .timestamp_curr0_sof_addr = 0x794, + .timestamp_curr1_sof_addr = 0x798, + .timestamp_perv0_sof_addr = 0x79C, + .timestamp_perv1_sof_addr = 0x7A0, + .timestamp_curr0_eof_addr = 0x7A4, + .timestamp_curr1_eof_addr = 0x7A8, + .timestamp_perv0_eof_addr = 0x7AC, + .timestamp_perv1_eof_addr = 0x7B0, + .batch_id_cfg0_addr = 0x7B4, + .batch_id_cfg1_addr = 0x7B8, + .batch_period_cfg_addr = 0x7BC, + .batch_stream_id_cfg_addr = 0x7C0, + .epoch0_cfg_batch_id0_addr = 0x7C4, + .epoch1_cfg_batch_id0_addr = 0x7C8, + .epoch0_cfg_batch_id1_addr = 0x7CC, + .epoch1_cfg_batch_id1_addr = 0x7D0, + .epoch0_cfg_batch_id2_addr = 0x7D4, + .epoch1_cfg_batch_id2_addr = 0x7D8, + .epoch0_cfg_batch_id3_addr = 0x7DC, + .epoch1_cfg_batch_id3_addr = 0x7E0, + .epoch0_cfg_batch_id4_addr = 0x7E4, + .epoch1_cfg_batch_id4_addr = 0x7E8, + .epoch0_cfg_batch_id5_addr = 0x7EC, + .epoch1_cfg_batch_id5_addr = 0x7F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .offline_mode_supported = 1, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .offline_mode_en_shift_val = 2, + .pix_pattern_shift_val = 24, + .stripe_loc_shift_val = 20, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, + .camif_irq_mask = 0x800000, + .rup_aup_mask = 0x400040, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_680_rdi_3_reg_info = { + .irq_status_addr = 0x11C, + .irq_mask_addr = 0x120, + .irq_clear_addr = 0x124, + .irq_set_addr = 0x128, + .cfg0_addr = 0x800, + .ctrl_addr = 0x804, + .debug_clr_cmd_addr = 0x808, + .multi_vcdt_cfg0_addr = 0x80c, + .cfg1_addr = 0x810, + .err_recovery_cfg0_addr = 0x814, + .err_recovery_cfg1_addr = 0x818, + .err_recovery_cfg2_addr = 0x81C, + .debug_byte_cntr_ping_addr = 0x820, + .debug_byte_cntr_pong_addr = 0x824, + .camif_frame_cfg_addr = 0x828, + .epoch_irq_cfg_addr = 0x82C, + .epoch0_subsample_ptrn_addr = 0x830, + .epoch1_subsample_ptrn_addr = 0x834, + .debug_camif_1_addr = 0x838, + .debug_camif_0_addr = 0x83C, + .frm_drop_pattern_addr = 0x840, + .frm_drop_period_addr = 0x840, + .irq_subsample_pattern_addr = 0x848, + .irq_subsample_period_addr = 0x84C, + .hcrop_addr = 0x850, + .vcrop_addr = 0x854, + .pix_drop_pattern_addr = 0x858, + .pix_drop_period_addr = 0x85C, + .line_drop_pattern_addr = 0x860, + .line_drop_period_addr = 0x864, + .debug_halt_status_addr = 0x868, + .debug_misr_val0_addr = 0x870, + .debug_misr_val1_addr = 0x874, + .debug_misr_val2_addr = 0x878, + .debug_misr_val3_addr = 0x87C, + .format_measure_cfg0_addr = 0x880, + .format_measure_cfg1_addr = 0x884, + .format_measure0_addr = 0x888, + .format_measure1_addr = 0x88C, + .format_measure2_addr = 0x890, + .timestamp_curr0_sof_addr = 0x894, + .timestamp_curr1_sof_addr = 0x898, + .timestamp_perv0_sof_addr = 0x89C, + .timestamp_perv1_sof_addr = 0x8A0, + .timestamp_curr0_eof_addr = 0x8A4, + .timestamp_curr1_eof_addr = 0x8A8, + .timestamp_perv0_eof_addr = 0x8AC, + .timestamp_perv1_eof_addr = 0x8B0, + .batch_id_cfg0_addr = 0x8B4, + .batch_id_cfg1_addr = 0x8B8, + .batch_period_cfg_addr = 0x8BC, + .batch_stream_id_cfg_addr = 0x8C0, + .epoch0_cfg_batch_id0_addr = 0x8C4, + .epoch1_cfg_batch_id0_addr = 0x8C8, + .epoch0_cfg_batch_id1_addr = 0x8CC, + .epoch1_cfg_batch_id1_addr = 0x8D0, + .epoch0_cfg_batch_id2_addr = 0x8D4, + .epoch1_cfg_batch_id2_addr = 0x8D8, + .epoch0_cfg_batch_id3_addr = 0x8DC, + .epoch1_cfg_batch_id3_addr = 0x8E0, + .epoch0_cfg_batch_id4_addr = 0x8E4, + .epoch1_cfg_batch_id4_addr = 0x8E8, + .epoch0_cfg_batch_id5_addr = 0x8EC, + .epoch1_cfg_batch_id5_addr = 0x8F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .offline_mode_supported = 1, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .offline_mode_en_shift_val = 2, + .pix_pattern_shift_val = 24, + .stripe_loc_shift_val = 20, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, + .camif_irq_mask = 0x800000, + .rup_aup_mask = 0x800080, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_680_rdi_4_reg_info = { + .irq_status_addr = 0x12C, + .irq_mask_addr = 0x130, + .irq_clear_addr = 0x134, + .irq_set_addr = 0x138, + .cfg0_addr = 0x900, + .ctrl_addr = 0x904, + .debug_clr_cmd_addr = 0x908, + .multi_vcdt_cfg0_addr = 0x90c, + .cfg1_addr = 0x910, + .err_recovery_cfg0_addr = 0x914, + .err_recovery_cfg1_addr = 0x918, + .err_recovery_cfg2_addr = 0x91C, + .debug_byte_cntr_ping_addr = 0x920, + .debug_byte_cntr_pong_addr = 0x924, + .camif_frame_cfg_addr = 0x928, + .epoch_irq_cfg_addr = 0x92C, + .epoch0_subsample_ptrn_addr = 0x930, + .epoch1_subsample_ptrn_addr = 0x934, + .debug_camif_1_addr = 0x938, + .debug_camif_0_addr = 0x93C, + .frm_drop_pattern_addr = 0x940, + .frm_drop_period_addr = 0x940, + .irq_subsample_pattern_addr = 0x948, + .irq_subsample_period_addr = 0x94C, + .hcrop_addr = 0x950, + .vcrop_addr = 0x954, + .pix_drop_pattern_addr = 0x958, + .pix_drop_period_addr = 0x95C, + .line_drop_pattern_addr = 0x960, + .line_drop_period_addr = 0x964, + .debug_halt_status_addr = 0x968, + .debug_misr_val0_addr = 0x970, + .debug_misr_val1_addr = 0x974, + .debug_misr_val2_addr = 0x978, + .debug_misr_val3_addr = 0x97C, + .format_measure_cfg0_addr = 0x980, + .format_measure_cfg1_addr = 0x984, + .format_measure0_addr = 0x988, + .format_measure1_addr = 0x98C, + .format_measure2_addr = 0x990, + .timestamp_curr0_sof_addr = 0x994, + .timestamp_curr1_sof_addr = 0x998, + .timestamp_perv0_sof_addr = 0x99C, + .timestamp_perv1_sof_addr = 0x9A0, + .timestamp_curr0_eof_addr = 0x9A4, + .timestamp_curr1_eof_addr = 0x9A8, + .timestamp_perv0_eof_addr = 0x9AC, + .timestamp_perv1_eof_addr = 0x9B0, + .batch_id_cfg0_addr = 0x9B4, + .batch_id_cfg1_addr = 0x9B8, + .batch_period_cfg_addr = 0x9BC, + .batch_stream_id_cfg_addr = 0x9C0, + .epoch0_cfg_batch_id0_addr = 0x9C4, + .epoch1_cfg_batch_id0_addr = 0x9C8, + .epoch0_cfg_batch_id1_addr = 0x9CC, + .epoch1_cfg_batch_id1_addr = 0x9D0, + .epoch0_cfg_batch_id2_addr = 0x9D4, + .epoch1_cfg_batch_id2_addr = 0x9D8, + .epoch0_cfg_batch_id3_addr = 0x9DC, + .epoch1_cfg_batch_id3_addr = 0x9E0, + .epoch0_cfg_batch_id4_addr = 0x9E4, + .epoch1_cfg_batch_id4_addr = 0x9E8, + .epoch0_cfg_batch_id5_addr = 0x9EC, + .epoch1_cfg_batch_id5_addr = 0x9F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .offline_mode_supported = 1, + .packing_fmt_shift_val = 15, + .early_eof_en_shift_val = 14, + .plain_fmt_shift_val = 12, + .plain_alignment_shift_val = 11, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .timestamp_en_shift_val = 4, + .format_measure_en_shift_val = 3, + .debug_byte_cntr_rst_shift_val = 2, + .offline_mode_en_shift_val = 2, + .pix_pattern_shift_val = 24, + .stripe_loc_shift_val = 20, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, + .camif_irq_mask = 0x800000, + .rup_aup_mask = 0x1000100, +}; + +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_680_csi2_reg_info = { + .irq_status_addr = 0x9C, + .irq_mask_addr = 0xA0, + .irq_clear_addr = 0xA4, + .irq_set_addr = 0xA8, + /*CSI2 rx control */ + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .capture_ctrl_addr = 0x208, + .rst_strobes_addr = 0x20C, + .cap_unmap_long_pkt_hdr_0_addr = 0x210, + .cap_unmap_long_pkt_hdr_1_addr = 0x214, + .captured_short_pkt_0_addr = 0x218, + .captured_short_pkt_1_addr = 0x21c, + .captured_long_pkt_0_addr = 0x220, + .captured_long_pkt_1_addr = 0x224, + .captured_long_pkt_ftr_addr = 0x228, + .captured_cphy_pkt_hdr_addr = 0x22c, + .lane0_misr_addr = 0x230, + .lane1_misr_addr = 0x234, + .lane2_misr_addr = 0x238, + .lane3_misr_addr = 0x23c, + .total_pkts_rcvd_addr = 0x240, + .stats_ecc_addr = 0x244, + .total_crc_err_addr = 0x248, + .de_scramble_type3_cfg0_addr = 0x24C, + .de_scramble_type3_cfg1_addr = 0x250, + .de_scramble_type2_cfg0_addr = 0x254, + .de_scramble_type2_cfg1_addr = 0x258, + .de_scramble_type1_cfg0_addr = 0x25C, + .de_scramble_type1_cfg1_addr = 0x260, + .de_scramble_type0_cfg0_addr = 0x264, + .de_scramble_type0_cfg1_addr = 0x268, + + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0xf, + .vc_mask = 0x7C00000, + .dt_mask = 0x3f0000, + .wc_mask = 0xffff0000, + .calc_crc_mask = 0xffff, + .expected_crc_mask = 0xffff, + .ecc_correction_shift_en = 0, + .lane_num_shift = 0, + .lane_cfg_shift = 4, + .phy_type_shift = 24, + .phy_num_shift = 20, + .tpg_mux_en_shift = 27, + .tpg_num_sel_shift = 28, + .phy_bist_shift_en = 7, + .epd_mode_shift_en = 8, + .eotp_shift_en = 9, + .dyn_sensor_switch_shift_en = 10, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, +}; + +static struct cam_ife_csid_ver2_common_reg_info + cam_ife_csid_680_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .global_cmd_addr = 0x8, + .reset_cfg_addr = 0xc, + .reset_cmd_addr = 0x10, + .irq_cmd_addr = 0x14, + .rup_aup_cmd_addr = 0x18, + .offline_cmd_addr = 0x1C, + .shdr_master_slave_cfg_addr = 0x20, + .top_irq_status_addr = 0x7C, + .top_irq_mask_addr = 0x80, + .top_irq_clear_addr = 0x84, + .top_irq_set_addr = 0x88, + .buf_done_irq_status_addr = 0x8C, + .buf_done_irq_mask_addr = 0x90, + .buf_done_irq_clear_addr = 0x94, + .buf_done_irq_set_addr = 0x98, + + /*configurations */ + .major_version = 6, + .minor_version = 8, + .version_incr = 0, + .num_rdis = 5, + .num_pix = 1, + .num_ppp = 1, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .frame_id_decode_en_shift_val = 1, + .multi_vcdt_vc1_shift_val = 2, + .multi_vcdt_dt1_shift_val = 7, + .multi_vcdt_en_shift_val = 0, + .timestamp_stb_sel_shift_val = 0, + .vfr_en_shift_val = 0, + .mup_shift_val = 28, + .shdr_slave_rdi2_shift = 22, + .shdr_slave_rdi1_shift = 21, + .shdr_master_rdi0_shift = 5, + .shdr_master_slave_en_shift = 0, + .early_eof_supported = 1, + .vfr_supported = 1, + .multi_vcdt_supported = 1, + .frame_id_dec_supported = 1, + .measure_en_hbi_vbi_cnt_mask = 0xc, + .measure_pixel_line_en_mask = 0x3, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .drop_supported = 1, + .ipp_irq_mask_all = 0x7FFF, + .rdi_irq_mask_all = 0x7FFF, + .ppp_irq_mask_all = 0xFFFF, + .rst_loc_path_only_val = 0x0, + .rst_loc_complete_csid_val = 0x1, + .rst_mode_frame_boundary_val = 0x0, + .rst_mode_immediate_val = 0x1, + .rst_cmd_hw_reset_complete_val = 0x0, + .rst_cmd_sw_reset_complete_val = 0x2, + .rst_cmd_irq_ctrl_only_val = 0x4, + .timestamp_strobe_val = 0x2, + .top_reset_irq_shift_val = 0, + .rst_location_shift_val = 4, + .rst_mode_shift_val = 0, + .epoch_div_factor = 4, + .global_reset = 1, + .rup_supported = 1, +}; + +static struct cam_ife_csid_ver2_top_reg_info + cam_ife_csid_680_top_reg_info = { + .io_path_cfg0_addr = { + 0x0, + 0x4, + 0x8, + }, + .dual_csid_cfg0_addr = { + 0xC, + 0x10, + 0x14, + }, + .input_core_type_shift_val = 0, + .sfe_offline_en_shift_val = 12, + .out_ife_en_shift_val = 8, + .dual_sync_sel_shift_val = 8, + .dual_en_shift_val = 0, + .master_slave_sel_shift_val = 1, + .master_sel_val = 0, + .slave_sel_val = 1, +}; + +static struct cam_ife_csid_ver2_reg_info cam_ife_csid_680_reg_info = { + .irq_reg_info = &cam_ife_csid_680_irq_reg_info, + .buf_done_irq_reg_info = &cam_ife_csid_680_buf_done_irq_reg_info, + .cmn_reg = &cam_ife_csid_680_cmn_reg_info, + .csi2_reg = &cam_ife_csid_680_csi2_reg_info, + .ipp_reg = &cam_ife_csid_680_ipp_reg_info, + .ppp_reg = &cam_ife_csid_680_ppp_reg_info, + .rdi_reg = { + &cam_ife_csid_680_rdi_0_reg_info, + &cam_ife_csid_680_rdi_1_reg_info, + &cam_ife_csid_680_rdi_2_reg_info, + &cam_ife_csid_680_rdi_3_reg_info, + &cam_ife_csid_680_rdi_4_reg_info, + }, + .top_reg = &cam_ife_csid_680_top_reg_info, + .input_core_sel = { + { + 0x0, + 0x1, + 0x2, + 0x3, + 0x8, + -1, + -1, + }, + { + 0x0, + 0x1, + 0x2, + 0x3, + -1, + -1, + -1, + }, + { + 0x0, + 0x1, + 0x2, + 0x3, + -1, + 0x9, + -1, + }, + }, + .need_top_cfg = 0x1, + .csid_cust_node_map = {0x1, 0x0, 0x2}, +}; +#endif /*_CAM_IFE_CSID_680_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c new file mode 100644 index 0000000000..66fb028e3b --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c @@ -0,0 +1,661 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include + +#include +#include + +#include +#include "cam_soc_util.h" +#include "cam_io_util.h" +#include "cam_debug_util.h" +#include "cam_cpas_api.h" +#include "cam_hw.h" +#include "cam_cdm_util.h" +#include "cam_ife_csid_hw_intf.h" +#include "cam_ife_csid_soc.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" +#include "cam_ife_csid_hw_ver2.h" + +const uint8_t *cam_ife_csid_irq_reg_tag[CAM_IFE_CSID_IRQ_REG_MAX] = { + "TOP", + "RX", + "RDI0", + "RDI1", + "RDI2", + "RDI3", + "RDI4", + "IPP", + "PPP", + "UDI0", + "UDI1", + "UDI2", +}; + +static int cam_ife_csid_get_cid(struct cam_ife_csid_cid_data *cid_data, + struct cam_csid_hw_reserve_resource_args *reserve) +{ + uint32_t i; + + if (cid_data->cid_cnt == 0) { + + for (i = 0; i < reserve->in_port->num_valid_vc_dt; i++) { + cid_data->vc_dt[i].vc = reserve->in_port->vc[i]; + cid_data->vc_dt[i].dt = reserve->in_port->dt[i]; + cid_data->vc_dt[i].valid = true; + } + + cid_data->num_vc_dt = reserve->in_port->num_valid_vc_dt; + return 0; + } + + for (i = 0; i < reserve->in_port->num_valid_vc_dt; i++) { + + if (cid_data->vc_dt[i].vc == reserve->in_port->vc[i] && + cid_data->vc_dt[i].dt == reserve->in_port->dt[i]) + return 0; + } + + return -EINVAL; +} + +int cam_ife_csid_is_pix_res_format_supported( + uint32_t in_format) +{ + int rc = -EINVAL; + + switch (in_format) { + case CAM_FORMAT_MIPI_RAW_6: + case CAM_FORMAT_MIPI_RAW_8: + case CAM_FORMAT_MIPI_RAW_10: + case CAM_FORMAT_MIPI_RAW_12: + case CAM_FORMAT_MIPI_RAW_14: + case CAM_FORMAT_MIPI_RAW_16: + case CAM_FORMAT_MIPI_RAW_20: + case CAM_FORMAT_DPCM_10_6_10: + case CAM_FORMAT_DPCM_10_8_10: + case CAM_FORMAT_DPCM_12_6_12: + case CAM_FORMAT_DPCM_12_8_12: + case CAM_FORMAT_DPCM_14_8_14: + case CAM_FORMAT_DPCM_14_10_14: + case CAM_FORMAT_DPCM_12_10_12: + rc = 0; + break; + default: + break; + } + return rc; +} + +int cam_ife_csid_get_format_rdi( + uint32_t in_format, uint32_t out_format, + struct cam_ife_csid_path_format *path_format, bool rpp) +{ + int rc = 0; + + switch (in_format) { + case CAM_FORMAT_MIPI_RAW_6: + switch (out_format) { + case CAM_FORMAT_MIPI_RAW_6: + path_format->decode_fmt = 0xf; + if (rpp) { + path_format->decode_fmt = 0x0; + path_format->packing_fmt = 0x1; + } + break; + case CAM_FORMAT_PLAIN8: + path_format->decode_fmt = 0x0; + path_format->plain_fmt = 0x0; + break; + default: + rc = -EINVAL; + break; + } + path_format->bits_per_pxl = 6; + break; + case CAM_FORMAT_MIPI_RAW_8: + switch (out_format) { + case CAM_FORMAT_MIPI_RAW_8: + case CAM_FORMAT_PLAIN128: + path_format->decode_fmt = 0xf; + if (rpp) { + path_format->decode_fmt = 0x1; + path_format->packing_fmt = 0x1; + } + break; + case CAM_FORMAT_PLAIN8: + path_format->decode_fmt = 0x1; + path_format->plain_fmt = 0x0; + break; + default: + rc = -EINVAL; + break; + } + path_format->bits_per_pxl = 8; + break; + case CAM_FORMAT_MIPI_RAW_10: + switch (out_format) { + case CAM_FORMAT_MIPI_RAW_10: + case CAM_FORMAT_PLAIN128: + path_format->decode_fmt = 0xf; + if (rpp) { + path_format->decode_fmt = 0x2; + path_format->packing_fmt = 0x1; + } + break; + case CAM_FORMAT_PLAIN16_10: + path_format->decode_fmt = 0x2; + path_format->plain_fmt = 0x1; + break; + default: + rc = -EINVAL; + break; + } + path_format->bits_per_pxl = 10; + break; + case CAM_FORMAT_MIPI_RAW_12: + switch (out_format) { + case CAM_FORMAT_MIPI_RAW_12: + path_format->decode_fmt = 0xf; + if (rpp) { + path_format->decode_fmt = 0x3; + path_format->packing_fmt = 0x1; + } + break; + case CAM_FORMAT_PLAIN16_12: + path_format->decode_fmt = 0x3; + path_format->plain_fmt = 0x1; + break; + default: + rc = -EINVAL; + break; + } + path_format->bits_per_pxl = 12; + break; + case CAM_FORMAT_MIPI_RAW_14: + switch (out_format) { + case CAM_FORMAT_MIPI_RAW_14: + path_format->decode_fmt = 0xf; + if (rpp) { + path_format->decode_fmt = 0x4; + path_format->packing_fmt = 0x1; + } + break; + case CAM_FORMAT_PLAIN16_14: + path_format->decode_fmt = 0x4; + path_format->plain_fmt = 0x1; + break; + default: + rc = -EINVAL; + break; + } + path_format->bits_per_pxl = 14; + break; + case CAM_FORMAT_MIPI_RAW_16: + switch (out_format) { + case CAM_FORMAT_MIPI_RAW_16: + path_format->decode_fmt = 0xf; + if (rpp) { + path_format->decode_fmt = 0x5; + path_format->packing_fmt = 0x1; + } + break; + case CAM_FORMAT_PLAIN16_16: + path_format->decode_fmt = 0x5; + path_format->plain_fmt = 0x1; + break; + default: + rc = -EINVAL; + break; + } + path_format->bits_per_pxl = 16; + break; + case CAM_FORMAT_MIPI_RAW_20: + switch (out_format) { + case CAM_FORMAT_MIPI_RAW_20: + path_format->decode_fmt = 0xf; + if (rpp) { + path_format->decode_fmt = 0x6; + path_format->packing_fmt = 0x1; + } + break; + case CAM_FORMAT_PLAIN32_20: + path_format->decode_fmt = 0x6; + path_format->plain_fmt = 0x2; + break; + default: + rc = -EINVAL; + break; + } + path_format->bits_per_pxl = 20; + break; + case CAM_FORMAT_DPCM_10_6_10: + path_format->decode_fmt = 0x7; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_10_8_10: + path_format->decode_fmt = 0x8; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_12_6_12: + path_format->decode_fmt = 0x9; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_12_8_12: + path_format->decode_fmt = 0xA; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_14_8_14: + path_format->decode_fmt = 0xB; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_14_10_14: + path_format->decode_fmt = 0xC; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_12_10_12: + path_format->decode_fmt = 0xD; + path_format->plain_fmt = 0x1; + break; + default: + rc = -EINVAL; + break; + } + + if (rc) + CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d", + in_format, out_format); + + return rc; +} + +int cam_ife_csid_get_format_ipp_ppp( + uint32_t in_format, + struct cam_ife_csid_path_format *path_format) +{ + int rc = 0; + + CAM_DBG(CAM_ISP, "input format:%d", + in_format); + + switch (in_format) { + case CAM_FORMAT_MIPI_RAW_6: + path_format->decode_fmt = 0; + path_format->plain_fmt = 0; + break; + case CAM_FORMAT_MIPI_RAW_8: + path_format->decode_fmt = 0x1; + path_format->plain_fmt = 0; + break; + case CAM_FORMAT_MIPI_RAW_10: + path_format->decode_fmt = 0x2; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_MIPI_RAW_12: + path_format->decode_fmt = 0x3; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_MIPI_RAW_14: + path_format->decode_fmt = 0x4; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_MIPI_RAW_16: + path_format->decode_fmt = 0x5; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_MIPI_RAW_20: + path_format->decode_fmt = 0x6; + path_format->plain_fmt = 0x2; + break; + case CAM_FORMAT_DPCM_10_6_10: + path_format->decode_fmt = 0x7; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_10_8_10: + path_format->decode_fmt = 0x8; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_12_6_12: + path_format->decode_fmt = 0x9; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_12_8_12: + path_format->decode_fmt = 0xA; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_14_8_14: + path_format->decode_fmt = 0xB; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_14_10_14: + path_format->decode_fmt = 0xC; + path_format->plain_fmt = 0x1; + break; + case CAM_FORMAT_DPCM_12_10_12: + path_format->decode_fmt = 0xD; + path_format->plain_fmt = 0x1; + break; + default: + CAM_ERR(CAM_ISP, "Unsupported format %d", + in_format); + rc = -EINVAL; + } + + CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d", + path_format->decode_fmt, + path_format->plain_fmt); + + return rc; +} + +int cam_ife_csid_hw_probe_init(struct cam_hw_intf *hw_intf, + struct cam_ife_csid_core_info *core_info, bool is_custom) +{ + + int rc = -EINVAL; + + if (core_info->sw_version == CAM_IFE_CSID_VER_1_0) { + rc = cam_ife_csid_hw_ver1_init(hw_intf, + core_info, is_custom); + } else if (core_info->sw_version == CAM_IFE_CSID_VER_2_0) { + rc = cam_ife_csid_hw_ver2_init(hw_intf, + core_info, is_custom); + } + + return rc; +} + +int cam_ife_csid_hw_deinit(struct cam_hw_intf *hw_intf, + struct cam_ife_csid_core_info *core_info) +{ + int rc = -EINVAL; + + if (core_info->sw_version == CAM_IFE_CSID_VER_1_0) + rc = cam_ife_csid_hw_ver1_deinit(hw_intf->hw_priv); + else if (core_info->sw_version == CAM_IFE_CSID_VER_2_0) + rc = cam_ife_csid_hw_ver2_deinit( + hw_intf->hw_priv); + + return rc; +} + +int cam_ife_csid_is_vc_full_width(struct cam_ife_csid_cid_data *cid_data) +{ + int i, j; + int rc = 0; + struct cam_ife_csid_cid_data *p_cid; + + for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) { + p_cid = &cid_data[i]; + + if (!p_cid->cid_cnt) + continue; + + if (p_cid->num_vc_dt >= CAM_IFE_CSID_MULTI_VC_DT_GRP_MAX) { + CAM_ERR(CAM_ISP, "Invalid num_vc_dt:%d cid: %d", + p_cid->num_vc_dt, i); + rc = -EINVAL; + goto end; + } + + for (j = 0; j < p_cid->num_vc_dt; j++) { + if (p_cid->vc_dt[j].valid && + p_cid->vc_dt[j].vc > 3) { + rc = 1; + goto end; + } + } + } + +end: + return rc; +} + +int cam_ife_csid_cid_reserve(struct cam_ife_csid_cid_data *cid_data, + uint32_t *cid_value, + uint32_t hw_idx, + struct cam_csid_hw_reserve_resource_args *reserve) +{ + int i, j, rc = 0; + + for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) { + rc = cam_ife_csid_get_cid(&cid_data[i], reserve); + if (!rc) + break; + } + + if (i == CAM_IFE_CSID_CID_MAX) { + for (j = 0; j < reserve->in_port->num_valid_vc_dt; j++) { + CAM_ERR(CAM_ISP, + "CSID[%d] reserve fail vc[%d] dt[%d]", + hw_idx, reserve->in_port->vc[j], + reserve->in_port->dt[j]); + return -EINVAL; + } + } + + cid_data[i].cid_cnt++; + *cid_value = i; + + return 0; +} + +int cam_ife_csid_cid_release( + struct cam_ife_csid_cid_data *cid_data, + uint32_t hw_idx, + uint32_t cid) +{ + int i; + + if (!cid_data->cid_cnt) { + CAM_WARN(CAM_ISP, "CSID[%d] unbalanced cid:%d release", + hw_idx, cid); + return 0; + } + + cid_data->cid_cnt--; + + if (cid_data->cid_cnt == 0) { + + for (i = 0; i < cid_data->num_vc_dt; i++) + cid_data->vc_dt[i].valid = false; + + cid_data->num_vc_dt = 0; + } + + return 0; +} + +int cam_ife_csid_check_in_port_args( + struct cam_csid_hw_reserve_resource_args *reserve, + uint32_t hw_idx) +{ + + if (reserve->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) { + + CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d", + hw_idx, reserve->in_port->res_type); + return -EINVAL; + } + + if (reserve->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX && + reserve->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) { + + CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d", + hw_idx, reserve->in_port->lane_type); + return -EINVAL; + } + + if ((reserve->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY && + reserve->in_port->lane_num > 4) && + reserve->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) { + + CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d", + hw_idx, reserve->in_port->lane_num); + return -EINVAL; + } + + if ((reserve->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY && + reserve->in_port->lane_num > 3) && + reserve->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) { + + CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d", + hw_idx, + reserve->in_port->lane_type, + reserve->in_port->lane_num); + return -EINVAL; + } + + if ((reserve->res_id == CAM_IFE_PIX_PATH_RES_IPP || + reserve->res_id == CAM_IFE_PIX_PATH_RES_PPP) && + (cam_ife_csid_is_pix_res_format_supported( + reserve->in_port->format))) { + CAM_ERR(CAM_ISP, "CSID %d, res_id %d, unsupported format %d", + hw_idx, reserve->res_id, reserve->in_port->format); + return -EINVAL; + } + + return 0; +} + +int cam_ife_csid_set_epd_config(struct cam_ife_csid_hw_flags *flags, + void *cmd_args, uint32_t hw_idx) +{ + struct cam_ife_csid_epd_update_args *epd_update = NULL; + + if ((!flags) || (!cmd_args)) + return -EINVAL; + + epd_update = + (struct cam_ife_csid_epd_update_args *)cmd_args; + + flags->epd_supported = epd_update->epd_supported; + CAM_DBG(CAM_ISP, "CSID[%u] EPD supported %d", hw_idx, + flags->epd_supported); + + return 0; +} + +int cam_ife_csid_get_rt_irq_idx( + uint32_t irq_reg, uint32_t num_ipp, + uint32_t num_ppp, uint32_t num_rdi) +{ + int rt_irq_reg_idx = -EINVAL; + + switch (irq_reg) { + case CAM_IFE_CSID_IRQ_REG_IPP: + rt_irq_reg_idx = CAM_IFE_CSID_IRQ_REG_RX + + num_rdi + 1; + break; + case CAM_IFE_CSID_IRQ_REG_PPP: + rt_irq_reg_idx = CAM_IFE_CSID_IRQ_REG_RX + + num_rdi + num_ipp + 1; + break; + case CAM_IFE_CSID_IRQ_REG_RDI_0: + case CAM_IFE_CSID_IRQ_REG_RDI_1: + case CAM_IFE_CSID_IRQ_REG_RDI_2: + case CAM_IFE_CSID_IRQ_REG_RDI_3: + case CAM_IFE_CSID_IRQ_REG_RDI_4: + rt_irq_reg_idx = irq_reg; + break; + case CAM_IFE_CSID_IRQ_REG_UDI_0: + case CAM_IFE_CSID_IRQ_REG_UDI_1: + case CAM_IFE_CSID_IRQ_REG_UDI_2: + rt_irq_reg_idx = CAM_IFE_CSID_IRQ_REG_RX + + num_rdi + num_ipp + num_ppp + + (irq_reg - CAM_IFE_CSID_IRQ_REG_UDI_0) + 1; + break; + default: + CAM_ERR(CAM_ISP, "Invalid irq reg %d", irq_reg); + break; + } + + return rt_irq_reg_idx; +} + +int cam_ife_csid_convert_res_to_irq_reg(uint32_t res_id) +{ + switch (res_id) { + + case CAM_IFE_PIX_PATH_RES_RDI_0: + return CAM_IFE_CSID_IRQ_REG_RDI_0; + case CAM_IFE_PIX_PATH_RES_RDI_1: + return CAM_IFE_CSID_IRQ_REG_RDI_1; + case CAM_IFE_PIX_PATH_RES_RDI_2: + return CAM_IFE_CSID_IRQ_REG_RDI_2; + case CAM_IFE_PIX_PATH_RES_RDI_3: + return CAM_IFE_CSID_IRQ_REG_RDI_3; + case CAM_IFE_PIX_PATH_RES_RDI_4: + return CAM_IFE_CSID_IRQ_REG_RDI_4; + case CAM_IFE_PIX_PATH_RES_IPP: + return CAM_IFE_CSID_IRQ_REG_IPP; + case CAM_IFE_PIX_PATH_RES_PPP: + return CAM_IFE_CSID_IRQ_REG_PPP; + case CAM_IFE_PIX_PATH_RES_UDI_0: + return CAM_IFE_CSID_IRQ_REG_UDI_0; + case CAM_IFE_PIX_PATH_RES_UDI_1: + return CAM_IFE_CSID_IRQ_REG_UDI_1; + case CAM_IFE_PIX_PATH_RES_UDI_2: + return CAM_IFE_CSID_IRQ_REG_UDI_2; + default: + return -EINVAL; + } +} + +int cam_ife_csid_get_base(struct cam_hw_soc_info *soc_info, + uint32_t base_id, void *cmd_args, size_t arg_size) +{ + struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args; + struct cam_cdm_utils_ops *cdm_util_ops = NULL; + size_t size = 0; + uint32_t mem_base = 0; + + + if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) { + CAM_ERR(CAM_ISP, "Error, Invalid cmd size"); + return -EINVAL; + } + + if (!cdm_args || !cdm_args->res) { + CAM_ERR(CAM_ISP, "Error, Invalid args"); + return -EINVAL; + } + + cdm_util_ops = + (struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops; + + if (!cdm_util_ops) { + CAM_ERR(CAM_ISP, "Invalid CDM ops"); + return -EINVAL; + } + + size = cdm_util_ops->cdm_required_size_changebase(); + /* since cdm returns dwords, we need to convert it into bytes */ + if ((size * 4) > cdm_args->cmd.size) { + CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d", + cdm_args->cmd.size, size); + return -EINVAL; + } + + mem_base = CAM_SOC_GET_REG_MAP_CAM_BASE( + soc_info, base_id); + CAM_DBG(CAM_ISP, "core %d mem_base 0x%x", + soc_info->index, mem_base); + + cdm_util_ops->cdm_write_changebase( + cdm_args->cmd.cmd_buf_addr, mem_base); + cdm_args->cmd.used_bytes = (size * 4); + + return 0; +} +const uint8_t **cam_ife_csid_get_irq_reg_tag_ptr(void) +{ + return cam_ife_csid_irq_reg_tag; +} + + diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h new file mode 100644 index 0000000000..08e1c4f95d --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h @@ -0,0 +1,362 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_IFE_CSID_COMMON_H_ +#define _CAM_IFE_CSID_COMMON_H_ + +#include "cam_hw.h" +#include "cam_ife_csid_hw_intf.h" +#include "cam_ife_csid_soc.h" + +#define CAM_IFE_CSID_VER_1_0 0x100 +#define CAM_IFE_CSID_VER_2_0 0x200 +#define CAM_IFE_CSID_MAX_ERR_COUNT 100 + +#define CAM_IFE_CSID_HW_CAP_IPP 0x1 +#define CAM_IFE_CSID_HW_CAP_RDI 0x2 +#define CAM_IFE_CSID_HW_CAP_PPP 0x4 +#define CAM_IFE_CSID_HW_CAP_TOP 0x8 + +#define CAM_IFE_CSID_TPG_ENCODE_RAW8 0x1 +#define CAM_IFE_CSID_TPG_ENCODE_RAW10 0x2 +#define CAM_IFE_CSID_TPG_ENCODE_RAW12 0x3 +#define CAM_IFE_CSID_TPG_ENCODE_RAW14 0x4 +#define CAM_IFE_CSID_TPG_ENCODE_RAW16 0x5 + +#define CAM_IFE_CSID_TPG_TEST_PATTERN_YUV 0x4 + +#define CAM_IFE_CSID_HW_IDX_0 0x1 +#define CAM_IFE_CSID_HW_IDX_1 0x2 +#define CAM_IFE_CSID_HW_IDX_2 0x4 + +#define CAM_IFE_CSID_LOG_BUF_LEN 512 + +/* + * Debug values enable the corresponding interrupts and debug logs provide + * necessary information + */ +#define CAM_IFE_CSID_DEBUG_ENABLE_SOF_IRQ BIT(0) +#define CAM_IFE_CSID_DEBUG_ENABLE_EOF_IRQ BIT(1) +#define CAM_IFE_CSID_DEBUG_ENABLE_SOT_IRQ BIT(2) +#define CAM_IFE_CSID_DEBUG_ENABLE_EOT_IRQ BIT(3) +#define CAM_IFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE BIT(4) +#define CAM_IFE_CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE BIT(5) +#define CAM_IFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE BIT(6) +#define CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO BIT(7) +#define CAM_IFE_CSID_DEBUG_DISABLE_EARLY_EOF BIT(8) + +/* Binning supported masks. Binning support changes for specific paths + * and also for targets. With the mask, we handle the supported features + * in reg files and handle in code accordingly. + */ + +#define CAM_IFE_CSID_BIN_HORIZONTAL BIT(0) +#define CAM_IFE_CSID_BIN_QCFA BIT(1) +#define CAM_IFE_CSID_BIN_VERTICAL BIT(2) + +#define CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX 4 + +/* enum for multiple mem base in some of the targets */ +enum cam_ife_csid_mem_base_id { + CAM_IFE_CSID_CLC_MEM_BASE_ID, + CAM_IFE_CSID_TOP_MEM_BASE_ID, +}; + +/* enum cam_ife_csid_path_multi_vc_dt_grp: for multi vc dt suppot */ +enum cam_ife_csid_path_multi_vc_dt_grp { + CAM_IFE_CSID_MULTI_VC_DT_GRP_0, + CAM_IFE_CSID_MULTI_VC_DT_GRP_1, + CAM_IFE_CSID_MULTI_VC_DT_GRP_MAX, +}; + +/** + * enum cam_ife_csid_irq_reg - Specify the csid irq reg + */ +enum cam_ife_csid_irq_reg { + CAM_IFE_CSID_IRQ_REG_TOP, + CAM_IFE_CSID_IRQ_REG_RX, + CAM_IFE_CSID_IRQ_REG_RDI_0, + CAM_IFE_CSID_IRQ_REG_RDI_1, + CAM_IFE_CSID_IRQ_REG_RDI_2, + CAM_IFE_CSID_IRQ_REG_RDI_3, + CAM_IFE_CSID_IRQ_REG_RDI_4, + CAM_IFE_CSID_IRQ_REG_IPP, + CAM_IFE_CSID_IRQ_REG_PPP, + CAM_IFE_CSID_IRQ_REG_UDI_0, + CAM_IFE_CSID_IRQ_REG_UDI_1, + CAM_IFE_CSID_IRQ_REG_UDI_2, + CAM_IFE_CSID_IRQ_REG_MAX, +}; + +/* + * struct cam_ife_csid_irq_desc: Structure to hold IRQ description + * + * @irq_desc: String to describe the IRQ bit + */ +struct cam_ife_csid_irq_desc { + uint8_t *desc; +}; + +/* + * struct cam_ife_csid_vc_dt: Structure to hold vc dt combination + * + * @vc: Virtual channel number + * @dt: Data type of incoming data + * @valid: flag to indicate if combimation is valid + */ + +struct cam_ife_csid_vc_dt { + uint32_t vc; + uint32_t dt; + bool valid; +}; + +/* + * struct cam_ife_csid_path_format: Structure format info + * + * @decode_fmt: Decode format + * @packing_fmt: Packing format + * @plain_fmt: Plain format + * @bits_per_pixel: Bits per pixel + */ +struct cam_ife_csid_path_format { + uint32_t decode_fmt; + uint32_t packing_fmt; + uint32_t plain_fmt; + uint32_t bits_per_pxl; +}; + +/* + * struct cam_ife_csid_csi2_rx_reg_info: Structure to hold Rx reg offset + * holds register address offsets + * shift values + * masks + */ +struct cam_ife_csid_csi2_rx_reg_info { + uint32_t irq_status_addr; + uint32_t irq_mask_addr; + uint32_t irq_clear_addr; + uint32_t irq_set_addr; + uint32_t cfg0_addr; + uint32_t cfg1_addr; + uint32_t capture_ctrl_addr; + uint32_t rst_strobes_addr; + uint32_t de_scramble_cfg0_addr; + uint32_t de_scramble_cfg1_addr; + uint32_t cap_unmap_long_pkt_hdr_0_addr; + uint32_t cap_unmap_long_pkt_hdr_1_addr; + uint32_t captured_short_pkt_0_addr; + uint32_t captured_short_pkt_1_addr; + uint32_t captured_long_pkt_0_addr; + uint32_t captured_long_pkt_1_addr; + uint32_t captured_long_pkt_ftr_addr; + uint32_t captured_cphy_pkt_hdr_addr; + uint32_t lane0_misr_addr; + uint32_t lane1_misr_addr; + uint32_t lane2_misr_addr; + uint32_t lane3_misr_addr; + uint32_t total_pkts_rcvd_addr; + uint32_t stats_ecc_addr; + uint32_t total_crc_err_addr; + uint32_t de_scramble_type3_cfg0_addr; + uint32_t de_scramble_type3_cfg1_addr; + uint32_t de_scramble_type2_cfg0_addr; + uint32_t de_scramble_type2_cfg1_addr; + uint32_t de_scramble_type1_cfg0_addr; + uint32_t de_scramble_type1_cfg1_addr; + uint32_t de_scramble_type0_cfg0_addr; + uint32_t de_scramble_type0_cfg1_addr; + + /*configurations */ + uint32_t rst_srb_all; + uint32_t rst_done_shift_val; + uint32_t irq_mask_all; + uint32_t misr_enable_shift_val; + uint32_t vc_mode_shift_val; + uint32_t capture_long_pkt_en_shift; + uint32_t capture_short_pkt_en_shift; + uint32_t capture_cphy_pkt_en_shift; + uint32_t capture_long_pkt_dt_shift; + uint32_t capture_long_pkt_vc_shift; + uint32_t capture_short_pkt_vc_shift; + uint32_t capture_cphy_pkt_dt_shift; + uint32_t capture_cphy_pkt_vc_shift; + uint32_t ecc_correction_shift_en; + uint32_t phy_bist_shift_en; + uint32_t epd_mode_shift_en; + uint32_t eotp_shift_en; + uint32_t dyn_sensor_switch_shift_en; + uint32_t phy_num_mask; + uint32_t vc_mask; + uint32_t wc_mask; + uint32_t dt_mask; + uint32_t calc_crc_mask; + uint32_t expected_crc_mask; + uint32_t lane_num_shift; + uint32_t lane_cfg_shift; + uint32_t phy_type_shift; + uint32_t phy_num_shift; + uint32_t tpg_mux_en_shift; + uint32_t tpg_num_sel_shift; + uint32_t fatal_err_mask; + uint32_t part_fatal_err_mask; + uint32_t non_fatal_err_mask; + uint32_t debug_irq_mask; +}; + +/* + * struct cam_ife_csid_timestamp: place holder for csid core info + * + * @prev_boot_timestamp: Previous frame boot timestamp + * @prev_sof_timestamp: Previous frame SOF timetamp + */ +struct cam_ife_csid_timestamp { + uint64_t prev_boot_ts; + uint64_t prev_sof_ts; +}; + +/* + * struct cam_ife_csid_core_info: place holder for csid core info + * + * @csid_reg: Pointer to csid reg info + * @sw_version: sw version based on targets + */ +struct cam_ife_csid_core_info { + void *csid_reg; + uint32_t sw_version; +}; + +/* + * struct cam_ife_csid_hw_counters: place holder for csid counters + * + * @csi2_reserve_cnt: Reserve count for csi2 + * @irq_debug_cnt: irq debug counter + * @error_irq_count: error irq counter + */ +struct cam_ife_csid_hw_counters { + uint32_t csi2_reserve_cnt; + uint32_t irq_debug_cnt; + uint32_t error_irq_count; +}; + +/* + * struct cam_ife_csid_debug_info: place holder for csid debug + * + * @debug_val: Debug val for enabled features + * @rx_mask: Debug mask for rx irq + * @path_mask: Debug mask for path irq + */ +struct cam_ife_csid_debug_info { + uint32_t debug_val; + uint32_t rx_mask; + uint32_t path_mask; +}; + +/* + * struct cam_ife_csid_hw_flags: place holder for flags + * + * @epd_supported: flag to indicate if epd supported + * @device_enabled: flag to indicate if device enabled + * @binning_enabled: flag to indicate if binning enabled + * @sof_irq_triggered: flag to indicate if sof irq triggered + * @fatal_err_detected: flag to indicate if fatal err detected + * @rx_enabled: flag to indicate if rx is enabled + * @tpg_configured: flag to indicate if internal_tpg is configured + * @sfe_inline_shdr: flag to indicate if sfe is inline shdr + * @reset_awaited: flag to indicate if reset is awaited + */ +struct cam_ife_csid_hw_flags { + bool epd_supported; + bool device_enabled; + bool binning_enabled; + bool sof_irq_triggered; + bool process_reset; + bool fatal_err_detected; + bool rx_enabled; + bool tpg_enabled; + bool tpg_configured; + bool sfe_inline_shdr; + bool reset_awaited; +}; + +/* + * struct cam_ife_csid_hw_flags: place holder for flags + * + * @vc_dt: vc_dt structure + * @cid_cnt: count of cid acquired + * @num_vc_dt: num of vc dt combinaton for this cid in multi vcdt case + */ +struct cam_ife_csid_cid_data { + struct cam_ife_csid_vc_dt vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_MAX]; + uint32_t cid_cnt; + uint32_t num_vc_dt; +}; + +/* + * struct cam_ife_csid_hw_flags: place holder for flags + * + * @phy_sel: selected phy + * @lane_type: type of lane selected + * @lane_num: number of lanes + * @lane_cfg: lane configuration + * @tpg_mux_sel: TPG mux sel + * @tpg_num_sel: TPG num sel + */ +struct cam_ife_csid_rx_cfg { + uint32_t phy_sel; + uint32_t lane_type; + uint32_t lane_num; + uint32_t lane_cfg; + uint32_t tpg_mux_sel; + uint32_t tpg_num_sel; +}; + +int cam_ife_csid_is_pix_res_format_supported( + uint32_t in_format); + +int cam_ife_csid_get_format_rdi( + uint32_t in_format, uint32_t out_format, + struct cam_ife_csid_path_format *path_format, bool rpp); + +int cam_ife_csid_get_format_ipp_ppp( + uint32_t in_format, + struct cam_ife_csid_path_format *path_format); + +int cam_ife_csid_hw_probe_init(struct cam_hw_intf *hw_intf, + struct cam_ife_csid_core_info *core_info, bool is_custom); + +int cam_ife_csid_hw_deinit(struct cam_hw_intf *hw_intf, + struct cam_ife_csid_core_info *core_info); + +int cam_ife_csid_cid_reserve(struct cam_ife_csid_cid_data *cid_data, + uint32_t *cid_value, + uint32_t hw_idx, + struct cam_csid_hw_reserve_resource_args *reserve); + +int cam_ife_csid_cid_release( + struct cam_ife_csid_cid_data *cid_data, + uint32_t hw_idx, + uint32_t cid); + +int cam_ife_csid_check_in_port_args( + struct cam_csid_hw_reserve_resource_args *reserve, + uint32_t hw_idx); + +int cam_ife_csid_set_epd_config(struct cam_ife_csid_hw_flags *flags, + void *cmd_args, uint32_t hw_idx); + +int cam_ife_csid_is_vc_full_width(struct cam_ife_csid_cid_data *cid_data); + +int cam_ife_csid_get_rt_irq_idx( + uint32_t irq_reg, uint32_t num_ipp, + uint32_t num_ppp, uint32_t num_rdi); + +int cam_ife_csid_convert_res_to_irq_reg(uint32_t res_id); + +int cam_ife_csid_get_base(struct cam_hw_soc_info *soc_info, + uint32_t base_id, void *cmd_args, size_t arg_size); + +const uint8_t **cam_ife_csid_get_irq_reg_tag_ptr(void); +#endif /*_CAM_IFE_CSID_COMMON_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c deleted file mode 100644 index 55e09e1317..0000000000 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ /dev/null @@ -1,5694 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. - */ - -#include -#include - -#include -#include - -#include -#include - -#include "cam_isp_hw_mgr_intf.h" -#include "cam_ife_csid_core.h" -#include "cam_isp_hw.h" -#include "cam_soc_util.h" -#include "cam_io_util.h" -#include "cam_debug_util.h" -#include "cam_cpas_api.h" -#include "cam_subdev.h" -#include "cam_tasklet_util.h" - -/* Timeout value in msec */ -#define IFE_CSID_TIMEOUT 1000 - -/* TPG VC/DT values */ -#define CAM_IFE_CSID_TPG_VC_VAL 0xA -#define CAM_IFE_CSID_TPG_DT_VAL 0x2B - -/* CSIPHY TPG VC/DT values */ -#define CAM_IFE_CPHY_TPG_VC_VAL 0x0 -#define CAM_IFE_CPHY_TPG_DT_VAL 0x2B - -/* Timeout values in usec */ -#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000 -#define CAM_IFE_CSID_TIMEOUT_ALL_US 100000 - -#define CAM_IFE_CSID_RESET_TIMEOUT_MS 100 - -/* - * Constant Factors needed to change QTimer ticks to nanoseconds - * QTimer Freq = 19.2 MHz - * Time(us) = ticks/19.2 - * Time(ns) = ticks/19.2 * 1000 - */ -#define CAM_IFE_CSID_QTIMER_MUL_FACTOR 10000 -#define CAM_IFE_CSID_QTIMER_DIV_FACTOR 192 - -/* Max number of sof irq's triggered in case of SOF freeze */ -#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12 - -/* Max CSI Rx irq error count threshold value */ -#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100 - -static int cam_ife_csid_reset_regs( - struct cam_ife_csid_hw *csid_hw, bool reset_hw); -static int cam_ife_csid_is_ipp_ppp_format_supported( - uint32_t in_format) -{ - int rc = -EINVAL; - - switch (in_format) { - case CAM_FORMAT_MIPI_RAW_6: - case CAM_FORMAT_MIPI_RAW_8: - case CAM_FORMAT_MIPI_RAW_10: - case CAM_FORMAT_MIPI_RAW_12: - case CAM_FORMAT_MIPI_RAW_14: - case CAM_FORMAT_MIPI_RAW_16: - case CAM_FORMAT_MIPI_RAW_20: - case CAM_FORMAT_DPCM_10_6_10: - case CAM_FORMAT_DPCM_10_8_10: - case CAM_FORMAT_DPCM_12_6_12: - case CAM_FORMAT_DPCM_12_8_12: - case CAM_FORMAT_DPCM_14_8_14: - case CAM_FORMAT_DPCM_14_10_14: - case CAM_FORMAT_DPCM_12_10_12: - rc = 0; - break; - default: - break; - } - return rc; -} - -static int cam_ife_csid_get_format_rdi( - uint32_t in_format, uint32_t out_format, uint32_t *decode_fmt, - uint32_t *plain_fmt, uint32_t *packing_fmt, bool rpp, uint32_t *in_bpp) -{ - int rc = 0; - - switch (in_format) { - case CAM_FORMAT_MIPI_RAW_6: - switch (out_format) { - case CAM_FORMAT_MIPI_RAW_6: - *decode_fmt = 0xf; - if (rpp) { - *decode_fmt = 0x0; - *packing_fmt = 0x1; - } - break; - case CAM_FORMAT_PLAIN8: - *decode_fmt = 0x0; - *plain_fmt = 0x0; - break; - default: - rc = -EINVAL; - break; - } - *in_bpp = 6; - break; - case CAM_FORMAT_MIPI_RAW_8: - switch (out_format) { - case CAM_FORMAT_MIPI_RAW_8: - case CAM_FORMAT_PLAIN128: - *decode_fmt = 0xf; - if (rpp) { - *decode_fmt = 0x1; - *packing_fmt = 0x1; - } - break; - case CAM_FORMAT_PLAIN8: - *decode_fmt = 0x1; - *plain_fmt = 0x0; - break; - default: - rc = -EINVAL; - break; - } - *in_bpp = 8; - break; - case CAM_FORMAT_MIPI_RAW_10: - switch (out_format) { - case CAM_FORMAT_MIPI_RAW_10: - case CAM_FORMAT_PLAIN128: - *decode_fmt = 0xf; - if (rpp) { - *decode_fmt = 0x2; - *packing_fmt = 0x1; - } - break; - case CAM_FORMAT_PLAIN16_10: - *decode_fmt = 0x2; - *plain_fmt = 0x1; - break; - default: - rc = -EINVAL; - break; - } - *in_bpp = 10; - break; - case CAM_FORMAT_MIPI_RAW_12: - switch (out_format) { - case CAM_FORMAT_MIPI_RAW_12: - *decode_fmt = 0xf; - if (rpp) { - *decode_fmt = 0x3; - *packing_fmt = 0x1; - } - break; - case CAM_FORMAT_PLAIN16_12: - *decode_fmt = 0x3; - *plain_fmt = 0x1; - break; - default: - rc = -EINVAL; - break; - } - *in_bpp = 12; - break; - case CAM_FORMAT_MIPI_RAW_14: - switch (out_format) { - case CAM_FORMAT_MIPI_RAW_14: - *decode_fmt = 0xf; - if (rpp) { - *decode_fmt = 0x4; - *packing_fmt = 0x1; - } - break; - case CAM_FORMAT_PLAIN16_14: - *decode_fmt = 0x4; - *plain_fmt = 0x1; - break; - default: - rc = -EINVAL; - break; - } - *in_bpp = 14; - break; - case CAM_FORMAT_MIPI_RAW_16: - switch (out_format) { - case CAM_FORMAT_MIPI_RAW_16: - *decode_fmt = 0xf; - if (rpp) { - *decode_fmt = 0x5; - *packing_fmt = 0x1; - } - break; - case CAM_FORMAT_PLAIN16_16: - *decode_fmt = 0x5; - *plain_fmt = 0x1; - break; - default: - rc = -EINVAL; - break; - } - *in_bpp = 16; - break; - case CAM_FORMAT_MIPI_RAW_20: - switch (out_format) { - case CAM_FORMAT_MIPI_RAW_20: - *decode_fmt = 0xf; - if (rpp) { - *decode_fmt = 0x6; - *packing_fmt = 0x1; - } - break; - case CAM_FORMAT_PLAIN32_20: - *decode_fmt = 0x6; - *plain_fmt = 0x2; - break; - default: - rc = -EINVAL; - break; - } - *in_bpp = 20; - break; - case CAM_FORMAT_DPCM_10_6_10: - *decode_fmt = 0x7; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_10_8_10: - *decode_fmt = 0x8; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_12_6_12: - *decode_fmt = 0x9; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_12_8_12: - *decode_fmt = 0xA; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_14_8_14: - *decode_fmt = 0xB; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_14_10_14: - *decode_fmt = 0xC; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_12_10_12: - *decode_fmt = 0xD; - *plain_fmt = 0x1; - break; - default: - rc = -EINVAL; - break; - } - - if (rc) - CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d", - in_format, out_format); - - return rc; -} - -static int cam_ife_csid_get_format_ipp_ppp( - uint32_t in_format, - uint32_t *decode_fmt, uint32_t *plain_fmt) -{ - int rc = 0; - - CAM_DBG(CAM_ISP, "input format:%d", - in_format); - - switch (in_format) { - case CAM_FORMAT_MIPI_RAW_6: - *decode_fmt = 0; - *plain_fmt = 0; - break; - case CAM_FORMAT_MIPI_RAW_8: - *decode_fmt = 0x1; - *plain_fmt = 0; - break; - case CAM_FORMAT_MIPI_RAW_10: - *decode_fmt = 0x2; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_MIPI_RAW_12: - *decode_fmt = 0x3; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_MIPI_RAW_14: - *decode_fmt = 0x4; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_MIPI_RAW_16: - *decode_fmt = 0x5; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_MIPI_RAW_20: - *decode_fmt = 0x6; - *plain_fmt = 0x2; - break; - case CAM_FORMAT_DPCM_10_6_10: - *decode_fmt = 0x7; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_10_8_10: - *decode_fmt = 0x8; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_12_6_12: - *decode_fmt = 0x9; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_12_8_12: - *decode_fmt = 0xA; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_14_8_14: - *decode_fmt = 0xB; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_14_10_14: - *decode_fmt = 0xC; - *plain_fmt = 0x1; - break; - case CAM_FORMAT_DPCM_12_10_12: - *decode_fmt = 0xD; - *plain_fmt = 0x1; - break; - default: - CAM_ERR(CAM_ISP, "Unsupported format %d", - in_format); - rc = -EINVAL; - } - - CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d", - *decode_fmt, *plain_fmt); - - return rc; -} - -static int cam_ife_match_vc_dt_pair(int32_t *vc, uint32_t *dt, - uint32_t num_valid_vc_dt, struct cam_ife_csid_cid_data *cid_data) -{ - uint32_t camera_hw_version; - int rc = 0; - - rc = cam_cpas_get_cpas_hw_version(&camera_hw_version); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to get HW version rc:%d", rc); - return -EINVAL; - } - - if ((camera_hw_version != CAM_CPAS_TITAN_480_V100) || - (camera_hw_version != CAM_CPAS_TITAN_580_V100) || - (camera_hw_version != CAM_CPAS_TITAN_570_V200)) - num_valid_vc_dt = 1; - - switch (num_valid_vc_dt) { - case 2: - if (vc[1] != cid_data->vc1 || - dt[1] != cid_data->dt1) - return -EINVAL; - case 1: - if (vc[0] != cid_data->vc || - dt[0] != cid_data->dt) - return -EINVAL; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node **res, int32_t *vc, uint32_t *dt, - uint32_t num_valid_vc_dt) -{ - struct cam_ife_csid_cid_data *cid_data; - uint32_t i = 0; - - *res = NULL; - - /* Return already reserved CID if the VC/DT matches */ - for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) { - if (csid_hw->cid_res[i].res_state >= - CAM_ISP_RESOURCE_STATE_RESERVED) { - cid_data = (struct cam_ife_csid_cid_data *) - csid_hw->cid_res[i].res_priv; - if (!cam_ife_match_vc_dt_pair(vc, dt, - num_valid_vc_dt, cid_data)) { - cid_data->cnt++; - *res = &csid_hw->cid_res[i]; - CAM_DBG(CAM_ISP, "CSID:%d CID %d", - csid_hw->hw_intf->hw_idx, - csid_hw->cid_res[i].res_id); - return 0; - } - } - } - - for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) { - if (csid_hw->cid_res[i].res_state == - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - cid_data = (struct cam_ife_csid_cid_data *) - csid_hw->cid_res[i].res_priv; - cid_data->vc = vc[0]; - cid_data->dt = dt[0]; - if (num_valid_vc_dt > 1) { - cid_data->vc1 = vc[1]; - cid_data->dt1 = dt[1]; - cid_data->is_valid_vc1_dt1 = 1; - } - cid_data->cnt = 1; - csid_hw->cid_res[i].res_state = - CAM_ISP_RESOURCE_STATE_RESERVED; - *res = &csid_hw->cid_res[i]; - CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated", - csid_hw->hw_intf->hw_idx, - csid_hw->cid_res[i].res_id); - return 0; - } - } - - CAM_ERR(CAM_ISP, "CSID:%d Free cid is not available", - csid_hw->hw_intf->hw_idx); - - return -EINVAL; -} - - -static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) -{ - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_reg_offset *csid_reg; - int rc = 0; - uint32_t val = 0, i; - unsigned long flags; - - soc_info = &csid_hw->hw_info->soc_info; - csid_reg = csid_hw->csid_info->csid_reg; - - if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d", - csid_hw->hw_intf->hw_idx, - csid_hw->hw_info->hw_state); - return -EINVAL; - } - - CAM_DBG(CAM_ISP, "CSID:%d Csid reset", - csid_hw->hw_intf->hw_idx); - - spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); - - /* Mask all interrupts */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - - if (csid_reg->cmn_reg->num_pix) - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_mask_addr); - - if (csid_reg->cmn_reg->num_ppp) - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_irq_mask_addr); - - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr); - - /* clear all interrupts */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_clear_addr); - - cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr); - - if (csid_reg->cmn_reg->num_pix) - cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_clear_addr); - - if (csid_reg->cmn_reg->num_ppp) - cam_io_w_mb(csid_reg->cmn_reg->ppp_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_irq_clear_addr); - - for (i = 0 ; i < csid_reg->cmn_reg->num_rdis; i++) - cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr); - - for (i = 0 ; i < csid_reg->cmn_reg->num_udis; i++) - cam_io_w_mb(csid_reg->cmn_reg->udi_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[i]->csid_udi_irq_clear_addr); - - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_irq_cmd_addr); - - spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); - - cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base + - csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr); - - /* enable the IPP and RDI format measure */ - if (csid_reg->cmn_reg->num_pix) - cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_cfg0_addr); - - if (csid_reg->cmn_reg->num_ppp) - cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_cfg0_addr); - - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) - cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr); - - /* reset SW regs first, then HW */ - rc = cam_ife_csid_reset_regs(csid_hw, false); - if (rc < 0) - goto end; - rc = cam_ife_csid_reset_regs(csid_hw, true); - if (rc < 0) - goto end; - - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - if (val != 0) - CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d", - csid_hw->hw_intf->hw_idx, val); - csid_hw->error_irq_count = 0; - csid_hw->prev_boot_timestamp = 0; - -end: - return rc; -} - -static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw, - struct cam_csid_reset_cfg_args *reset) -{ - int rc = 0; - unsigned long rem_jiffies; - struct cam_hw_soc_info *soc_info; - struct cam_isp_resource_node *res; - const struct cam_ife_csid_reg_offset *csid_reg; - uint32_t reset_strb_addr, reset_strb_val, val, id; - struct completion *complete; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - res = reset->node_res; - - if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d", - csid_hw->hw_intf->hw_idx, - csid_hw->hw_info->hw_state); - return -EINVAL; - } - - if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { - CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d", - csid_hw->hw_intf->hw_idx, res->res_id); - rc = -EINVAL; - goto end; - } - - CAM_DBG(CAM_ISP, "CSID:%d resource:%d", - csid_hw->hw_intf->hw_idx, res->res_id); - - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { - if (!csid_reg->ipp_reg) { - CAM_ERR(CAM_ISP, "CSID:%d IPP not supported :%d", - csid_hw->hw_intf->hw_idx, - res->res_id); - return -EINVAL; - } - - reset_strb_addr = csid_reg->ipp_reg->csid_pxl_rst_strobes_addr; - complete = &csid_hw->csid_ipp_complete; - - /* Enable path reset done interrupt */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_mask_addr); - val |= CSID_PATH_INFO_RST_DONE; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_mask_addr); - - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { - if (!csid_reg->ppp_reg) { - CAM_ERR(CAM_ISP, "CSID:%d PPP not supported :%d", - csid_hw->hw_intf->hw_idx, - res->res_id); - return -EINVAL; - } - - reset_strb_addr = csid_reg->ppp_reg->csid_pxl_rst_strobes_addr; - complete = &csid_hw->csid_ppp_complete; - - /* Enable path reset done interrupt */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_irq_mask_addr); - val |= CSID_PATH_INFO_RST_DONE; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_irq_mask_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - id = res->res_id; - if (!csid_reg->rdi_reg[id]) { - CAM_ERR(CAM_ISP, "CSID:%d RDI res not supported :%d", - csid_hw->hw_intf->hw_idx, - res->res_id); - return -EINVAL; - } - - reset_strb_addr = - csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr; - complete = - &csid_hw->csid_rdin_complete[id]; - - /* Enable path reset done interrupt */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); - val |= CSID_PATH_INFO_RST_DONE; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - if (!csid_reg->udi_reg[id]) { - CAM_ERR(CAM_ISP, "CSID:%d UDI res not supported :%d", - csid_hw->hw_intf->hw_idx, - res->res_id); - return -EINVAL; - } - - reset_strb_addr = - csid_reg->udi_reg[id]->csid_udi_rst_strobes_addr; - complete = - &csid_hw->csid_udin_complete[id]; - - /* Enable path reset done interrupt */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_irq_mask_addr); - val |= CSID_PATH_INFO_RST_DONE; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_irq_mask_addr); - } else { - CAM_ERR(CAM_ISP, "Invalid res_id %u", res->res_id); - return -EINVAL; - } - - reinit_completion(complete); - reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all; - - /* Reset the corresponding ife csid path */ - cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base + - reset_strb_addr); - - rem_jiffies = wait_for_completion_timeout(complete, - msecs_to_jiffies(CAM_IFE_CSID_RESET_TIMEOUT_MS)); - if (!rem_jiffies) { - rc = -ETIMEDOUT; - CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d", - csid_hw->hw_intf->hw_idx, - res->res_id, rc); - } - -end: - return rc; - -} - -int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw, - struct cam_csid_hw_reserve_resource_args *cid_reserv) -{ - int rc = 0, i, id; - struct cam_ife_csid_cid_data *cid_data; - uint32_t camera_hw_version; - uint32_t valid_vc_dt; - uint32_t res_type; - struct cam_csid_soc_private *soc_priv; - - CAM_DBG(CAM_ISP, - "CSID:%d res_sel:0x%x Lane type:%d lane_num:%d dt:%d vc:%d cust_node:%u", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->res_type, - cid_reserv->in_port->lane_type, - cid_reserv->in_port->lane_num, - cid_reserv->in_port->dt[0], - cid_reserv->in_port->vc[0], - cid_reserv->in_port->cust_node); - - soc_priv = (struct cam_csid_soc_private *) - (csid_hw->hw_info->soc_info.soc_private); - - if (soc_priv->is_ife_csid_lite && !cid_reserv->can_use_lite) { - CAM_DBG(CAM_ISP, "CSID[%u] not lite context", - csid_hw->hw_intf->hw_idx); - return -EINVAL; - } - - if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->res_type); - rc = -EINVAL; - goto end; - } - - if (cid_reserv->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX && - cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->lane_type); - rc = -EINVAL; - goto end; - } - - if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY && - cid_reserv->in_port->lane_num > 4) && - cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->lane_num); - rc = -EINVAL; - goto end; - } - if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY && - cid_reserv->in_port->lane_num > 3) && - cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) { - CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->lane_type, - cid_reserv->in_port->lane_num); - rc = -EINVAL; - goto end; - } - - valid_vc_dt = cid_reserv->in_port->num_valid_vc_dt; - - /* CSID CSI2 v2.0 supports 31 vc */ - for (i = 0; i < valid_vc_dt; i++) { - if (cid_reserv->in_port->vc[i] > 0x1f || - cid_reserv->in_port->dt[i] > 0x3f) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d or dt: %d", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->vc[i], - cid_reserv->in_port->dt[i]); - rc = -EINVAL; - goto end; - } - } - - if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG && ( - (cid_reserv->in_port->format < CAM_FORMAT_MIPI_RAW_8 && - cid_reserv->in_port->format > CAM_FORMAT_MIPI_RAW_16))) { - CAM_ERR(CAM_ISP, " CSID:%d Invalid tpg decode fmt %d", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->format); - rc = -EINVAL; - goto end; - } - - if (csid_hw->csi2_reserve_cnt == UINT_MAX) { - CAM_ERR(CAM_ISP, - "CSID%d reserve cnt reached max", - csid_hw->hw_intf->hw_idx); - rc = -EINVAL; - goto end; - } - - rc = cam_cpas_get_cpas_hw_version(&camera_hw_version); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to get HW version rc:%d", rc); - goto end; - } - CAM_DBG(CAM_ISP, "HW version: %x", camera_hw_version); - - switch (camera_hw_version) { - case CAM_CPAS_TITAN_NONE: - case CAM_CPAS_TITAN_MAX: - CAM_ERR(CAM_ISP, "Invalid HW version: %x", camera_hw_version); - break; - case CAM_CPAS_TITAN_170_V100: - case CAM_CPAS_TITAN_170_V110: - case CAM_CPAS_TITAN_170_V120: - case CAM_CPAS_TITAN_170_V200: - if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_PHY_3 && - csid_hw->hw_intf->hw_idx != 2) { - rc = -EINVAL; - goto end; - } - break; - case CAM_CPAS_TITAN_480_V100: - case CAM_CPAS_TITAN_580_V100: - /* - * Assigning existing two IFEs for custom in KONA, - * this needs to be addressed accordingly for - * upcoming targets - */ - if (cid_reserv->in_port->cust_node) { - if (cid_reserv->in_port->usage_type == - CAM_ISP_RES_USAGE_DUAL) { - CAM_ERR(CAM_ISP, - "Dual IFE is not supported for cust_node %u", - cid_reserv->in_port->cust_node); - rc = -EINVAL; - goto end; - } - - if (cid_reserv->in_port->cust_node == - CAM_ISP_ACQ_CUSTOM_PRIMARY) { - if (csid_hw->hw_intf->hw_idx != 0) { - CAM_ERR(CAM_ISP, - "CSID%d not eligible for cust_node: %u", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->cust_node); - rc = -EINVAL; - goto end; - } - } - - if (cid_reserv->in_port->cust_node == - CAM_ISP_ACQ_CUSTOM_SECONDARY) { - if (csid_hw->hw_intf->hw_idx != 1) { - CAM_ERR(CAM_ISP, - "CSID%d not eligible for cust_node: %u", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->cust_node); - rc = -EINVAL; - goto end; - } - } - } - break; - default: - break; - } - CAM_DBG(CAM_ISP, "Reserve_cnt %u", csid_hw->csi2_reserve_cnt); - - if (csid_hw->csi2_reserve_cnt) { - /* current configure res type should match requested res type */ - if (csid_hw->res_type != cid_reserv->in_port->res_type) { - rc = -EINVAL; - goto end; - } - - if ((cid_reserv->in_port->res_type != - CAM_ISP_IFE_IN_RES_TPG) && - (csid_hw->csi2_rx_cfg.lane_cfg != - cid_reserv->in_port->lane_cfg || - csid_hw->csi2_rx_cfg.lane_type != - cid_reserv->in_port->lane_type || - csid_hw->csi2_rx_cfg.lane_num != - cid_reserv->in_port->lane_num)) { - rc = -EINVAL; - goto end; - } - if ((cid_reserv->in_port->res_type == - CAM_ISP_IFE_IN_RES_TPG) && - (csid_hw->tpg_cfg.in_format != - cid_reserv->in_port->format || - csid_hw->tpg_cfg.width != - cid_reserv->in_port->left_width || - csid_hw->tpg_cfg.height != - cid_reserv->in_port->height || - csid_hw->tpg_cfg.test_pattern != - cid_reserv->in_port->test_pattern)) { - rc = -EINVAL; - goto end; - } - } - - switch (cid_reserv->res_id) { - case CAM_IFE_PIX_PATH_RES_IPP: - if (csid_hw->ipp_res.res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d IPP resource not available state %d", - csid_hw->hw_intf->hw_idx, - csid_hw->ipp_res.res_state); - rc = -EINVAL; - goto end; - } - break; - case CAM_IFE_PIX_PATH_RES_PPP: - if (csid_hw->ppp_res.res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d PPP resource not available state %d", - csid_hw->hw_intf->hw_idx, - csid_hw->ppp_res.res_state); - rc = -EINVAL; - goto end; - } - break; - case CAM_IFE_PIX_PATH_RES_RDI_0: - case CAM_IFE_PIX_PATH_RES_RDI_1: - case CAM_IFE_PIX_PATH_RES_RDI_2: - case CAM_IFE_PIX_PATH_RES_RDI_3: - if (csid_hw->rdi_res[cid_reserv->res_id].res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d RDI:%d resource not available state:%d", - csid_hw->hw_intf->hw_idx, - cid_reserv->res_id, - csid_hw->rdi_res[cid_reserv->res_id].res_state); - rc = -EINVAL; - goto end; - } - break; - case CAM_IFE_PIX_PATH_RES_UDI_0: - case CAM_IFE_PIX_PATH_RES_UDI_1: - case CAM_IFE_PIX_PATH_RES_UDI_2: - id = cid_reserv->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - if (csid_hw->udi_res[id].res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d UDI:%d resource not available state:%d", - csid_hw->hw_intf->hw_idx, - cid_reserv->res_id, - csid_hw->udi_res[id].res_state); - rc = -EINVAL; - goto end; - } - break; - default: - CAM_ERR(CAM_ISP, "CSID%d: Invalid csid path", - csid_hw->hw_intf->hw_idx); - rc = -EINVAL; - goto end; - } - - rc = cam_ife_csid_cid_get(csid_hw, - &cid_reserv->node_res, - cid_reserv->in_port->vc, - cid_reserv->in_port->dt, - cid_reserv->in_port->num_valid_vc_dt); - if (rc) { - CAM_ERR(CAM_ISP, "CSID:%d CID Reserve failed res_type %d", - csid_hw->hw_intf->hw_idx, - cid_reserv->in_port->res_type); - goto end; - } - cid_data = (struct cam_ife_csid_cid_data *) - cid_reserv->node_res->res_priv; - - CAM_DBG(CAM_ISP, "Obtained cid:%d", cid_reserv->node_res->res_id); - if (!csid_hw->csi2_reserve_cnt) { - csid_hw->res_type = cid_reserv->in_port->res_type; - - csid_hw->csi2_rx_cfg.lane_cfg = - cid_reserv->in_port->lane_cfg; - csid_hw->csi2_rx_cfg.lane_type = - cid_reserv->in_port->lane_type; - csid_hw->csi2_rx_cfg.lane_num = - cid_reserv->in_port->lane_num; - - res_type = cid_reserv->in_port->res_type; - if ((res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) || - (res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1) || - (res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_2)) { - csid_hw->csi2_rx_cfg.phy_sel = - (cid_reserv->phy_sel & 0xFF) - 1; - csid_hw->csi2_reserve_cnt++; - CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired", - csid_hw->hw_intf->hw_idx, - cid_reserv->node_res->res_id); - goto end; - } - - if (cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) { - csid_hw->csi2_rx_cfg.phy_sel = - (cid_reserv->in_port->res_type & 0xFF) - 1; - csid_hw->csi2_reserve_cnt++; - CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired", - csid_hw->hw_intf->hw_idx, - cid_reserv->node_res->res_id); - goto end; - } - - /* Below code is executed only for TPG in_res type */ - csid_hw->csi2_rx_cfg.phy_sel = 0; - if (cid_reserv->in_port->format > - CAM_FORMAT_MIPI_RAW_16) { - CAM_ERR(CAM_ISP, " Wrong TPG format"); - rc = -EINVAL; - goto end; - } - csid_hw->tpg_cfg.in_format = - cid_reserv->in_port->format; - csid_hw->tpg_cfg.usage_type = - cid_reserv->in_port->usage_type; - if (cid_reserv->in_port->usage_type) - csid_hw->tpg_cfg.width = - (cid_reserv->in_port->right_stop + 1); - else - csid_hw->tpg_cfg.width = - cid_reserv->in_port->left_width; - - csid_hw->tpg_cfg.height = cid_reserv->in_port->height; - csid_hw->tpg_cfg.test_pattern = - cid_reserv->in_port->test_pattern; - - CAM_DBG(CAM_ISP, "CSID:%d TPG width:%d height:%d", - csid_hw->hw_intf->hw_idx, - csid_hw->tpg_cfg.width, - csid_hw->tpg_cfg.height); - - cid_data->tpg_set = 1; - } - - csid_hw->csi2_reserve_cnt++; - CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired phy_sel %u", - csid_hw->hw_intf->hw_idx, - cid_reserv->node_res->res_id, - csid_hw->csi2_rx_cfg.phy_sel); - -end: - return rc; -} - -bool cam_ife_csid_is_resolution_supported_by_fuse(uint32_t width) -{ - bool supported = true; - uint32_t hw_version, fuse_val = UINT_MAX; - int rc = 0; - - rc = cam_cpas_get_cpas_hw_version(&hw_version); - - if (rc) { - CAM_ERR(CAM_ISP, "Could not get CPAS version"); - return supported; - } - - switch (hw_version) { - case CAM_CPAS_TITAN_570_V200: - cam_cpas_is_feature_supported(CAM_CPAS_MP_LIMIT_FUSE, - CAM_CPAS_HW_IDX_ANY, &fuse_val); - switch (fuse_val) { - case 0x0: - if (width > CAM_CSID_RESOLUTION_22MP_WIDTH) { - CAM_ERR(CAM_ISP, - "Resolution not supported required_width: %d max_supported_width: %d", - width, CAM_CSID_RESOLUTION_22MP_WIDTH); - supported = false; - } - break; - case 0x1: - if (width > CAM_CSID_RESOLUTION_25MP_WIDTH) { - CAM_ERR(CAM_ISP, - "Resolution not supported required_width: %d max_supported_width: %d", - width, CAM_CSID_RESOLUTION_25MP_WIDTH); - supported = false; - } - break; - case 0x2: - if (width > CAM_CSID_RESOLUTION_28MP_WIDTH) { - CAM_ERR(CAM_ISP, - "Resolution not supported required_width: %d max_supported_width: %d", - width, CAM_CSID_RESOLUTION_28MP_WIDTH); - supported = false; - } - break; - case UINT_MAX: - CAM_WARN(CAM_ISP, "Fuse value not updated"); - break; - default: - CAM_ERR(CAM_ISP, - "Fuse value not defined, fuse_val: 0x%x", - fuse_val); - supported = false; - break; - } - break; - default: - break; - } - return supported; -} - -bool cam_ife_csid_is_resolution_supported_by_dt(struct cam_ife_csid_hw *csid_hw, - uint32_t width) -{ - bool supported = true; - struct cam_hw_soc_info soc_info; - struct cam_csid_soc_private *soc_private = NULL; - - if (!csid_hw || !csid_hw->hw_info) { - CAM_ERR(CAM_ISP, "Argument parsing error!"); - supported = false; - goto end; - } - - soc_info = csid_hw->hw_info->soc_info; - - soc_private = (struct cam_csid_soc_private *)soc_info.soc_private; - - if (!soc_private) { - CAM_ERR(CAM_ISP, "soc_private not found"); - supported = false; - goto end; - } - - if (soc_private->max_width_enabled) { - if (width > soc_private->max_width) { - CAM_ERR(CAM_ISP, - "Resolution not supported required_width: %d max_supported_width: %d", - width, soc_private->max_width); - supported = false; - } - } -end: - return supported; -} - -bool cam_ife_csid_is_resolution_supported(struct cam_ife_csid_hw *csid_hw, - uint32_t width) -{ - bool supported = false; - - if (!csid_hw) { - CAM_ERR(CAM_ISP, "csid_hw is NULL"); - return supported; - } - - if (cam_ife_csid_is_resolution_supported_by_fuse(width) && - cam_ife_csid_is_resolution_supported_by_dt(csid_hw, width)) - supported = true; - return supported; -} - -int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw, - struct cam_csid_hw_reserve_resource_args *reserve) -{ - int rc = 0, i, id; - struct cam_ife_csid_path_cfg *path_data; - struct cam_isp_resource_node *res; - bool is_rdi = false; - uint32_t width = 0; - - /* CSID CSI2 v2.0 supports 31 vc */ - if (reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX) { - CAM_ERR(CAM_ISP, "CSID: %d Sync Mode: %d", - reserve->sync_mode); - return -EINVAL; - } - - for (i = 0; i < reserve->in_port->num_valid_vc_dt; i++) { - if (reserve->in_port->dt[i] > 0x3f || - reserve->in_port->vc[i] > 0x1f) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d", - csid_hw->hw_intf->hw_idx, - reserve->in_port->vc, reserve->in_port->dt); - rc = -EINVAL; - goto end; - } - } - - switch (reserve->res_id) { - case CAM_IFE_PIX_PATH_RES_IPP: - if (csid_hw->ipp_res.res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d IPP resource not available %d", - csid_hw->hw_intf->hw_idx, - csid_hw->ipp_res.res_state); - rc = -EINVAL; - goto end; - } - - if (cam_ife_csid_is_ipp_ppp_format_supported( - reserve->in_port->format)) { - CAM_ERR(CAM_ISP, - "CSID:%d res id:%d un support format %d", - csid_hw->hw_intf->hw_idx, reserve->res_id, - reserve->in_port->format); - rc = -EINVAL; - goto end; - } - - /* assign the IPP resource */ - res = &csid_hw->ipp_res; - CAM_DBG(CAM_ISP, - "CSID:%d IPP resource:%d acquired successfully", - csid_hw->hw_intf->hw_idx, res->res_id); - - break; - case CAM_IFE_PIX_PATH_RES_PPP: - if (csid_hw->ppp_res.res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d PPP resource not available %d", - csid_hw->hw_intf->hw_idx, - csid_hw->ppp_res.res_state); - rc = -EINVAL; - goto end; - } - - if (cam_ife_csid_is_ipp_ppp_format_supported( - reserve->in_port->format)) { - CAM_ERR(CAM_ISP, - "CSID:%d res id:%d unsupported format %d", - csid_hw->hw_intf->hw_idx, reserve->res_id, - reserve->in_port->format); - rc = -EINVAL; - goto end; - } - - /* assign the PPP resource */ - res = &csid_hw->ppp_res; - CAM_DBG(CAM_ISP, - "CSID:%d PPP resource:%d acquired successfully", - csid_hw->hw_intf->hw_idx, res->res_id); - - break; - case CAM_IFE_PIX_PATH_RES_RDI_0: - case CAM_IFE_PIX_PATH_RES_RDI_1: - case CAM_IFE_PIX_PATH_RES_RDI_2: - case CAM_IFE_PIX_PATH_RES_RDI_3: - if (csid_hw->rdi_res[reserve->res_id].res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d RDI:%d resource not available %d", - csid_hw->hw_intf->hw_idx, - reserve->res_id, - csid_hw->rdi_res[reserve->res_id].res_state); - rc = -EINVAL; - goto end; - } else { - res = &csid_hw->rdi_res[reserve->res_id]; - CAM_DBG(CAM_ISP, - "CSID:%d RDI resource:%d acquire success", - csid_hw->hw_intf->hw_idx, - res->res_id); - is_rdi = true; - } - - break; - case CAM_IFE_PIX_PATH_RES_UDI_0: - case CAM_IFE_PIX_PATH_RES_UDI_1: - case CAM_IFE_PIX_PATH_RES_UDI_2: - id = reserve->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - if (csid_hw->udi_res[id].res_state != - CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_DBG(CAM_ISP, - "CSID:%d UDI:%d resource not available %d", - csid_hw->hw_intf->hw_idx, - reserve->res_id, - csid_hw->udi_res[id].res_state); - rc = -EINVAL; - goto end; - } else { - res = &csid_hw->udi_res[id]; - CAM_DBG(CAM_ISP, - "CSID:%d UDI resource:%d acquire success", - csid_hw->hw_intf->hw_idx, - res->res_id); - } - - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res id:%d", - csid_hw->hw_intf->hw_idx, reserve->res_id); - rc = -EINVAL; - goto end; - } - - res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; - path_data = (struct cam_ife_csid_path_cfg *)res->res_priv; - - path_data->cid = reserve->cid; - path_data->in_format = reserve->in_port->format; - path_data->out_format = reserve->out_port->format; - path_data->sync_mode = reserve->sync_mode; - path_data->height = reserve->in_port->height; - path_data->start_line = reserve->in_port->line_start; - path_data->end_line = reserve->in_port->line_stop; - path_data->crop_enable = reserve->crop_enable; - path_data->drop_enable = reserve->drop_enable; - path_data->horizontal_bin = reserve->in_port->horizontal_bin; - path_data->qcfa_bin = reserve->in_port->qcfa_bin; - path_data->num_bytes_out = reserve->in_port->num_bytes_out; - path_data->hblank_cnt = reserve->in_port->hbi_cnt; - - CAM_DBG(CAM_ISP, - "Res id: %d height:%d line_start %d line_stop %d crop_en %d hblank %u", - reserve->res_id, reserve->in_port->height, - reserve->in_port->line_start, reserve->in_port->line_stop, - path_data->crop_enable, path_data->hblank_cnt); - - if ((reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) || - (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1) || - (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_2)) { - path_data->dt = CAM_IFE_CPHY_TPG_DT_VAL; - path_data->vc = CAM_IFE_CPHY_TPG_VC_VAL; - } else if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) { - path_data->dt = CAM_IFE_CSID_TPG_DT_VAL; - path_data->vc = CAM_IFE_CSID_TPG_VC_VAL; - } else { - path_data->dt = reserve->in_port->dt[0]; - path_data->vc = reserve->in_port->vc[0]; - if (reserve->in_port->num_valid_vc_dt) { - path_data->dt1 = reserve->in_port->dt[1]; - path_data->vc1 = reserve->in_port->vc[1]; - path_data->is_valid_vc1_dt1 = 1; - } - } - - if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) { - width = reserve->in_port->left_stop - - reserve->in_port->left_start + 1; - if (path_data->horizontal_bin || path_data->qcfa_bin) - width /= 2; - if ((reserve->res_id == CAM_IFE_PIX_PATH_RES_IPP) && - !(cam_ife_csid_is_resolution_supported(csid_hw, - width))) { - rc = -EINVAL; - goto end; - } - path_data->start_pixel = reserve->in_port->left_start; - path_data->end_pixel = reserve->in_port->left_stop; - path_data->width = reserve->in_port->left_width; - - if (is_rdi) { - path_data->end_pixel = reserve->in_port->right_stop; - path_data->width = path_data->end_pixel - - path_data->start_pixel + 1; - } - - CAM_DBG(CAM_ISP, - "CSID:%d res:%d master:startpixel 0x%x endpixel:0x%x", - csid_hw->hw_intf->hw_idx, reserve->res_id, - path_data->start_pixel, path_data->end_pixel); - CAM_DBG(CAM_ISP, - "CSID:%d res:%d master:line start:0x%x line end:0x%x", - csid_hw->hw_intf->hw_idx, reserve->res_id, - path_data->start_line, path_data->end_line); - } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) { - width = reserve->in_port->right_stop - - reserve->in_port->right_start + 1; - if (path_data->horizontal_bin || path_data->qcfa_bin) - width /= 2; - if ((reserve->res_id == CAM_IFE_PIX_PATH_RES_IPP) && - !(cam_ife_csid_is_resolution_supported(csid_hw, - width))) { - rc = -EINVAL; - goto end; - } - path_data->master_idx = reserve->master_idx; - CAM_DBG(CAM_ISP, "CSID:%d master_idx=%d", - csid_hw->hw_intf->hw_idx, path_data->master_idx); - path_data->start_pixel = reserve->in_port->right_start; - path_data->end_pixel = reserve->in_port->right_stop; - path_data->width = reserve->in_port->right_width; - CAM_DBG(CAM_ISP, - "CSID:%d res:%d slave:start:0x%x end:0x%x width 0x%x", - csid_hw->hw_intf->hw_idx, reserve->res_id, - path_data->start_pixel, path_data->end_pixel, - path_data->width); - CAM_DBG(CAM_ISP, - "CSID:%d res:%d slave:line start:0x%x line end:0x%x", - csid_hw->hw_intf->hw_idx, reserve->res_id, - path_data->start_line, path_data->end_line); - } else { - width = reserve->in_port->left_stop - - reserve->in_port->left_start + 1; - if (path_data->horizontal_bin || path_data->qcfa_bin) - width /= 2; - if ((reserve->res_id == CAM_IFE_PIX_PATH_RES_IPP) && - !(cam_ife_csid_is_resolution_supported(csid_hw, - width))) { - rc = -EINVAL; - goto end; - } - path_data->width = reserve->in_port->left_width; - path_data->start_pixel = reserve->in_port->left_start; - path_data->end_pixel = reserve->in_port->left_stop; - CAM_DBG(CAM_ISP, - "CSID:%d res:%d left width %d start: %d stop:%d", - csid_hw->hw_intf->hw_idx, reserve->res_id, - reserve->in_port->left_width, - reserve->in_port->left_start, - reserve->in_port->left_stop); - } - - CAM_DBG(CAM_ISP, "CSID:%d res:%d width %d height %d", - csid_hw->hw_intf->hw_idx, reserve->res_id, - path_data->width, path_data->height); - reserve->node_res = res; - csid_hw->event_cb = reserve->event_cb; - csid_hw->priv = reserve->priv; - -end: - return rc; -} - -static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) -{ - int rc = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - uint32_t i; - int clk_lvl; - unsigned long flags; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - /* overflow check before increment */ - if (csid_hw->hw_info->open_count == UINT_MAX) { - CAM_ERR(CAM_ISP, "CSID:%d Open count reached max", - csid_hw->hw_intf->hw_idx); - return -EINVAL; - } - - /* Increment ref Count */ - csid_hw->hw_info->open_count++; - if (csid_hw->hw_info->open_count > 1) { - CAM_DBG(CAM_ISP, "CSID hw has already been enabled"); - return rc; - } - - CAM_DBG(CAM_ISP, "CSID:%d init CSID HW", - csid_hw->hw_intf->hw_idx); - - rc = cam_soc_util_get_clk_level(soc_info, csid_hw->clk_rate, - soc_info->src_clk_idx, &clk_lvl); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to get clk level for rate %d", - csid_hw->clk_rate); - goto err; - } - - CAM_DBG(CAM_ISP, "CSID clock lvl %d", clk_lvl); - - rc = cam_ife_csid_enable_soc_resources(soc_info, clk_lvl); - if (rc) { - CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed", - csid_hw->hw_intf->hw_idx); - goto err; - } - - csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP; - /* Reset CSID top */ - rc = cam_ife_csid_global_reset(csid_hw); - if (rc) - goto disable_soc; - - spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); - - /* clear all interrupts */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_clear_addr); - - cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr); - - if (csid_reg->cmn_reg->num_pix) - cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_clear_addr); - - if (csid_reg->cmn_reg->num_ppp) - cam_io_w_mb(csid_reg->cmn_reg->ppp_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_irq_clear_addr); - - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) - cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr); - - for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) - cam_io_w_mb(csid_reg->cmn_reg->udi_irq_mask_all, - soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[i]->csid_udi_irq_clear_addr); - - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_irq_cmd_addr); - - spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); - - csid_hw->csid_info->hw_reg_version = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_hw_version_addr); - CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x", - csid_hw->hw_intf->hw_idx, - csid_hw->csid_info->hw_reg_version); - - spin_lock_irqsave(&csid_hw->lock_state, flags); - csid_hw->fatal_err_detected = false; - csid_hw->device_enabled = 1; - spin_unlock_irqrestore(&csid_hw->lock_state, flags); - cam_tasklet_start(csid_hw->tasklet); - - return 0; - -disable_soc: - cam_ife_csid_disable_soc_resources(soc_info); - csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; -err: - csid_hw->hw_info->open_count--; - return rc; -} - -static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) -{ - int rc = -EINVAL; - uint32_t i; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_reg_offset *csid_reg; - unsigned long flags; - - /* Check for refcount */ - if (!csid_hw->hw_info->open_count) { - CAM_WARN(CAM_ISP, "Unbalanced disable_hw"); - return rc; - } - - /* Decrement ref Count */ - csid_hw->hw_info->open_count--; - - if (csid_hw->hw_info->open_count) { - rc = 0; - return rc; - } - - soc_info = &csid_hw->hw_info->soc_info; - csid_reg = csid_hw->csid_info->csid_reg; - - CAM_DBG(CAM_ISP, "%s:Calling Global Reset\n", __func__); - cam_ife_csid_global_reset(csid_hw); - CAM_DBG(CAM_ISP, "%s:Global Reset Done\n", __func__); - - CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW", - csid_hw->hw_intf->hw_idx); - - /*disable the top IRQ interrupt */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_mask_addr); - - rc = cam_ife_csid_disable_soc_resources(soc_info); - if (rc) - CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed", - csid_hw->hw_intf->hw_idx); - - cam_tasklet_stop(csid_hw->tasklet); - spin_lock_irqsave(&csid_hw->lock_state, flags); - csid_hw->device_enabled = 0; - spin_unlock_irqrestore(&csid_hw->lock_state, flags); - - csid_hw->ipp_path_config.measure_enabled = 0; - csid_hw->ppp_path_config.measure_enabled = 0; - for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) - csid_hw->rdi_path_config[i].measure_enabled = 0; - - csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; - csid_hw->error_irq_count = 0; - csid_hw->prev_boot_timestamp = 0; - csid_hw->epd_supported = 0; - - return rc; -} - - -static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - uint32_t val = 0; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_reg_offset *csid_reg = NULL; - - csid_hw->tpg_start_cnt++; - if (csid_hw->tpg_start_cnt == 1) { - /*Enable the TPG */ - CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG", - csid_hw->hw_intf->hw_idx); - - soc_info = &csid_hw->hw_info->soc_info; - { - uint32_t val; - uint32_t i; - uint32_t base = 0x600; - - CAM_DBG(CAM_ISP, "================ TPG ============"); - for (i = 0; i < 16; i++) { - val = cam_io_r_mb( - soc_info->reg_map[0].mem_base + - base + i * 4); - CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", - (base + i*4), val); - } - - CAM_DBG(CAM_ISP, "================ IPP ============="); - base = 0x200; - for (i = 0; i < 10; i++) { - val = cam_io_r_mb( - soc_info->reg_map[0].mem_base + - base + i * 4); - CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", - (base + i*4), val); - } - - CAM_DBG(CAM_ISP, "================ RX ============="); - base = 0x100; - for (i = 0; i < 5; i++) { - val = cam_io_r_mb( - soc_info->reg_map[0].mem_base + - base + i * 4); - CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", - (base + i*4), val); - } - } - - /* Enable the IFE force clock on for dual isp case */ - csid_reg = csid_hw->csid_info->csid_reg; - if (csid_hw->tpg_cfg.usage_type) { - rc = cam_ife_csid_enable_ife_force_clock_on(soc_info, - csid_reg->tpg_reg->tpg_cpas_ife_reg_offset); - if (rc) - return rc; - } - - CAM_DBG(CAM_ISP, "============ TPG control ============"); - val = (4 << 20); - val |= (0x80 << 8); - val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4); - val |= 7; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_ctrl_addr); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600); - CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val); - } - - return 0; -} - -static int cam_ife_csid_tpg_stop(struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_reg_offset *csid_reg = NULL; - - if (csid_hw->tpg_start_cnt) - csid_hw->tpg_start_cnt--; - - if (csid_hw->tpg_start_cnt) - return 0; - - soc_info = &csid_hw->hw_info->soc_info; - csid_reg = csid_hw->csid_info->csid_reg; - - /* disable the TPG */ - if (!csid_hw->tpg_start_cnt) { - CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG", - csid_hw->hw_intf->hw_idx); - - /* Disable the IFE force clock on for dual isp case */ - if (csid_hw->tpg_cfg.usage_type) - rc = cam_ife_csid_disable_ife_force_clock_on(soc_info, - csid_reg->tpg_reg->tpg_cpas_ife_reg_offset); - - /*stop the TPG */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_ctrl_addr); - } - - return 0; -} - - -static int cam_ife_csid_config_tpg(struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - uint32_t val = 0; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - CAM_DBG(CAM_ISP, "CSID:%d TPG config", - csid_hw->hw_intf->hw_idx); - - /* configure one DT, infinite frames */ - val = (0 << 16) | (1 << 10) | CAM_IFE_CSID_TPG_VC_VAL; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_vc_cfg0_addr); - - /* vertical blanking count = 0x3FF, horzontal blanking count = 0x740*/ - val = (0x3FF << 12) | 0x740; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_vc_cfg1_addr); - - cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base + - csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_lfsr_seed_addr); - - val = csid_hw->tpg_cfg.width << 16 | - csid_hw->tpg_cfg.height; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_dt_n_cfg_0_addr); - - cam_io_w_mb(CAM_IFE_CSID_TPG_DT_VAL, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_dt_n_cfg_1_addr); - - /* - * in_format is the same as the input resource format. - * it is one larger than the register spec format. - */ - val = ((csid_hw->tpg_cfg.in_format - 1) << 16) | 0x8; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_dt_n_cfg_2_addr); - - /* static frame with split color bar */ - val = 1 << 5; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_color_bars_cfg_addr); - /* config pix pattern */ - cam_io_w_mb(csid_hw->tpg_cfg.test_pattern, - soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_common_gen_cfg_addr); - - return 0; -} - -static int cam_ife_csid_csi2_irq_ctrl( - struct cam_ife_csid_hw *csid_hw, - bool irq_enable) -{ - uint32_t val = 0; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_reg_offset *csid_reg; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (irq_enable) { - /*Enable the CSI2 rx interrupts */ - val = CSID_CSI2_RX_INFO_RST_DONE | - CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW | - CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW | - CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW | - CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW | - CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW | - CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION | - CSID_CSI2_RX_ERROR_CRC | - CSID_CSI2_RX_ERROR_ECC | - CSID_CSI2_RX_ERROR_MMAPPED_VC_DT | - CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW | - CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME | - CSID_CSI2_RX_ERROR_CPHY_PH_CRC; - - if (csid_hw->epd_supported == 1) - CAM_INFO(CAM_ISP, - "Disable CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION for EPD"); - else - val = val | CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION; - - /* Enable the interrupt based on csid debug info set */ - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ) - val |= CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED | - CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED | - CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED | - CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) - val |= CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED | - CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED | - CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED | - CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) - val |= CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) - val |= CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED; - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) - val |= CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - } else { - /* Disable the CSI2 rx inerrupts */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - } - - return 0; -} - -static int cam_ife_csid_enable_csi2( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - struct cam_ife_csid_cid_data *cid_data; - uint32_t val = 0; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - CAM_DBG(CAM_ISP, "CSID:%d count:%d config csi2 rx", - csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt); - - /* overflow check before increment */ - if (csid_hw->csi2_cfg_cnt == UINT_MAX) { - CAM_ERR(CAM_ISP, "CSID:%d Open count reached max", - csid_hw->hw_intf->hw_idx); - return -EINVAL; - } - - cid_data = (struct cam_ife_csid_cid_data *)res->res_priv; - - res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; - csid_hw->csi2_cfg_cnt++; - if (csid_hw->csi2_cfg_cnt > 1) - return rc; - - /* rx cfg0 */ - val = 0; - val = (csid_hw->csi2_rx_cfg.lane_num - 1) | - (csid_hw->csi2_rx_cfg.lane_cfg << 4) | - (csid_hw->csi2_rx_cfg.lane_type << 24); - val |= (csid_hw->csi2_rx_cfg.phy_sel & - csid_reg->csi2_reg->csi2_rx_phy_num_mask) << 20; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr); - - /* rx cfg1*/ - val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val); - /* if VC value is more than 3 than set full width of VC */ - if (cid_data->vc > 3 || (cid_data->is_valid_vc1_dt1 && - cid_data->vc1 > 3)) - val |= (1 << csid_reg->csi2_reg->csi2_vc_mode_shift_val); - - /* enable packet ecc correction */ - val |= 1; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr); - - if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) { - /* Config the TPG */ - rc = cam_ife_csid_config_tpg(csid_hw, res); - if (rc) { - res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; - return rc; - } - } - - cam_ife_csid_csi2_irq_ctrl(csid_hw, true); - return 0; -} - -static int cam_ife_csid_disable_csi2( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - if (res->res_id >= CAM_IFE_CSID_CID_MAX) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d", - csid_hw->hw_intf->hw_idx, res->res_id); - return -EINVAL; - } - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - CAM_DBG(CAM_ISP, "CSID:%d cnt : %d Disable csi2 rx", - csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt); - - if (csid_hw->csi2_cfg_cnt) - csid_hw->csi2_cfg_cnt--; - - if (csid_hw->csi2_cfg_cnt) - return 0; - - cam_ife_csid_csi2_irq_ctrl(csid_hw, false); - - /* Reset the Rx CFG registers */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr); - - res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; - - return 0; -} - -static void cam_ife_csid_halt_csi2( - struct cam_ife_csid_hw *csid_hw) -{ - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx", - csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt); - - /* Disable the CSI2 rx inerrupts */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - - /* Reset the Rx CFG registers */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr); -} - -static int cam_ife_csid_init_config_pxl_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - struct cam_ife_csid_path_cfg *path_data; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; - bool is_ipp; - uint32_t decode_format = 0, plain_format = 0, val = 0; - uint32_t camera_hw_version; - struct cam_isp_sensor_dimension *path_config; - - path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { - is_ipp = true; - pxl_reg = csid_reg->ipp_reg; - path_config = &(csid_hw->ipp_path_config); - } else { - is_ipp = false; - pxl_reg = csid_reg->ppp_reg; - path_config = &(csid_hw->ppp_path_config); - } - - if (!pxl_reg) { - CAM_ERR(CAM_ISP, "CSID:%d %s:%d is not supported on HW", - csid_hw->hw_intf->hw_idx, - (is_ipp) ? "IPP" : "PPP", res->res_id); - return -EINVAL; - } - - CAM_DBG(CAM_ISP, "Config %s Path", (is_ipp) ? "IPP" : "PPP"); - rc = cam_ife_csid_get_format_ipp_ppp(path_data->in_format, - &decode_format, &plain_format); - if (rc) - return rc; - - /* - * configure Pxl path and enable the time stamp capture. - * enable the HW measrurement blocks - */ - val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) | - (path_data->dt << csid_reg->cmn_reg->dt_shift_val) | - (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) | - (decode_format << csid_reg->cmn_reg->fmt_shift_val) | - (path_data->crop_enable << - csid_reg->cmn_reg->crop_h_en_shift_val) | - (path_data->crop_enable << - csid_reg->cmn_reg->crop_v_en_shift_val) | - (1 << 1) | 1; - - rc = cam_cpas_get_cpas_hw_version(&camera_hw_version); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to get HW version rc:%d", rc); - camera_hw_version = 0; - } - CAM_DBG(CAM_ISP, "HW version: %x", camera_hw_version); - - if ((camera_hw_version == CAM_CPAS_TITAN_480_V100) || - (camera_hw_version == CAM_CPAS_TITAN_580_V100) || - (camera_hw_version == CAM_CPAS_TITAN_570_V200)) - val |= (path_data->drop_enable << - csid_reg->cmn_reg->drop_h_en_shift_val) | - (path_data->drop_enable << - csid_reg->cmn_reg->drop_v_en_shift_val); - - if (path_data->horizontal_bin || path_data->qcfa_bin) { - val |= (1 << pxl_reg->horizontal_bin_en_shift_val); - if (path_data->qcfa_bin) - val |= (1 << pxl_reg->quad_cfa_bin_en_shift_val); - } - - if (is_ipp && csid_hw->binning_supported && - csid_hw->binning_enable) - val |= (1 << pxl_reg->quad_cfa_bin_en_shift_val); - - val |= (1 << pxl_reg->pix_store_en_shift_val); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg0_addr); - - if (path_data->is_valid_vc1_dt1 && - ((camera_hw_version == CAM_CPAS_TITAN_480_V100) || - (camera_hw_version == CAM_CPAS_TITAN_580_V100) || - (camera_hw_version == CAM_CPAS_TITAN_570_V200))) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_multi_vcdt_cfg0_addr); - val |= ((path_data->vc1 << 2) | - (path_data->dt1 << 7) | 1); - } - - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg1_addr); - - /* Program min hbi between lines */ - if ((path_data->hblank_cnt) && (path_data->hblank_cnt <= - (CAM_CSID_MIN_HBI_CFG_MAX_VAL * 16))) { - if ((path_data->hblank_cnt % 16) == 0) - val |= ((path_data->hblank_cnt / 16) << - pxl_reg->hblank_cfg_shift_val); - else - val |= (((path_data->hblank_cnt / 16) + 1) << - pxl_reg->hblank_cfg_shift_val); - } - - /* select the post irq sub sample strobe for time stamp capture */ - val |= CSID_TIMESTAMP_STB_POST_IRQ; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg1_addr); - - if (path_data->crop_enable) { - val = (((path_data->end_pixel & 0xFFFF) << - csid_reg->cmn_reg->crop_shift) | - (path_data->start_pixel & 0xFFFF)); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_hcrop_addr); - CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x", - csid_hw->hw_intf->hw_idx, val); - - val = (((path_data->end_line & 0xFFFF) << - csid_reg->cmn_reg->crop_shift) | - (path_data->start_line & 0xFFFF)); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_vcrop_addr); - CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", - csid_hw->hw_intf->hw_idx, val); - - /* Enable generating early eof strobe based on crop config. - * Skip for version 480 HW due to HW limitation. - */ - if (!(csid_hw->csid_debug & CSID_DEBUG_DISABLE_EARLY_EOF) && - (camera_hw_version != CAM_CPAS_TITAN_480_V100) && - (camera_hw_version != CAM_CPAS_TITAN_580_V100) && - (camera_hw_version != CAM_CPAS_TITAN_570_V200)) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg0_addr); - val |= (1 << pxl_reg->early_eof_en_shift_val); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg0_addr); - } - } - - /* set frame drop pattern to 0 and period to 1 */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_frm_drop_period_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_frm_drop_pattern_addr); - /* set irq sub sample pattern to 0 and period to 1 */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_irq_subsample_period_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_irq_subsample_pattern_addr); - - /* configure pixel format measure */ - if (path_config->measure_enabled) { - val = (((path_config->height & - csid_reg->cmn_reg->format_measure_height_mask_val) << - csid_reg->cmn_reg->format_measure_height_shift_val) | - (path_config->width & - csid_reg->cmn_reg->format_measure_width_mask_val)); - CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x", - csid_hw->hw_intf->hw_idx, val); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_format_measure_cfg1_addr); - - /* enable pixel and line counter */ - cam_io_w_mb(3, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_format_measure_cfg0_addr); - } - - /* set pxl drop pattern to 0 and period to 1 */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_pix_drop_pattern_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_pix_drop_period_addr); - /* set line drop pattern to 0 and period to 1 */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_line_drop_pattern_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_line_drop_period_addr); - - - /* Enable the Pxl path */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg0_addr); - val |= (1 << csid_reg->cmn_reg->path_en_shift_val); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) - val |= csid_reg->cmn_reg->format_measure_en_val; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg0_addr); - - /* Enable Error Detection */ - if (pxl_reg->overflow_ctrl_en) { - val = pxl_reg->overflow_ctrl_en; - /* Overflow ctrl mode: 2 -> Detect overflow */ - val |= 0x8; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_err_recovery_cfg0_addr); - } - - /* Enable the HBI/VBI counter */ - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_format_measure_cfg0_addr); - val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; - cam_io_w_mb(val, - soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_format_measure_cfg0_addr); - } - - /* configure the rx packet capture based on csid debug set */ - val = 0; - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) - val = ((1 << - csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift)); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) - val |= ((1 << - csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) | - (path_data->dt << - csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift)); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) - val |= ((1 << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) | - (path_data->dt << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift)); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr); - CAM_DBG(CAM_ISP, "rx capture control value 0x%x", val); - - res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; - - return rc; -} - -static int cam_ife_csid_deinit_pxl_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - uint32_t val; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; - bool is_ipp; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { - is_ipp = true; - pxl_reg = csid_reg->ipp_reg; - } else { - is_ipp = false; - pxl_reg = csid_reg->ppp_reg; - } - - if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { - CAM_ERR(CAM_ISP, - "CSID:%d %s Res type %d res_id:%d in wrong state %d", - csid_hw->hw_intf->hw_idx, - (is_ipp) ? "IPP" : "PPP", - res->res_type, res->res_id, res->res_state); - rc = -EINVAL; - } - - if (!pxl_reg) { - CAM_ERR(CAM_ISP, "CSID:%d %s %d is not supported on HW", - csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", - res->res_id); - rc = -EINVAL; - goto end; - } - - /* Disable Error Recovery */ - if (pxl_reg->overflow_ctrl_en) - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_err_recovery_cfg0_addr); - - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg0_addr); - if (val & csid_reg->cmn_reg->format_measure_en_val) { - val &= ~csid_reg->cmn_reg->format_measure_en_val; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_cfg0_addr); - - /* Disable the HBI/VBI counter */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_format_measure_cfg0_addr); - val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_format_measure_cfg0_addr); - } - -end: - res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; - return rc; -} - -static int cam_ife_csid_enable_pxl_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - struct cam_ife_csid_path_cfg *path_data; - const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; - bool is_ipp; - uint32_t val = 0; - struct cam_isp_sensor_dimension *path_config; - unsigned int irq_mask_val = 0; - - path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { - is_ipp = true; - pxl_reg = csid_reg->ipp_reg; - path_config = &(csid_hw->ipp_path_config); - } else { - is_ipp = false; - pxl_reg = csid_reg->ppp_reg; - path_config = &(csid_hw->ppp_path_config); - } - - if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { - CAM_ERR(CAM_ISP, - "CSID:%d %s path res type:%d res_id:%d Invalid state%d", - csid_hw->hw_intf->hw_idx, - (is_ipp) ? "IPP" : "PPP", - res->res_type, res->res_id, res->res_state); - return -EINVAL; - } - - if (!pxl_reg) { - CAM_ERR(CAM_ISP, "CSID:%d %s %d not supported on HW", - csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", - res->res_id); - return -EINVAL; - } - - CAM_DBG(CAM_ISP, "Enable %s path", (is_ipp) ? "IPP" : "PPP"); - - if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ) && - (path_data->sync_mode != CAM_ISP_HW_SYNC_SLAVE)) { - irq_mask_val = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - - if (!(irq_mask_val & - CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT)) { - CAM_DBG(CAM_ISP, - "Subscribing to UNMAPPED_VC_DT event for sync_mode: %d", - path_data->sync_mode); - irq_mask_val |= - CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT; - cam_io_w_mb(irq_mask_val, - soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - } - } - - /* Set master or slave path */ - if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) { - /*Set halt mode as master */ - if (pxl_reg->halt_master_sel_en) - val = pxl_reg->halt_sel_internal_master_val << 4 | - CSID_HALT_MODE_MASTER << 2; - else - val = CSID_HALT_MODE_MASTER << 2; - } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE) { - /*Set halt mode as slave and set master idx */ - if (pxl_reg->halt_master_sel_en) - val = CSID_HALT_MODE_SLAVE << 2; - else - val = path_data->master_idx << 4 | - CSID_HALT_MODE_SLAVE << 2; - } else { - /* Default is internal halt mode */ - val = 0; - } - /* - * Resume at frame boundary if Master or No Sync. - * Slave will get resume command from Master. - */ - if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER || - path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) - val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_ctrl_addr); - - CAM_DBG(CAM_ISP, "CSID:%d %s Ctrl val: 0x%x", - csid_hw->hw_intf->hw_idx, - (is_ipp) ? "IPP" : "PPP", val); - - /* Enable the required pxl path interrupts */ - val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW; - - if (pxl_reg->ccif_violation_en) - val |= CSID_PATH_ERROR_CCIF_VIOLATION; - - if (pxl_reg->overflow_ctrl_en) - val |= CSID_PATH_OVERFLOW_RECOVERY; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) - val |= CSID_PATH_INFO_INPUT_SOF; - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) - val |= CSID_PATH_INFO_INPUT_EOF; - - val |= (CSID_PATH_ERROR_PIX_COUNT | - CSID_PATH_ERROR_LINE_COUNT); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_irq_mask_addr); - - CAM_DBG(CAM_ISP, "Enable %s IRQ mask 0x%x", - (is_ipp) ? "IPP" : "PPP", val); - - res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; - - return 0; -} - - -static int cam_ife_csid_change_pxl_halt_mode( - struct cam_ife_csid_hw *csid_hw, - struct cam_ife_csid_hw_halt_args *csid_halt) -{ - uint32_t val = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_pxl_reg_offset *pxl_reg; - struct cam_isp_resource_node *res; - - res = csid_halt->node_res; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_id != CAM_IFE_PIX_PATH_RES_IPP) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res id %d", - csid_hw->hw_intf->hw_idx, res->res_id); - return -EINVAL; - } - - if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { - CAM_ERR(CAM_ISP, "CSID:%d Res:%d in invalid state:%d", - csid_hw->hw_intf->hw_idx, res->res_id, res->res_state); - return -EINVAL; - } - - pxl_reg = csid_reg->ipp_reg; - - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_irq_mask_addr); - - /* configure Halt for slave */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_ctrl_addr); - val &= ~0xC; - val |= (csid_halt->halt_mode << 2); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_ctrl_addr); - CAM_DBG(CAM_ISP, "CSID:%d IPP path Res halt mode:%d configured:%x", - csid_hw->hw_intf->hw_idx, csid_halt->halt_mode, val); - - return 0; -} - -static int cam_ife_csid_disable_pxl_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res, - enum cam_ife_csid_halt_cmd stop_cmd) -{ - int rc = 0; - uint32_t val = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - struct cam_ife_csid_path_cfg *path_data; - const struct cam_ife_csid_pxl_reg_offset *pxl_reg; - bool is_ipp; - - path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { - CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d", - csid_hw->hw_intf->hw_idx, res->res_id); - return -EINVAL; - } - - if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW || - res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { - CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d", - csid_hw->hw_intf->hw_idx, res->res_id, res->res_state); - return rc; - } - - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { - is_ipp = true; - pxl_reg = csid_reg->ipp_reg; - } else { - is_ipp = false; - pxl_reg = csid_reg->ppp_reg; - } - - if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { - CAM_DBG(CAM_ISP, "CSID:%d %s path Res:%d Invalid state%d", - csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", - res->res_id, res->res_state); - return -EINVAL; - } - - if (!pxl_reg) { - CAM_ERR(CAM_ISP, "CSID:%d %s %d is not supported on HW", - csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", - res->res_id); - return -EINVAL; - } - - if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY && - stop_cmd != CAM_CSID_HALT_IMMEDIATELY) { - CAM_ERR(CAM_ISP, "CSID:%d %s path un supported stop command:%d", - csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", - stop_cmd); - return -EINVAL; - } - - CAM_DBG(CAM_ISP, "CSID:%d res_id:%d %s path", - csid_hw->hw_intf->hw_idx, res->res_id, - (is_ipp) ? "IPP" : "PPP"); - - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_irq_mask_addr); - - if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER || - path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) { - /* configure Halt for master */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_ctrl_addr); - val &= ~0x3; - val |= stop_cmd; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_ctrl_addr); - } - - if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE && - stop_cmd == CAM_CSID_HALT_IMMEDIATELY) { - /* configure Halt for slave */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_ctrl_addr); - val &= ~0xF; - val |= stop_cmd; - val |= (CSID_HALT_MODE_MASTER << 2); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - pxl_reg->csid_pxl_ctrl_addr); - } - - return rc; -} - -static int cam_ife_csid_init_config_rdi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - struct cam_ife_csid_path_cfg *path_data; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - uint32_t path_format = 0, plain_fmt = 0, val = 0, id; - uint32_t format_measure_addr, camera_hw_version; - uint32_t packing_fmt = 0, in_bpp = 0; - - path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - id = res->res_id; - if (!csid_reg->rdi_reg[id]) { - CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", - csid_hw->hw_intf->hw_idx, id); - return -EINVAL; - } - - rc = cam_ife_csid_get_format_rdi(path_data->in_format, - path_data->out_format, &path_format, &plain_fmt, &packing_fmt, - path_data->crop_enable || path_data->drop_enable, &in_bpp); - if (rc) - return rc; - - /* - * RDI path config and enable the time stamp capture - * Enable the measurement blocks - */ - val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) | - (path_data->dt << csid_reg->cmn_reg->dt_shift_val) | - (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) | - (path_format << csid_reg->cmn_reg->fmt_shift_val) | - (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) | - (path_data->crop_enable << - csid_reg->cmn_reg->crop_h_en_shift_val) | - (path_data->crop_enable << - csid_reg->cmn_reg->crop_v_en_shift_val) | - (1 << 2) | 3; - - rc = cam_cpas_get_cpas_hw_version(&camera_hw_version); - if (rc) { - CAM_ERR(CAM_ISP, "Failed to get HW version rc:%d", rc); - camera_hw_version = 0; - } - CAM_DBG(CAM_ISP, "HW version: %x", camera_hw_version); - - if (camera_hw_version == CAM_CPAS_TITAN_480_V100 || - camera_hw_version == CAM_CPAS_TITAN_175_V130 || - camera_hw_version == CAM_CPAS_TITAN_580_V100 || - camera_hw_version == CAM_CPAS_TITAN_570_V200 || - camera_hw_version == CAM_CPAS_TITAN_165_V100) { - val |= (path_data->drop_enable << - csid_reg->cmn_reg->drop_h_en_shift_val) | - (path_data->drop_enable << - csid_reg->cmn_reg->drop_v_en_shift_val) | - (packing_fmt << - csid_reg->cmn_reg->packing_fmt_shift_val); - } - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); - - if (path_data->is_valid_vc1_dt1 && - ((camera_hw_version == CAM_CPAS_TITAN_480_V100) || - (camera_hw_version == CAM_CPAS_TITAN_580_V100) || - (camera_hw_version == CAM_CPAS_TITAN_570_V200))) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_multi_vcdt_cfg0_addr); - val |= ((path_data->vc1 << 2) | - (path_data->dt1 << 7) | 1); - } - - /* select the post irq sub sample strobe for time stamp capture */ - cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr); - - if (path_data->crop_enable) { - val = (((path_data->end_pixel & 0xFFFF) << - csid_reg->cmn_reg->crop_shift) | - (path_data->start_pixel & 0xFFFF)); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_rpp_hcrop_addr); - CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x", - csid_hw->hw_intf->hw_idx, val); - - val = (((path_data->end_line & 0xFFFF) << - csid_reg->cmn_reg->crop_shift) | - (path_data->start_line & 0xFFFF)); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_rpp_vcrop_addr); - CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", - csid_hw->hw_intf->hw_idx, val); - } - - /* Enable Error Detection */ - if (csid_reg->rdi_reg[id]->overflow_ctrl_en) { - val = csid_reg->rdi_reg[id]->overflow_ctrl_en; - /* Overflow ctrl mode: 2 -> Detect overflow */ - val |= 0x8; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_err_recovery_cfg0_addr); - } - - /* configure pixel format measure */ - if (csid_hw->rdi_path_config[id].measure_enabled) { - val = ((csid_hw->rdi_path_config[id].height & - csid_reg->cmn_reg->format_measure_height_mask_val) << - csid_reg->cmn_reg->format_measure_height_shift_val); - - if (path_format == 0xF) - val |= (__KERNEL_DIV_ROUND_UP( - (csid_hw->rdi_path_config[id].width * - in_bpp), 8) & - csid_reg->cmn_reg->format_measure_width_mask_val); - else - val |= (csid_hw->rdi_path_config[id].width & - csid_reg->cmn_reg->format_measure_width_mask_val); - - CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x", - csid_hw->hw_intf->hw_idx, val); - CAM_DBG(CAM_ISP, "format measure width : 0x%x height : 0x%x", - csid_hw->rdi_path_config[id].width, - csid_hw->rdi_path_config[id].height); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr); - - /* enable pixel and line counter */ - cam_io_w_mb(3, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr); - } - - /* set frame drop pattern to 0 and period to 1 */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_frm_drop_pattern_addr); - /* set IRQ sum sabmple */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_period_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_pattern_addr); - - /* set pixel drop pattern to 0 and period to 1 */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_pattern_addr); - - /* Write max value to pixel drop period due to a bug in ver 480 HW */ - if (((camera_hw_version == CAM_CPAS_TITAN_480_V100) || - (camera_hw_version == CAM_CPAS_TITAN_580_V100) || - (camera_hw_version == CAM_CPAS_TITAN_570_V200)) && - path_data->drop_enable) - cam_io_w_mb(0x1F, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr); - else - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr); - - /* set line drop pattern to 0 and period to 1 */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_pattern_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_period_addr); - - /* Configure the halt mode */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); - - /* Enable the RPP path */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); - val |= (1 << csid_reg->cmn_reg->path_en_shift_val); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) - val |= csid_reg->cmn_reg->format_measure_en_val; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); - - format_measure_addr = - csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr; - - /* Enable the HBI/VBI counter */ - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - format_measure_addr); - val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; - cam_io_w_mb(val, - soc_info->reg_map[0].mem_base + format_measure_addr); - } - - /* configure the rx packet capture based on csid debug set */ - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) - val = ((1 << - csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift)); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) - val |= ((1 << - csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) | - (path_data->dt << - csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift)); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) - val |= ((1 << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) | - (path_data->dt << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift)); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr); - - res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; - - return rc; -} - -static int cam_ife_csid_init_config_udi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - struct cam_ife_csid_path_cfg *path_data; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - uint32_t path_format = 0, plain_fmt = 0, val = 0, val1, id; - uint32_t format_measure_addr, packing_fmt = 0, in_bpp = 0; - - path_data = (struct cam_ife_csid_path_cfg *)res->res_priv; - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - if ((id >= CAM_IFE_CSID_UDI_MAX) || (!csid_reg->udi_reg[id])) { - CAM_ERR(CAM_ISP, "CSID:%d UDI:%d is not supported on HW", - csid_hw->hw_intf->hw_idx, id); - return -EINVAL; - } - - rc = cam_ife_csid_get_format_rdi(path_data->in_format, - path_data->out_format, &path_format, &plain_fmt, &packing_fmt, - path_data->crop_enable || path_data->drop_enable, &in_bpp); - if (rc) { - CAM_ERR(CAM_ISP, - "Failed to get format in_format: %u out_format: %u rc: %d", - path_data->in_format, path_data->out_format, rc); - return rc; - } - - /* - * UDI path config and enable the time stamp capture - * Enable the measurement blocks - */ - val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) | - (path_data->dt << csid_reg->cmn_reg->dt_shift_val) | - (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) | - (path_format << csid_reg->cmn_reg->fmt_shift_val) | - (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) | - (path_data->crop_enable << - csid_reg->cmn_reg->crop_h_en_shift_val) | - (path_data->crop_enable << - csid_reg->cmn_reg->crop_v_en_shift_val) | - (1 << 2) | 3; - - val |= (packing_fmt << csid_reg->cmn_reg->packing_fmt_shift_val); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_cfg0_addr); - - /* select the post irq sub sample strobe for time stamp capture */ - val1 = CSID_TIMESTAMP_STB_POST_IRQ; - - /* select the num bytes out per cycle */ - val1 |= (path_data->num_bytes_out << - csid_reg->cmn_reg->num_bytes_out_shift_val); - - cam_io_w_mb(val1, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_cfg1_addr); - - /* Enable Error Detection */ - if (csid_reg->udi_reg[id]->overflow_ctrl_en) { - val = csid_reg->udi_reg[id]->overflow_ctrl_en; - /* Overflow ctrl mode: 2 -> Detect overflow */ - val |= 0x8; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_err_recovery_cfg0_addr); - } - - /* set frame drop pattern to 0 and period to 1 */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_frm_drop_period_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_frm_drop_pattern_addr); - /* set IRQ sum sabmple */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_irq_subsample_period_addr); - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_irq_subsample_pattern_addr); - - /* set pixel drop pattern to 0 and period to 1 */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_rpp_pix_drop_pattern_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_rpp_pix_drop_period_addr); - /* set line drop pattern to 0 and period to 1 */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_rpp_line_drop_pattern_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_rpp_line_drop_period_addr); - - /* Configure the halt mode */ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_ctrl_addr); - - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_cfg0_addr); - val |= (1 << csid_reg->cmn_reg->path_en_shift_val); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) - val |= csid_reg->cmn_reg->format_measure_en_val; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_cfg0_addr); - - format_measure_addr = - csid_reg->udi_reg[id]->csid_udi_format_measure_cfg0_addr; - - /* Enable the HBI/VBI counter */ - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - format_measure_addr); - val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; - cam_io_w_mb(val, - soc_info->reg_map[0].mem_base + format_measure_addr); - } - - /* configure the rx packet capture based on csid debug set */ - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) - val = ((1 << - csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift)); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) - val |= ((1 << - csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) | - (path_data->dt << - csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift)); - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) - val |= ((1 << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) | - (path_data->dt << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) | - (path_data->vc << - csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift)); - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr); - - res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; - - return rc; -} - -static int cam_ife_csid_deinit_udi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - uint32_t id, val, format_measure_addr; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - - if ((res->res_id < CAM_IFE_PIX_PATH_RES_UDI_0) || - (res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2) || - (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) || - (!csid_reg->udi_reg[id])) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d", - csid_hw->hw_intf->hw_idx, res->res_id, - res->res_state); - return -EINVAL; - } - - /* Disable Error Recovery */ - if (csid_reg->udi_reg[id]->overflow_ctrl_en) { - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_err_recovery_cfg0_addr); - } - - format_measure_addr = - csid_reg->udi_reg[id]->csid_udi_format_measure_cfg0_addr; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_cfg0_addr); - val &= ~csid_reg->cmn_reg->format_measure_en_val; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_cfg0_addr); - - /* Disable the HBI/VBI counter */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - format_measure_addr); - val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - format_measure_addr); - } - - res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; - return rc; -} - -static int cam_ife_csid_deinit_rdi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - int rc = 0; - uint32_t id, val, format_measure_addr; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - id = res->res_id; - - if (res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 || - res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || - !csid_reg->rdi_reg[id]) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d", - csid_hw->hw_intf->hw_idx, res->res_id, - res->res_state); - return -EINVAL; - } - - /* Disable Error Recovery */ - if (csid_reg->rdi_reg[id]->overflow_ctrl_en) { - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_err_recovery_cfg0_addr); - } - - format_measure_addr = - csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); - val &= ~csid_reg->cmn_reg->format_measure_en_val; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); - - /* Disable the HBI/VBI counter */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - format_measure_addr); - val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - format_measure_addr); - } - - res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; - return rc; -} - -static int cam_ife_csid_enable_rdi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - unsigned int irq_mask_val = 0; - uint32_t id, val; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - id = res->res_id; - - if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || - res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 || - !csid_reg->rdi_reg[id]) { - CAM_ERR(CAM_ISP, - "CSID:%d invalid res type:%d res_id:%d state%d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id, res->res_state); - return -EINVAL; - } - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ) { - irq_mask_val = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - - if (!(irq_mask_val & - CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT)) { - CAM_DBG(CAM_ISP, "Subscribing to UNMAPPED_VC_DT event"); - irq_mask_val |= - CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT; - cam_io_w_mb(irq_mask_val, - soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - } - } - - /*resume at frame boundary */ - cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, - soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); - - /* Enable the required RDI interrupts */ - val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW; - - if (csid_reg->rdi_reg[id]->ccif_violation_en) - val |= CSID_PATH_ERROR_CCIF_VIOLATION; - - if (csid_reg->rdi_reg[id]->overflow_ctrl_en) - val |= CSID_PATH_OVERFLOW_RECOVERY; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) - val |= CSID_PATH_INFO_INPUT_SOF; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) - val |= CSID_PATH_INFO_INPUT_EOF; - - val |= (CSID_PATH_ERROR_PIX_COUNT | - CSID_PATH_ERROR_LINE_COUNT); - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); - - res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; - - return 0; -} - -static int cam_ife_csid_enable_udi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - unsigned int irq_mask_val = 0; - uint32_t id, val; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - - if ((res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) || - (res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2) || - (res->res_id < CAM_IFE_PIX_PATH_RES_UDI_0) || - (!csid_reg->udi_reg[id])) { - CAM_ERR(CAM_ISP, - "CSID:%d invalid res type:%d res_id:%d state%d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id, res->res_state); - return -EINVAL; - } - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ) { - irq_mask_val = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - - if (!(irq_mask_val & - CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT)) { - CAM_DBG(CAM_ISP, - "Subscribing to UNMAPPED_VC_DT event"); - irq_mask_val |= - CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT; - cam_io_w_mb(irq_mask_val, - soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); - } - } - - /*resume at frame boundary */ - cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, - soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_ctrl_addr); - - /* Enable the required UDI interrupts */ - val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW; - - if (csid_reg->udi_reg[id]->ccif_violation_en) - val |= CSID_PATH_ERROR_CCIF_VIOLATION; - - if (csid_reg->udi_reg[id]->overflow_ctrl_en) - val |= CSID_PATH_OVERFLOW_RECOVERY; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) - val |= CSID_PATH_INFO_INPUT_SOF; - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) - val |= CSID_PATH_INFO_INPUT_EOF; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_irq_mask_addr); - - res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; - - return 0; -} - -static int cam_ife_csid_disable_rdi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res, - enum cam_ife_csid_halt_cmd stop_cmd) -{ - int rc = 0; - uint32_t id, val = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - id = res->res_id; - - if ((res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3) || - (!csid_reg->rdi_reg[res->res_id])) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d Invalid res id%d", - csid_hw->hw_intf->hw_idx, res->res_id); - return -EINVAL; - } - - if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW || - res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d Res:%d already in stopped state:%d", - csid_hw->hw_intf->hw_idx, - res->res_id, res->res_state); - return rc; - } - - if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d Res:%d Invalid res_state%d", - csid_hw->hw_intf->hw_idx, res->res_id, - res->res_state); - return -EINVAL; - } - - if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY && - stop_cmd != CAM_CSID_HALT_IMMEDIATELY) { - CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d", - csid_hw->hw_intf->hw_idx, stop_cmd); - return -EINVAL; - } - - CAM_DBG(CAM_ISP, "CSID:%d res_id:%d", - csid_hw->hw_intf->hw_idx, res->res_id); - - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); - - /* Halt the RDI path */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); - val &= ~0x3; - val |= stop_cmd; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); - - return rc; -} - -static int cam_ife_csid_disable_udi_path( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res, - enum cam_ife_csid_halt_cmd stop_cmd) -{ - int rc = 0; - uint32_t id, val = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - - if ((res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2) || - (res->res_id < CAM_IFE_PIX_PATH_RES_UDI_0) || - (!csid_reg->udi_reg[id])) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d Invalid res id%d", - csid_hw->hw_intf->hw_idx, res->res_id); - return -EINVAL; - } - - if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW || - res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d Res:%d already in stopped state:%d", - csid_hw->hw_intf->hw_idx, - res->res_id, res->res_state); - return rc; - } - - if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d Res:%d Invalid res_state%d", - csid_hw->hw_intf->hw_idx, res->res_id, - res->res_state); - return -EINVAL; - } - - if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY && - stop_cmd != CAM_CSID_HALT_IMMEDIATELY) { - CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d", - csid_hw->hw_intf->hw_idx, stop_cmd); - return -EINVAL; - } - - CAM_DBG(CAM_ISP, "CSID:%d res_id:%d", - csid_hw->hw_intf->hw_idx, res->res_id); - - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_irq_mask_addr); - - /* Halt the UDI path */ - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_ctrl_addr); - val &= ~0x3; - val |= stop_cmd; - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[id]->csid_udi_ctrl_addr); - - return rc; -} - -static int cam_ife_csid_poll_stop_status( - struct cam_ife_csid_hw *csid_hw, - uint32_t res_mask) -{ - int rc = 0, id; - uint32_t csid_status_addr = 0, val = 0, res_id = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - for (; res_id < CAM_IFE_PIX_PATH_RES_MAX; res_id++, res_mask >>= 1) { - if ((res_mask & 0x1) == 0) - continue; - val = 0; - - if (res_id == CAM_IFE_PIX_PATH_RES_IPP) { - csid_status_addr = - csid_reg->ipp_reg->csid_pxl_status_addr; - } else if (res_id == CAM_IFE_PIX_PATH_RES_PPP) { - csid_status_addr = - csid_reg->ppp_reg->csid_pxl_status_addr; - } else if (res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - csid_status_addr = - csid_reg->rdi_reg[res_id]->csid_rdi_status_addr; - } else if (res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - id = res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - csid_status_addr = - csid_reg->udi_reg[id]->csid_udi_status_addr; - } else { - CAM_ERR(CAM_ISP, "Invalid res_id: %u", res_id); - rc = -EINVAL; - break; - } - - CAM_DBG(CAM_ISP, "start polling CSID:%d res_id:%d", - csid_hw->hw_intf->hw_idx, res_id); - - rc = readl_poll_timeout(soc_info->reg_map[0].mem_base + - csid_status_addr, val, (val & 0x1) == 0x1, - CAM_IFE_CSID_TIMEOUT_SLEEP_US, - CAM_IFE_CSID_TIMEOUT_ALL_US); - if (rc < 0) { - CAM_ERR(CAM_ISP, "CSID:%d res:%d halt failed rc %d", - csid_hw->hw_intf->hw_idx, res_id, rc); - rc = -ETIMEDOUT; - break; - } - CAM_DBG(CAM_ISP, "End polling CSID:%d res_id:%d", - csid_hw->hw_intf->hw_idx, res_id); - } - - return rc; -} - -static int cam_ife_csid_get_hbi_vbi( - struct cam_ife_csid_hw *csid_hw, - struct cam_isp_resource_node *res) -{ - uint32_t hbi, vbi; - int32_t id; - const struct cam_ife_csid_reg_offset *csid_reg; - const struct cam_ife_csid_rdi_reg_offset *rdi_reg; - const struct cam_ife_csid_udi_reg_offset *udi_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH || - res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - return -EINVAL; - } - - if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d", - csid_hw->hw_intf->hw_idx, - csid_hw->hw_info->hw_state); - return -EINVAL; - } - - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { - hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_format_measure1_addr); - vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_format_measure2_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { - hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_format_measure1_addr); - vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_format_measure2_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - rdi_reg = csid_reg->rdi_reg[res->res_id]; - hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - rdi_reg->csid_rdi_format_measure1_addr); - vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - rdi_reg->csid_rdi_format_measure2_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - udi_reg = csid_reg->udi_reg[id]; - hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - udi_reg->csid_udi_format_measure1_addr); - vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + - udi_reg->csid_udi_format_measure2_addr); - } else { - CAM_ERR(CAM_ISP, "Invalid res_id: %u", res->res_id); - return -EINVAL; - } - - CAM_INFO_RATE_LIMIT(CAM_ISP, - "Device %s index %u Resource %u HBI: 0x%x VBI: 0x%x", - soc_info->dev_name, soc_info->index, - res->res_id, hbi, vbi); - - return 0; -} - -static int cam_ife_csid_get_time_stamp( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - struct cam_csid_get_time_stamp_args *time_stamp; - struct cam_isp_resource_node *res; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_rdi_reg_offset *rdi_reg; - const struct cam_ife_csid_udi_reg_offset *udi_reg; - struct timespec64 ts; - uint32_t time_32, id; - uint64_t time_delta = 0; - - time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args; - res = time_stamp->node_res; - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH || - res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { - CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - return -EINVAL; - } - - if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d", - csid_hw->hw_intf->hw_idx, - csid_hw->hw_info->hw_state); - return -EINVAL; - } - - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_timestamp_curr1_sof_addr); - time_stamp->time_stamp_val = (uint64_t) time_32; - time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32; - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_timestamp_curr0_sof_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_timestamp_curr1_sof_addr); - time_stamp->time_stamp_val = (uint64_t) time_32; - time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32; - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_timestamp_curr0_sof_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - id = res->res_id; - rdi_reg = csid_reg->rdi_reg[id]; - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - rdi_reg->csid_rdi_timestamp_curr1_sof_addr); - time_stamp->time_stamp_val = (uint64_t) time_32; - time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32; - - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - rdi_reg->csid_rdi_timestamp_curr0_sof_addr); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; - udi_reg = csid_reg->udi_reg[id]; - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - udi_reg->csid_udi_timestamp_curr1_sof_addr); - time_stamp->time_stamp_val = (uint64_t) time_32; - time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32; - - time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - udi_reg->csid_udi_timestamp_curr0_sof_addr); - } else { - CAM_ERR(CAM_ISP, "Invalid res_id: %u", res->res_id); - return -EINVAL; - } - - time_stamp->time_stamp_val |= (uint64_t) time_32; - time_stamp->time_stamp_val = mul_u64_u32_div( - time_stamp->time_stamp_val, - CAM_IFE_CSID_QTIMER_MUL_FACTOR, - CAM_IFE_CSID_QTIMER_DIV_FACTOR); - - if (!csid_hw->prev_boot_timestamp) { - ktime_get_boottime_ts64(&ts); - time_stamp->boot_timestamp = - (uint64_t)((ts.tv_sec * 1000000000) + - ts.tv_nsec); - csid_hw->prev_qtimer_ts = 0; - CAM_DBG(CAM_ISP, "timestamp:%lld", - time_stamp->boot_timestamp); - } else { - time_delta = time_stamp->time_stamp_val - - csid_hw->prev_qtimer_ts; - time_stamp->boot_timestamp = - csid_hw->prev_boot_timestamp + time_delta; - if (time_delta == 0) - CAM_WARN_RATE_LIMIT(CAM_ISP, - "CSID:%d No qtimer update ts: %lld prev ts:%lld", - csid_hw->hw_intf->hw_idx, - time_stamp->time_stamp_val, - csid_hw->prev_qtimer_ts); - } - csid_hw->prev_qtimer_ts = time_stamp->time_stamp_val; - csid_hw->prev_boot_timestamp = time_stamp->boot_timestamp; - - return 0; -} - -static int cam_ife_csid_set_csid_debug(struct cam_ife_csid_hw *csid_hw, - void *cmd_args) -{ - uint32_t *csid_debug; - - csid_debug = (uint32_t *) cmd_args; - csid_hw->csid_debug = *csid_debug; - CAM_DBG(CAM_ISP, "CSID:%d set csid debug value:%d", - csid_hw->hw_intf->hw_idx, csid_hw->csid_debug); - - return 0; -} - -int cam_ife_csid_get_hw_caps(void *hw_priv, - void *get_hw_cap_args, uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw_caps *hw_caps; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_csid_soc_private *soc_priv = NULL; - - if (!hw_priv || !get_hw_cap_args) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - csid_reg = csid_hw->csid_info->csid_reg; - hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args; - - hw_caps->num_rdis = csid_reg->cmn_reg->num_rdis; - hw_caps->num_pix = csid_reg->cmn_reg->num_pix; - hw_caps->num_ppp = csid_reg->cmn_reg->num_ppp; - - /* NOTE: HW version is not correct since we dont enable - * the soc resources in the probe for CSID, instead we - * when the camera actually runs - */ - hw_caps->version_incr = - csid_hw->csid_info->hw_reg_version & 0x00ffff; - hw_caps->minor_version = - (csid_hw->csid_info->hw_reg_version >> 16) & 0x0fff; - hw_caps->major_version = - (csid_hw->csid_info->hw_reg_version >> 28) & 0x000f; - - soc_priv = (struct cam_csid_soc_private *) - (csid_hw_info->soc_info.soc_private); - - hw_caps->is_lite = soc_priv->is_ife_csid_lite; - - CAM_DBG(CAM_ISP, - "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d", - csid_hw->hw_intf->hw_idx, hw_caps->num_rdis, - hw_caps->num_pix, hw_caps->major_version, - hw_caps->minor_version, hw_caps->version_incr); - - return rc; -} - -int cam_ife_csid_reset(void *hw_priv, - void *reset_args, uint32_t arg_size) -{ - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_csid_reset_cfg_args *reset; - int rc = 0; - - if (!hw_priv || !reset_args || (arg_size != - sizeof(struct cam_csid_reset_cfg_args))) { - CAM_ERR(CAM_ISP, "CSID:Invalid args"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - reset = (struct cam_csid_reset_cfg_args *)reset_args; - - mutex_lock(&csid_hw->hw_info->hw_mutex); - switch (reset->reset_type) { - case CAM_IFE_CSID_RESET_GLOBAL: - rc = cam_ife_csid_global_reset(csid_hw); - break; - case CAM_IFE_CSID_RESET_PATH: - rc = cam_ife_csid_path_reset(csid_hw, reset); - break; - default: - CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d", - reset->reset_type); - rc = -EINVAL; - break; - } - mutex_unlock(&csid_hw->hw_info->hw_mutex); - - return rc; -} - -int cam_ife_csid_reserve(void *hw_priv, - void *reserve_args, uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_csid_hw_reserve_resource_args *reserv; - - if (!hw_priv || !reserve_args || (arg_size != - sizeof(struct cam_csid_hw_reserve_resource_args))) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - reserv = (struct cam_csid_hw_reserve_resource_args *)reserve_args; - - CAM_DBG(CAM_ISP, "res_type %d, CSID: %u", - reserv->res_type, csid_hw->hw_intf->hw_idx); - - mutex_lock(&csid_hw->hw_info->hw_mutex); - switch (reserv->res_type) { - case CAM_ISP_RESOURCE_CID: - rc = cam_ife_csid_cid_reserve(csid_hw, reserv); - break; - case CAM_ISP_RESOURCE_PIX_PATH: - rc = cam_ife_csid_path_reserve(csid_hw, reserv); - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type :%d", - csid_hw->hw_intf->hw_idx, reserv->res_type); - rc = -EINVAL; - break; - } - mutex_unlock(&csid_hw->hw_info->hw_mutex); - return rc; -} - -int cam_ife_csid_release(void *hw_priv, - void *release_args, uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_isp_resource_node *res; - struct cam_ife_csid_cid_data *cid_data; - - if (!hw_priv || !release_args || - (arg_size != sizeof(struct cam_isp_resource_node))) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - res = (struct cam_isp_resource_node *)release_args; - - mutex_lock(&csid_hw->hw_info->hw_mutex); - csid_hw->event_cb = NULL; - csid_hw->priv = NULL; - if ((res->res_type == CAM_ISP_RESOURCE_CID && - res->res_id >= CAM_IFE_CSID_CID_MAX) || - (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && - res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - rc = -EINVAL; - goto end; - } - - if ((res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) || - (res->res_state >= CAM_ISP_RESOURCE_STATE_STREAMING)) { - CAM_WARN(CAM_ISP, - "CSID:%d res type:%d Res %d in state %d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id, - res->res_state); - goto end; - } - - CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); - - switch (res->res_type) { - case CAM_ISP_RESOURCE_CID: - cid_data = (struct cam_ife_csid_cid_data *) res->res_priv; - if (cid_data->cnt) - cid_data->cnt--; - - if (!cid_data->cnt) - res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; - - if (csid_hw->csi2_reserve_cnt) - csid_hw->csi2_reserve_cnt--; - - if (!csid_hw->csi2_reserve_cnt) - memset(&csid_hw->csi2_rx_cfg, 0, - sizeof(struct cam_ife_csid_csi2_rx_cfg)); - - CAM_DBG(CAM_ISP, "CSID:%d res id :%d cnt:%d reserv cnt:%d res_state:%d", - csid_hw->hw_intf->hw_idx, - res->res_id, cid_data->cnt, csid_hw->csi2_reserve_cnt, - res->res_state); - - break; - case CAM_ISP_RESOURCE_PIX_PATH: - res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) - csid_hw->ipp_path_config.measure_enabled = 0; - else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) - csid_hw->ppp_path_config.measure_enabled = 0; - else if (res->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0 && - res->res_id <= CAM_IFE_PIX_PATH_RES_RDI_3) - csid_hw->rdi_path_config[res->res_id].measure_enabled - = 0; - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - rc = -EINVAL; - break; - } - -end: - mutex_unlock(&csid_hw->hw_info->hw_mutex); - return rc; -} - -static int cam_ife_csid_reset_regs( - struct cam_ife_csid_hw *csid_hw, bool reset_hw) -{ - int rc = 0; - const struct cam_ife_csid_reg_offset *csid_reg = - csid_hw->csid_info->csid_reg; - struct cam_hw_soc_info *soc_info; - uint32_t val = 0; - unsigned long flags, rem_jiffies = 0; - - soc_info = &csid_hw->hw_info->soc_info; - - reinit_completion(&csid_hw->csid_top_complete); - - spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); - - csid_hw->is_resetting = true; - - /* clear the top interrupt first */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_clear_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_irq_cmd_addr); - - if (reset_hw) { - /* enable top reset complete IRQ */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_mask_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_irq_cmd_addr); - } - - /* perform the top CSID registers reset */ - val = reset_hw ? csid_reg->cmn_reg->csid_rst_stb : - csid_reg->cmn_reg->csid_reg_rst_stb; - cam_io_w_mb(val, - soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_rst_strobes_addr); - - /* - * for SW reset, we enable the IRQ after since the mask - * register has been reset - */ - if (!reset_hw) { - /* enable top reset complete IRQ */ - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_mask_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_irq_cmd_addr); - } - - spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); - CAM_DBG(CAM_ISP, "CSID reset start"); - - rem_jiffies = wait_for_completion_timeout(&csid_hw->csid_top_complete, - msecs_to_jiffies(CAM_IFE_CSID_RESET_TIMEOUT_MS)); - if (rem_jiffies == 0) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_status_addr); - if (val & 0x1) { - /* clear top reset IRQ */ - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_clear_addr); - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_irq_cmd_addr); - CAM_DBG(CAM_ISP, "CSID:%d %s reset completed %d", - csid_hw->hw_intf->hw_idx, - reset_hw ? "hw" : "sw", - rem_jiffies); - goto end; - } - CAM_ERR(CAM_ISP, "CSID:%d csid_reset %s fail rc = %d", - csid_hw->hw_intf->hw_idx, reset_hw ? "hw" : "sw", - rem_jiffies); - rc = -ETIMEDOUT; - goto end; - } else - CAM_DBG(CAM_ISP, "CSID:%d %s reset completed %d", - csid_hw->hw_intf->hw_idx, reset_hw ? "hw" : "sw", - rem_jiffies); - -end: - csid_hw->is_resetting = false; - return rc; -} - -int cam_ife_csid_init_hw(void *hw_priv, - void *init_args, uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_isp_resource_node *res; - const struct cam_ife_csid_reg_offset *csid_reg; - - if (!hw_priv || !init_args || - (arg_size != sizeof(struct cam_isp_resource_node))) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - res = (struct cam_isp_resource_node *)init_args; - csid_reg = csid_hw->csid_info->csid_reg; - - mutex_lock(&csid_hw->hw_info->hw_mutex); - if ((res->res_type == CAM_ISP_RESOURCE_CID && - res->res_id >= CAM_IFE_CSID_CID_MAX) || - (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && - res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - rc = -EINVAL; - goto end; - } - - if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) && - (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) { - CAM_ERR(CAM_ISP, - "CSID:%d res type:%d res_id:%dInvalid state %d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id, res->res_state); - rc = -EINVAL; - goto end; - } - - CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); - - /* Initialize the csid hardware */ - rc = cam_ife_csid_enable_hw(csid_hw); - if (rc) - goto end; - - switch (res->res_type) { - case CAM_ISP_RESOURCE_CID: - rc = cam_ife_csid_enable_csi2(csid_hw, res); - break; - case CAM_ISP_RESOURCE_PIX_PATH: - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP || - res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { - rc = cam_ife_csid_init_config_pxl_path(csid_hw, res); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - rc = cam_ife_csid_init_config_rdi_path(csid_hw, res); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - rc = cam_ife_csid_init_config_udi_path(csid_hw, res); - } else { - CAM_ERR(CAM_ISP, "Invalid res_id: %u", res->res_id); - rc = -EINVAL; - goto end; - } - - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type state %d", - csid_hw->hw_intf->hw_idx, - res->res_type); - break; - } - - rc = cam_ife_csid_reset_regs(csid_hw, true); - if (rc < 0) - CAM_ERR(CAM_ISP, "CSID: Failed in HW reset"); - - if (rc) - cam_ife_csid_disable_hw(csid_hw); - -end: - mutex_unlock(&csid_hw->hw_info->hw_mutex); - return rc; -} - -int cam_ife_csid_deinit_hw(void *hw_priv, - void *deinit_args, uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_isp_resource_node *res; - - if (!hw_priv || !deinit_args || - (arg_size != sizeof(struct cam_isp_resource_node))) { - CAM_ERR(CAM_ISP, "CSID:Invalid arguments"); - return -EINVAL; - } - - CAM_DBG(CAM_ISP, "Enter"); - res = (struct cam_isp_resource_node *)deinit_args; - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - - mutex_lock(&csid_hw->hw_info->hw_mutex); - if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { - CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state", - csid_hw->hw_intf->hw_idx, - res->res_id); - goto end; - } - - switch (res->res_type) { - case CAM_ISP_RESOURCE_CID: - CAM_DBG(CAM_ISP, "De-Init ife_csid"); - rc = cam_ife_csid_disable_csi2(csid_hw, res); - break; - case CAM_ISP_RESOURCE_PIX_PATH: - CAM_DBG(CAM_ISP, "De-Init Pix Path: %d\n", res->res_id); - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP || - res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { - rc = cam_ife_csid_deinit_pxl_path(csid_hw, res); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - rc = cam_ife_csid_deinit_rdi_path(csid_hw, res); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - rc = cam_ife_csid_deinit_udi_path(csid_hw, res); - } else { - CAM_ERR(CAM_ISP, "Invalid res_id: %u", res->res_id); - rc = -EINVAL; - goto end; - } - - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d", - csid_hw->hw_intf->hw_idx, - res->res_type); - goto end; - } - - /* Disable CSID HW */ - CAM_DBG(CAM_ISP, "Disabling CSID Hw\n"); - cam_ife_csid_disable_hw(csid_hw); - CAM_DBG(CAM_ISP, "%s: Exit\n", __func__); - -end: - mutex_unlock(&csid_hw->hw_info->hw_mutex); - return rc; -} - -int cam_ife_csid_start(void *hw_priv, void *start_args, - uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_isp_resource_node *res; - const struct cam_ife_csid_reg_offset *csid_reg; - unsigned long flags; - - if (!hw_priv || !start_args || - (arg_size != sizeof(struct cam_isp_resource_node))) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - res = (struct cam_isp_resource_node *)start_args; - csid_reg = csid_hw->csid_info->csid_reg; - - if ((res->res_type == CAM_ISP_RESOURCE_CID && - res->res_id >= CAM_IFE_CSID_CID_MAX) || - (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && - res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) { - CAM_DBG(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, - res->res_id); - rc = -EINVAL; - goto end; - } - - /* Reset sof irq debug fields */ - csid_hw->sof_irq_triggered = false; - csid_hw->irq_debug_cnt = 0; - - spin_lock_irqsave(&csid_hw->lock_state, flags); - if (!csid_hw->device_enabled) - cam_ife_csid_csi2_irq_ctrl(csid_hw, true); - csid_hw->device_enabled = 1; - - CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d", - csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); - - switch (res->res_type) { - case CAM_ISP_RESOURCE_CID: - if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) - rc = cam_ife_csid_tpg_start(csid_hw, res); - break; - case CAM_ISP_RESOURCE_PIX_PATH: - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP || - res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { - rc = cam_ife_csid_enable_pxl_path(csid_hw, res); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - rc = cam_ife_csid_enable_rdi_path(csid_hw, res); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - rc = cam_ife_csid_enable_udi_path(csid_hw, res); - } else { - CAM_ERR(CAM_ISP, "Invalid res_id: %u", res->res_id); - rc = -EINVAL; - goto irq_restore; - } - - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", - csid_hw->hw_intf->hw_idx, - res->res_type); - break; - } -irq_restore: - spin_unlock_irqrestore(&csid_hw->lock_state, flags); -end: - return rc; -} - -int cam_ife_csid_halt(struct cam_ife_csid_hw *csid_hw, - void *halt_args) -{ - struct cam_isp_resource_node *res; - struct cam_ife_csid_hw_halt_args *csid_halt; - int rc = 0; - - if (!csid_hw || !halt_args) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - - csid_halt = (struct cam_ife_csid_hw_halt_args *)halt_args; - - /* Change the halt mode */ - res = csid_halt->node_res; - CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id); - - if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type %d", - csid_hw->hw_intf->hw_idx, - res->res_type); - return -EINVAL; - } - - switch (res->res_id) { - case CAM_IFE_PIX_PATH_RES_IPP: - rc = cam_ife_csid_change_pxl_halt_mode(csid_hw, csid_halt); - break; - default: - CAM_DBG(CAM_ISP, "CSID:%d res_id %d", - csid_hw->hw_intf->hw_idx, - res->res_id); - break; - } - - return rc; -} - -int cam_ife_csid_stop(void *hw_priv, - void *stop_args, uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_isp_resource_node *res; - struct cam_csid_hw_stop_args *csid_stop; - uint32_t i; - uint32_t res_mask = 0; - unsigned long flags; - - if (!hw_priv || !stop_args || - (arg_size != sizeof(struct cam_csid_hw_stop_args))) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - csid_stop = (struct cam_csid_hw_stop_args *) stop_args; - - if (!csid_stop->num_res) { - CAM_ERR(CAM_ISP, "CSID: Invalid args"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - CAM_DBG(CAM_ISP, "CSID:%d num_res %d", - csid_hw->hw_intf->hw_idx, - csid_stop->num_res); - - spin_lock_irqsave(&csid_hw->lock_state, flags); - csid_hw->device_enabled = 0; - cam_ife_csid_csi2_irq_ctrl(csid_hw, false); - spin_unlock_irqrestore(&csid_hw->lock_state, flags); - - /* Stop the resource first */ - for (i = 0; i < csid_stop->num_res; i++) { - res = csid_stop->node_res[i]; - CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d", - csid_hw->hw_intf->hw_idx, - res->res_type, res->res_id); - switch (res->res_type) { - case CAM_ISP_RESOURCE_CID: - if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) - rc = cam_ife_csid_tpg_stop(csid_hw, res); - break; - case CAM_ISP_RESOURCE_PIX_PATH: - res_mask |= (1 << res->res_id); - if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP || - res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { - rc = cam_ife_csid_disable_pxl_path(csid_hw, - res, csid_stop->stop_cmd); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || - res->res_id == CAM_IFE_PIX_PATH_RES_RDI_3) { - rc = cam_ife_csid_disable_rdi_path(csid_hw, - res, csid_stop->stop_cmd); - } else if (res->res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || - res->res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { - rc = cam_ife_csid_disable_udi_path(csid_hw, - res, csid_stop->stop_cmd); - } else { - CAM_ERR(CAM_ISP, "Invalid res_id: %u", - res->res_id); - return -EINVAL; - } - - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", - csid_hw->hw_intf->hw_idx, - res->res_type); - break; - } - } - - if (res_mask) - rc = cam_ife_csid_poll_stop_status(csid_hw, res_mask); - - for (i = 0; i < csid_stop->num_res; i++) { - res = csid_stop->node_res[i]; - res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; - } - - CAM_DBG(CAM_ISP, "%s: Exit\n", __func__); - - return rc; - -} - -int cam_ife_csid_read(void *hw_priv, - void *read_args, uint32_t arg_size) -{ - CAM_ERR(CAM_ISP, "CSID: un supported"); - - return -EINVAL; -} - -int cam_ife_csid_write(void *hw_priv, - void *write_args, uint32_t arg_size) -{ - CAM_ERR(CAM_ISP, "CSID: un supported"); - return -EINVAL; -} - -static int cam_ife_csid_sof_irq_debug( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - int i = 0; - uint32_t val = 0; - bool sof_irq_enable = false; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (*((uint32_t *)cmd_args) == 1) - sof_irq_enable = true; - - if (csid_hw->hw_info->hw_state == - CAM_HW_STATE_POWER_DOWN) { - CAM_WARN(CAM_ISP, - "CSID:%d powered down unable to %s sof irq", - csid_hw->hw_intf->hw_idx, - (sof_irq_enable == true) ? "enable" : "disable"); - return 0; - } - - if (csid_reg->ipp_reg) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_mask_addr); - - if (val) { - if (sof_irq_enable) - val |= CSID_PATH_INFO_INPUT_SOF; - else - val &= ~CSID_PATH_INFO_INPUT_SOF; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_mask_addr); - val = 0; - } - } - - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr); - if (val) { - if (sof_irq_enable) - val |= CSID_PATH_INFO_INPUT_SOF; - else - val &= ~CSID_PATH_INFO_INPUT_SOF; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr); - val = 0; - } - } - - for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[i]->csid_udi_irq_mask_addr); - if (val) { - if (sof_irq_enable) - val |= CSID_PATH_INFO_INPUT_SOF; - else - val &= ~CSID_PATH_INFO_INPUT_SOF; - - cam_io_w_mb(val, soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[i]->csid_udi_irq_mask_addr); - val = 0; - } - } - - if (sof_irq_enable) { - csid_hw->csid_debug |= CSID_DEBUG_ENABLE_SOF_IRQ; - csid_hw->sof_irq_triggered = true; - } else { - csid_hw->csid_debug &= ~CSID_DEBUG_ENABLE_SOF_IRQ; - csid_hw->sof_irq_triggered = false; - } - - if (!in_irq()) - CAM_INFO(CAM_ISP, "SOF freeze: CSID SOF irq %s, CSID HW:%d", - (sof_irq_enable) ? "enabled" : "disabled", - csid_hw->hw_intf->hw_idx); - - return 0; -} - -static int cam_ife_csid_set_csid_clock( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - struct cam_ife_csid_clock_update_args *clk_update = NULL; - - if (!csid_hw) - return -EINVAL; - - clk_update = - (struct cam_ife_csid_clock_update_args *)cmd_args; - - csid_hw->clk_rate = clk_update->clk_rate; - CAM_INFO(CAM_ISP, "CSID clock rate %llu", csid_hw->clk_rate); - - return 0; -} - -static int cam_ife_csid_dump_csid_clock( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - if (!csid_hw) - return -EINVAL; - - CAM_INFO(CAM_ISP, "CSID:%d clock rate %llu", - csid_hw->hw_intf->hw_idx, - csid_hw->clk_rate); - - return 0; -} - -static int cam_ife_csid_set_sensor_dimension( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - struct cam_ife_sensor_dimension_update_args *dimension_update = NULL; - uint32_t i; - - if (!csid_hw) - return -EINVAL; - - dimension_update = - (struct cam_ife_sensor_dimension_update_args *)cmd_args; - csid_hw->ipp_path_config.measure_enabled = - dimension_update->ipp_path.measure_enabled; - if (dimension_update->ipp_path.measure_enabled) { - csid_hw->ipp_path_config.width = - dimension_update->ipp_path.width; - csid_hw->ipp_path_config.height = - dimension_update->ipp_path.height; - CAM_DBG(CAM_ISP, "CSID ipp path width %d height %d", - csid_hw->ipp_path_config.width, - csid_hw->ipp_path_config.height); - } - csid_hw->ppp_path_config.measure_enabled = - dimension_update->ppp_path.measure_enabled; - if (dimension_update->ppp_path.measure_enabled) { - csid_hw->ppp_path_config.width = - dimension_update->ppp_path.width; - csid_hw->ppp_path_config.height = - dimension_update->ppp_path.height; - CAM_DBG(CAM_ISP, "CSID ppp path width %d height %d", - csid_hw->ppp_path_config.width, - csid_hw->ppp_path_config.height); - } - for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) { - csid_hw->rdi_path_config[i].measure_enabled - = dimension_update->rdi_path[i].measure_enabled; - if (csid_hw->rdi_path_config[i].measure_enabled) { - csid_hw->rdi_path_config[i].width = - dimension_update->rdi_path[i].width; - csid_hw->rdi_path_config[i].height = - dimension_update->rdi_path[i].height; - if (csid_hw->rdi_path_config[i].height == 1) - csid_hw->rdi_path_config[i].measure_enabled = 0; - CAM_DBG(CAM_ISP, - "CSID rdi path[%d] width %d height %d", - i, csid_hw->rdi_path_config[i].width, - csid_hw->rdi_path_config[i].height); - } - } - return 0; -} - -static int cam_ife_csid_set_csid_qcfa( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - struct cam_ife_csid_qcfa_update_args *qcfa_update = NULL; - - if (!csid_hw) - return -EINVAL; - - qcfa_update = - (struct cam_ife_csid_qcfa_update_args *)cmd_args; - - csid_hw->binning_supported = qcfa_update->qcfa_binning; - CAM_DBG(CAM_ISP, "CSID QCFA binning %d", csid_hw->binning_supported); - - return 0; -} - -static int cam_ife_csid_set_epd_config( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - struct cam_ife_csid_epd_update_args *epd_update = NULL; - - if ((!csid_hw) || (!cmd_args)) - return -EINVAL; - - epd_update = - (struct cam_ife_csid_epd_update_args *)cmd_args; - - csid_hw->epd_supported = epd_update->epd_supported; - CAM_DBG(CAM_ISP, "CSID EPD supported %d", csid_hw->epd_supported); - return 0; -} - -static int cam_ife_csid_dump_hw( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - int i; - uint8_t *dst; - uint32_t *addr, *start; - uint32_t min_len; - uint32_t num_reg; - size_t remain_len; - struct cam_isp_hw_dump_header *hdr; - struct cam_isp_hw_dump_args *dump_args = - (struct cam_isp_hw_dump_args *)cmd_args; - struct cam_hw_soc_info *soc_info; - - if (!dump_args) { - CAM_ERR(CAM_ISP, "Invalid args"); - return -EINVAL; - } - if (!dump_args->cpu_addr || !dump_args->buf_len) { - CAM_ERR(CAM_ISP, - "Invalid params %pK %zu", - (void *)dump_args->cpu_addr, - dump_args->buf_len); - return -EINVAL; - } - soc_info = &csid_hw->hw_info->soc_info; - if (dump_args->buf_len <= dump_args->offset) { - CAM_WARN(CAM_ISP, - "Dump offset overshoot offset %zu buf_len %zu", - dump_args->offset, dump_args->buf_len); - return -ENOSPC; - } - min_len = soc_info->reg_map[0].size + - sizeof(struct cam_isp_hw_dump_header) + - sizeof(uint32_t); - remain_len = dump_args->buf_len - dump_args->offset; - if (remain_len < min_len) { - CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu, min %u", - remain_len, min_len); - return -ENOSPC; - } - dst = (uint8_t *)dump_args->cpu_addr + dump_args->offset; - hdr = (struct cam_isp_hw_dump_header *)dst; - scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "CSID_REG:"); - addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); - - start = addr; - num_reg = soc_info->reg_map[0].size/4; - hdr->word_size = sizeof(uint32_t); - *addr = soc_info->index; - addr++; - for (i = 0; i < num_reg; i++) { - addr[0] = soc_info->mem_block[0]->start + (i*4); - addr[1] = cam_io_r(soc_info->reg_map[0].mem_base - + (i*4)); - addr += 2; - } - hdr->size = hdr->word_size * (addr - start); - dump_args->offset += hdr->size + - sizeof(struct cam_isp_hw_dump_header); - CAM_DBG(CAM_ISP, "offset %zu", dump_args->offset); - return 0; -} - -static int cam_ife_csid_log_acquire_data( - struct cam_ife_csid_hw *csid_hw, void *cmd_args) -{ - struct cam_isp_resource_node *res = - (struct cam_isp_resource_node *)cmd_args; - struct cam_ife_csid_path_cfg *path_data; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_reg_offset *csid_reg; - const struct cam_ife_csid_rdi_reg_offset *rdi_reg; - uint32_t byte_cnt_ping, byte_cnt_pong; - - path_data = (struct cam_ife_csid_path_cfg *)res->res_priv; - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - - if (res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) { - CAM_ERR(CAM_ISP, - "CSID:%d invalid res id:%d res type: %d state:%d", - csid_hw->hw_intf->hw_idx, res->res_id, res->res_type, - res->res_state); - return -EINVAL; - } - - /* Dump all the acquire data for this hardware */ - CAM_INFO(CAM_ISP, - "CSID:%d res id:%d type:%d state:%d in f:%d out f:%d st pix:%d end pix:%d st line:%d end line:%d h bin:%d qcfa bin:%d", - csid_hw->hw_intf->hw_idx, res->res_id, res->res_type, - res->res_type, path_data->in_format, path_data->out_format, - path_data->start_pixel, path_data->end_pixel, - path_data->start_line, path_data->end_line, - path_data->horizontal_bin, path_data->qcfa_bin); - - if (res->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0 && - res->res_id <= CAM_IFE_PIX_PATH_RES_RDI_3) { - rdi_reg = csid_reg->rdi_reg[res->res_id]; - /* read total number of bytes transmitted through RDI */ - byte_cnt_ping = cam_io_r_mb(soc_info->reg_map[0].mem_base + - rdi_reg->csid_rdi_byte_cntr_ping_addr); - byte_cnt_pong = cam_io_r_mb(soc_info->reg_map[0].mem_base + - rdi_reg->csid_rdi_byte_cntr_pong_addr); - CAM_INFO(CAM_ISP, - "CSID:%d res id:%d byte cnt val ping:%d pong:%d", - csid_hw->hw_intf->hw_idx, res->res_id, - byte_cnt_ping, byte_cnt_pong); - } - - return 0; -} - -static int cam_ife_csid_process_cmd(void *hw_priv, - uint32_t cmd_type, void *cmd_args, uint32_t arg_size) -{ - int rc = 0; - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_info *csid_hw_info; - struct cam_isp_resource_node *res = NULL; - - if (!hw_priv || !cmd_args) { - CAM_ERR(CAM_ISP, "CSID: Invalid arguments"); - return -EINVAL; - } - - csid_hw_info = (struct cam_hw_info *)hw_priv; - csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; - - switch (cmd_type) { - case CAM_IFE_CSID_CMD_GET_TIME_STAMP: - rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args); - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_HBI_VBI_INFO) { - res = ((struct cam_csid_get_time_stamp_args *) - cmd_args)->node_res; - cam_ife_csid_get_hbi_vbi(csid_hw, res); - } - break; - case CAM_IFE_CSID_SET_CSID_DEBUG: - rc = cam_ife_csid_set_csid_debug(csid_hw, cmd_args); - break; - case CAM_IFE_CSID_SOF_IRQ_DEBUG: - rc = cam_ife_csid_sof_irq_debug(csid_hw, cmd_args); - break; - case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE: - rc = cam_ife_csid_set_csid_clock(csid_hw, cmd_args); - break; - case CAM_ISP_HW_CMD_CSID_CLOCK_DUMP: - rc = cam_ife_csid_dump_csid_clock(csid_hw, cmd_args); - break; - case CAM_ISP_HW_CMD_CSID_QCFA_SUPPORTED: - rc = cam_ife_csid_set_csid_qcfa(csid_hw, cmd_args); - break; - case CAM_IFE_CSID_SET_CONFIG: - rc = cam_ife_csid_set_epd_config(csid_hw, cmd_args); - break; - case CAM_ISP_HW_CMD_DUMP_HW: - rc = cam_ife_csid_dump_hw(csid_hw, cmd_args); - break; - case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG: - rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args); - break; - case CAM_IFE_CSID_LOG_ACQUIRE_DATA: - rc = cam_ife_csid_log_acquire_data(csid_hw, cmd_args); - break; - case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE: - rc = cam_ife_csid_halt(csid_hw, cmd_args); - break; - default: - CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", - csid_hw->hw_intf->hw_idx, cmd_type); - rc = -EINVAL; - break; - } - - return rc; - -} - -static int cam_csid_get_evt_payload( - struct cam_ife_csid_hw *csid_hw, - struct cam_csid_evt_payload **evt_payload) -{ - - spin_lock(&csid_hw->lock_state); - - if (list_empty(&csid_hw->free_payload_list)) { - *evt_payload = NULL; - spin_unlock(&csid_hw->lock_state); - CAM_ERR_RATE_LIMIT(CAM_ISP, "No free payload core %d", - csid_hw->hw_intf->hw_idx); - return -ENOMEM; - } - - *evt_payload = list_first_entry(&csid_hw->free_payload_list, - struct cam_csid_evt_payload, list); - list_del_init(&(*evt_payload)->list); - spin_unlock(&csid_hw->lock_state); - - return 0; -} - -static int cam_csid_put_evt_payload( - struct cam_ife_csid_hw *csid_hw, - struct cam_csid_evt_payload **evt_payload) -{ - unsigned long flags; - - if (*evt_payload == NULL) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid payload core %d", - csid_hw->hw_intf->hw_idx); - return -EINVAL; - } - spin_lock_irqsave(&csid_hw->lock_state, flags); - list_add_tail(&(*evt_payload)->list, - &csid_hw->free_payload_list); - *evt_payload = NULL; - spin_unlock_irqrestore(&csid_hw->lock_state, flags); - - return 0; -} - -static int cam_csid_evt_bottom_half_handler( - void *handler_priv, - void *evt_payload_priv) -{ - struct cam_ife_csid_hw *csid_hw; - struct cam_csid_evt_payload *evt_payload; - int i; - int rc = 0; - struct cam_isp_hw_event_info event_info; - const struct cam_ife_csid_reg_offset *csid_reg; - int udi_start_idx = CAM_IFE_CSID_IRQ_REG_UDI_0; - - if (!handler_priv || !evt_payload_priv) { - CAM_ERR(CAM_ISP, - "Invalid Param handler_priv %pK evt_payload_priv %pK", - handler_priv, evt_payload_priv); - return 0; - } - - csid_hw = (struct cam_ife_csid_hw *)handler_priv; - evt_payload = (struct cam_csid_evt_payload *)evt_payload_priv; - csid_reg = csid_hw->csid_info->csid_reg; - - if (!csid_hw->event_cb || !csid_hw->priv) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "hw_idx %d Invalid args %pK %pK", - csid_hw->hw_intf->hw_idx, - csid_hw->event_cb, - csid_hw->priv); - goto end; - } - - if (csid_hw->priv != evt_payload->priv) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "hw_idx %d priv mismatch %pK, %pK", - csid_hw->hw_intf->hw_idx, - csid_hw->priv, - evt_payload->priv); - goto end; - } - - if (csid_hw->sof_irq_triggered && (evt_payload->evt_type == - CAM_ISP_HW_ERROR_NONE)) { - if (evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_INFO_INPUT_SOF) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP SOF received", - csid_hw->hw_intf->hw_idx); - } - - if (evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_INFO_INPUT_SOF) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PPP SOF received", - csid_hw->hw_intf->hw_idx); - } - - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { - if (evt_payload->irq_status[i] & - CSID_PATH_INFO_INPUT_SOF) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d RDI:%d SOF received", - csid_hw->hw_intf->hw_idx, i); - } - - for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { - if (evt_payload->irq_status[udi_start_idx + i] & - CSID_PATH_INFO_INPUT_SOF) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d UDI:%d SOF received", - csid_hw->hw_intf->hw_idx, i); - } - } else { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID %d err %d phy %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x PPP: 0x%x RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x RDI3: 0x%x UDI0: 0x%x UDI1: 0x%x UDI2: 0x%x", - csid_hw->hw_intf->hw_idx, - evt_payload->evt_type, - csid_hw->csi2_rx_cfg.phy_sel, - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_TOP], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RX], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_IPP], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_PPP], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RDI_0], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RDI_1], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RDI_2], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RDI_3], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_UDI_1], - evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_UDI_2]); - } - - if (evt_payload->evt_type == CAM_ISP_HW_ERROR_CSID_FATAL) - cam_subdev_notify_message(CAM_CSIPHY_DEVICE_TYPE, - CAM_SUBDEV_MESSAGE_IRQ_ERR, - csid_hw->csi2_rx_cfg.phy_sel); - - /* this hunk can be extended to handle more cases - * which we want to offload to bottom half from - * irq handlers - */ - event_info.err_type = evt_payload->evt_type; - event_info.hw_idx = evt_payload->hw_idx; - - switch (evt_payload->evt_type) { - case CAM_ISP_HW_ERROR_CSID_FATAL: - if (csid_hw->fatal_err_detected) - break; - csid_hw->fatal_err_detected = true; - rc = csid_hw->event_cb(NULL, - CAM_ISP_HW_EVENT_ERROR, (void *)&event_info); - break; - - default: - CAM_DBG(CAM_ISP, "CSID[%d] error type %d", - csid_hw->hw_intf->hw_idx, - evt_payload->evt_type); - break; - } -end: - cam_csid_put_evt_payload(csid_hw, &evt_payload); - return 0; -} - -static int cam_csid_handle_hw_err_irq( - struct cam_ife_csid_hw *csid_hw, - int evt_type, - uint32_t *irq_status) -{ - int rc = 0; - int i; - void *bh_cmd = NULL; - struct cam_csid_evt_payload *evt_payload; - - CAM_DBG(CAM_ISP, "CSID[%d] error %d", - csid_hw->hw_intf->hw_idx, evt_type); - - rc = cam_csid_get_evt_payload(csid_hw, &evt_payload); - if (rc) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "No free payload core %d", - csid_hw->hw_intf->hw_idx); - return rc; - } - - rc = tasklet_bh_api.get_bh_payload_func(csid_hw->tasklet, &bh_cmd); - if (rc || !bh_cmd) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID[%d] Can not get cmd for tasklet, evt_type %d", - csid_hw->hw_intf->hw_idx, - evt_type); - cam_csid_put_evt_payload(csid_hw, &evt_payload); - return rc; - } - - evt_payload->evt_type = evt_type; - evt_payload->priv = csid_hw->priv; - evt_payload->hw_idx = csid_hw->hw_intf->hw_idx; - - for (i = 0; i < CAM_IFE_CSID_IRQ_REG_MAX; i++) - evt_payload->irq_status[i] = irq_status[i]; - - tasklet_bh_api.bottom_half_enqueue_func(csid_hw->tasklet, - bh_cmd, - csid_hw, - evt_payload, - cam_csid_evt_bottom_half_handler); - - return rc; -} - -irqreturn_t cam_ife_csid_irq(int irq_num, void *data) -{ - struct cam_ife_csid_hw *csid_hw; - struct cam_hw_soc_info *soc_info; - const struct cam_ife_csid_reg_offset *csid_reg; - const struct cam_ife_csid_csi2_rx_reg_offset *csi2_reg; - uint32_t irq_status[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; - uint32_t i, val, val2; - bool fatal_err_detected = false; - uint32_t sof_irq_debug_en = 0, log_en = 0; - unsigned long flags; - - csid_hw = (struct cam_ife_csid_hw *)data; - - CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx); - - if (!data) { - CAM_ERR(CAM_ISP, "CSID: Invalid arguments"); - return IRQ_HANDLED; - } - - csid_reg = csid_hw->csid_info->csid_reg; - soc_info = &csid_hw->hw_info->soc_info; - csi2_reg = csid_reg->csi2_reg; - - /* read */ - irq_status[CAM_IFE_CSID_IRQ_REG_TOP] = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_status_addr); - - irq_status[CAM_IFE_CSID_IRQ_REG_RX] = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_status_addr); - - if (csid_reg->cmn_reg->num_pix) - irq_status[CAM_IFE_CSID_IRQ_REG_IPP] = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_status_addr); - - if (csid_reg->cmn_reg->num_ppp) - irq_status[CAM_IFE_CSID_IRQ_REG_PPP] = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_irq_status_addr); - - if (csid_reg->cmn_reg->num_rdis <= CAM_IFE_CSID_RDI_MAX) { - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { - irq_status[i] = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr); - } - } - - if (csid_reg->cmn_reg->num_udis <= CAM_IFE_CSID_UDI_MAX) { - for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { - irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] = - cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[i]->csid_udi_irq_status_addr); - } - } - - spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); - /* clear */ - cam_io_w_mb(irq_status[CAM_IFE_CSID_IRQ_REG_TOP], - soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_top_irq_clear_addr); - - cam_io_w_mb(irq_status[CAM_IFE_CSID_IRQ_REG_RX], - soc_info->reg_map[0].mem_base + - csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr); - if (csid_reg->cmn_reg->num_pix) - cam_io_w_mb(irq_status[CAM_IFE_CSID_IRQ_REG_IPP], - soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_irq_clear_addr); - - if (csid_reg->cmn_reg->num_ppp) - cam_io_w_mb(irq_status[CAM_IFE_CSID_IRQ_REG_PPP], - soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_irq_clear_addr); - - if (csid_reg->cmn_reg->num_rdis <= CAM_IFE_CSID_RDI_MAX) { - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { - cam_io_w_mb(irq_status[i], - soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr); - } - } - - if (csid_reg->cmn_reg->num_udis <= CAM_IFE_CSID_UDI_MAX) { - for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { - cam_io_w_mb(irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i], - soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[i]->csid_udi_irq_clear_addr); - } - } - - cam_io_w_mb(1, soc_info->reg_map[0].mem_base + - csid_reg->cmn_reg->csid_irq_cmd_addr); - - spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); - - CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", - irq_status[CAM_IFE_CSID_IRQ_REG_TOP]); - CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", - irq_status[CAM_IFE_CSID_IRQ_REG_RX]); - CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", - irq_status[CAM_IFE_CSID_IRQ_REG_IPP]); - CAM_DBG(CAM_ISP, "irq_status_ppp = 0x%x", - irq_status[CAM_IFE_CSID_IRQ_REG_PPP]); - CAM_DBG(CAM_ISP, - "irq_status_rdi0= 0x%x irq_status_rdi1= 0x%x irq_status_rdi2= 0x%x", - irq_status[0], irq_status[1], irq_status[2]); - CAM_DBG(CAM_ISP, - "irq_status_udi0= 0x%x irq_status_udi1= 0x%x irq_status_udi2= 0x%x", - irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0], - irq_status[CAM_IFE_CSID_IRQ_REG_UDI_1], - irq_status[CAM_IFE_CSID_IRQ_REG_UDI_2]); - - if (irq_status[CAM_IFE_CSID_IRQ_REG_TOP] & CSID_TOP_IRQ_DONE) { - CAM_DBG(CAM_ISP, "csid top reset complete"); - complete(&csid_hw->csid_top_complete); - csid_hw->is_resetting = false; - return IRQ_HANDLED; - } - - if (csid_hw->is_resetting) { - CAM_DBG(CAM_ISP, "CSID:%d is resetting, IRQ Handling exit", - csid_hw->hw_intf->hw_idx); - return IRQ_HANDLED; - } - - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "csi rx reset complete"); - complete(&csid_hw->csid_csi2_complete); - } - - spin_lock_irqsave(&csid_hw->lock_state, flags); - if (csid_hw->device_enabled == 1) { - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow", - csid_hw->hw_intf->hw_idx); - fatal_err_detected = true; - goto handle_fatal_error; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow", - csid_hw->hw_intf->hw_idx); - fatal_err_detected = true; - goto handle_fatal_error; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow", - csid_hw->hw_intf->hw_idx); - fatal_err_detected = true; - goto handle_fatal_error; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow", - csid_hw->hw_intf->hw_idx); - fatal_err_detected = true; - goto handle_fatal_error; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW", - csid_hw->hw_intf->hw_idx); - fatal_err_detected = true; - goto handle_fatal_error; - } - if ((irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) && - (!csid_hw->epd_supported)) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d CPHY_EOT_RECEPTION", - csid_hw->hw_intf->hw_idx); - csid_hw->error_irq_count++; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d CPHY_SOT_RECEPTION", - csid_hw->hw_intf->hw_idx); - csid_hw->error_irq_count++; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_CPHY_PH_CRC) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC", - csid_hw->hw_intf->hw_idx); - csid_hw->error_irq_count++; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_CRC) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC", - csid_hw->hw_intf->hw_idx); - csid_hw->error_irq_count++; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_ECC) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC", - csid_hw->hw_intf->hw_idx); - csid_hw->error_irq_count++; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT", - csid_hw->hw_intf->hw_idx); - } - if ((irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT) && - (csid_hw->csid_debug & - CSID_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ)) { - - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csi2_reg->csid_csi2_rx_captured_long_pkt_0_addr); - - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d UNMAPPED_VC_DT. VC: %d DT: %d WC: %d", - csid_hw->hw_intf->hw_idx, (val >> 22), - ((val >> 16) & 0x3F), (val & 0xFFFF)); - csid_hw->error_irq_count++; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d ERROR_STREAM_UNDERFLOW", - csid_hw->hw_intf->hw_idx); - csid_hw->error_irq_count++; - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) { - CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME", - csid_hw->hw_intf->hw_idx); - csid_hw->error_irq_count++; - } - } - -handle_fatal_error: - spin_unlock_irqrestore(&csid_hw->lock_state, flags); - - if (csid_hw->error_irq_count > - CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT) { - fatal_err_detected = true; - csid_hw->error_irq_count = 0; - } - - if (fatal_err_detected) { - cam_ife_csid_halt_csi2(csid_hw); - cam_csid_handle_hw_err_irq(csid_hw, - CAM_ISP_HW_ERROR_CSID_FATAL, irq_status); - } - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) { - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL0_EOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL1_EOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL2_EOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL3_EOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - } - - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ) { - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL0_SOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL1_SOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL2_SOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - if (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED) { - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PHY_DL3_SOT_CAPTURED", - csid_hw->hw_intf->hw_idx); - } - } - - if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) && - (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED)) { - - CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d LONG_PKT_CAPTURED", - csid_hw->hw_intf->hw_idx); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csi2_reg->csid_csi2_rx_captured_long_pkt_0_addr); - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d long packet VC :%d DT:%d WC:%d", - csid_hw->hw_intf->hw_idx, - (val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF)); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csi2_reg->csid_csi2_rx_captured_long_pkt_1_addr); - CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d long packet ECC :%d", - csid_hw->hw_intf->hw_idx, val); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csi2_reg->csid_csi2_rx_captured_long_pkt_ftr_addr); - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d long pkt cal CRC:%d expected CRC:%d", - csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF)); - } - if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) && - (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED)) { - - CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d SHORT_PKT_CAPTURED", - csid_hw->hw_intf->hw_idx); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csi2_reg->csid_csi2_rx_captured_short_pkt_0_addr); - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d short pkt VC :%d DT:%d LC:%d", - csid_hw->hw_intf->hw_idx, - (val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF)); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csi2_reg->csid_csi2_rx_captured_short_pkt_1_addr); - CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d short packet ECC :%d", - csid_hw->hw_intf->hw_idx, val); - } - - if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) && - (irq_status[CAM_IFE_CSID_IRQ_REG_RX] & - CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED)) { - CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PKT_HDR_CAPTURED", - csid_hw->hw_intf->hw_idx); - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csi2_reg->csid_csi2_rx_captured_cphy_pkt_hdr_addr); - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d cphy packet VC :%d DT:%d WC:%d", - csid_hw->hw_intf->hw_idx, - (val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF)); - } - - /*read the IPP errors */ - if (csid_reg->cmn_reg->num_pix) { - /* IPP reset done bit */ - if (irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "CSID:%d IPP reset complete", - csid_hw->hw_intf->hw_idx); - complete(&csid_hw->csid_ipp_complete); - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_INFO_INPUT_SOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)) { - if (!csid_hw->sof_irq_triggered) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP SOF received", - csid_hw->hw_intf->hw_idx); - else - log_en = 1; - - if (csid_hw->sof_irq_triggered) - csid_hw->irq_debug_cnt++; - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_INFO_INPUT_EOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) - CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received", - csid_hw->hw_intf->hw_idx); - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_ERROR_CCIF_VIOLATION)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP CCIF violation", - csid_hw->hw_intf->hw_idx); - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_OVERFLOW_RECOVERY)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP Overflow due to back pressure", - csid_hw->hw_intf->hw_idx); - - if (irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_ERROR_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP fifo over flow", - csid_hw->hw_intf->hw_idx); - /* Stop IPP path immediately */ - cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, - soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_ctrl_addr); - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_ERROR_PIX_COUNT) || - (irq_status[CAM_IFE_CSID_IRQ_REG_IPP] & - CSID_PATH_ERROR_LINE_COUNT)) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_format_measure0_addr); - val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ipp_reg->csid_pxl_format_measure_cfg1_addr - ); - - CAM_ERR(CAM_ISP, - "CSID:%d irq_status_ipp:0x%x", - csid_hw->hw_intf->hw_idx, - irq_status[CAM_IFE_CSID_IRQ_REG_IPP]); - CAM_ERR(CAM_ISP, - "Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x [format_measure0: 0x%x]", - ((val2 >> - csid_reg->cmn_reg->format_measure_height_shift_val) & - csid_reg->cmn_reg->format_measure_height_mask_val), - val2 & - csid_reg->cmn_reg->format_measure_width_mask_val, - ((val >> - csid_reg->cmn_reg->format_measure_height_shift_val) & - csid_reg->cmn_reg->format_measure_height_mask_val), - val & - csid_reg->cmn_reg->format_measure_width_mask_val, - val); - } - } - - /*read PPP errors */ - if (csid_reg->cmn_reg->num_ppp) { - /* PPP reset done bit */ - if (irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "CSID:%d PPP reset complete", - csid_hw->hw_intf->hw_idx); - complete(&csid_hw->csid_ppp_complete); - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_INFO_INPUT_SOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)) { - if (!csid_hw->sof_irq_triggered) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP SOF received", - csid_hw->hw_intf->hw_idx); - else - log_en = 1; - - if (csid_hw->sof_irq_triggered) - csid_hw->irq_debug_cnt++; - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_INFO_INPUT_EOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) - CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received", - csid_hw->hw_intf->hw_idx); - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_ERROR_CCIF_VIOLATION)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d PPP CCIF violation", - csid_hw->hw_intf->hw_idx); - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_OVERFLOW_RECOVERY)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d IPP Overflow due to back pressure", - csid_hw->hw_intf->hw_idx); - - if (irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_ERROR_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d PPP fifo over flow", - csid_hw->hw_intf->hw_idx); - /* Stop PPP path immediately */ - cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, - soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_ctrl_addr); - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_ERROR_PIX_COUNT) || - (irq_status[CAM_IFE_CSID_IRQ_REG_PPP] & - CSID_PATH_ERROR_LINE_COUNT)) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_format_measure0_addr); - val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->ppp_reg->csid_pxl_format_measure_cfg1_addr - ); - - CAM_ERR(CAM_ISP, - "CSID:%d irq_status_ppp:0x%x", - csid_hw->hw_intf->hw_idx, - irq_status[CAM_IFE_CSID_IRQ_REG_PPP]); - CAM_ERR(CAM_ISP, - "Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x [format_measure0: 0x%x]", - ((val2 >> - csid_reg->cmn_reg->format_measure_height_shift_val) & - csid_reg->cmn_reg->format_measure_height_mask_val), - val2 & - csid_reg->cmn_reg->format_measure_width_mask_val, - ((val >> - csid_reg->cmn_reg->format_measure_height_shift_val) & - csid_reg->cmn_reg->format_measure_height_mask_val), - val & - csid_reg->cmn_reg->format_measure_width_mask_val, - val); - } - } - - for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { - if (irq_status[i] & - BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "CSID:%d RDI%d reset complete", - csid_hw->hw_intf->hw_idx, i); - complete(&csid_hw->csid_rdin_complete[i]); - } - - if ((irq_status[i] & CSID_PATH_INFO_INPUT_SOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)) { - if (!csid_hw->sof_irq_triggered) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d RDI:%d SOF received", - csid_hw->hw_intf->hw_idx, i); - else - log_en = 1; - - if (csid_hw->sof_irq_triggered) - csid_hw->irq_debug_cnt++; - } - - if ((irq_status[i] & CSID_PATH_INFO_INPUT_EOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d RDI:%d EOF received", - csid_hw->hw_intf->hw_idx, i); - - if ((irq_status[i] & CSID_PATH_ERROR_CCIF_VIOLATION)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d RDI :%d CCIF violation", - csid_hw->hw_intf->hw_idx, i); - - if ((irq_status[i] & CSID_PATH_OVERFLOW_RECOVERY)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d RDI :%d Overflow due to back pressure", - csid_hw->hw_intf->hw_idx, i); - - if (irq_status[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d RDI fifo over flow", - csid_hw->hw_intf->hw_idx); - /* Stop RDI path immediately */ - cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, - soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr); - } - - if ((irq_status[i] & CSID_PATH_ERROR_PIX_COUNT) || - (irq_status[i] & CSID_PATH_ERROR_LINE_COUNT)) { - val = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_format_measure0_addr); - val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[i]->csid_rdi_format_measure_cfg1_addr - ); - CAM_ERR(CAM_ISP, - "CSID:%d irq_status_rdi[%d]:0x%x", - csid_hw->hw_intf->hw_idx, i, irq_status[i]); - CAM_ERR(CAM_ISP, - "Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x [format_measure0: 0x%x]", - ((val2 >> - csid_reg->cmn_reg->format_measure_height_shift_val) & - csid_reg->cmn_reg->format_measure_height_mask_val), - val2 & - csid_reg->cmn_reg->format_measure_width_mask_val, - ((val >> - csid_reg->cmn_reg->format_measure_height_shift_val) & - csid_reg->cmn_reg->format_measure_height_mask_val), - val & - csid_reg->cmn_reg->format_measure_width_mask_val, - val); - } - } - - for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { - if (irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] & - BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { - CAM_DBG(CAM_ISP, "CSID:%d UDI%d reset complete", - csid_hw->hw_intf->hw_idx, i); - complete(&csid_hw->csid_udin_complete[i]); - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] & - CSID_PATH_INFO_INPUT_SOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)) { - if (!csid_hw->sof_irq_triggered) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d UDI:%d SOF received", - csid_hw->hw_intf->hw_idx, i); - else - log_en = 1; - - if (csid_hw->sof_irq_triggered) - csid_hw->irq_debug_cnt++; - } - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] & - CSID_PATH_INFO_INPUT_EOF) && - (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) - CAM_INFO_RATE_LIMIT(CAM_ISP, - "CSID:%d UDI:%d EOF received", - csid_hw->hw_intf->hw_idx, i); - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] & - CSID_PATH_ERROR_CCIF_VIOLATION)) - CAM_WARN_RATE_LIMIT(CAM_ISP, - "CSID:%d UDI :%d CCIF violation", - csid_hw->hw_intf->hw_idx, i); - - if ((irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] & - CSID_PATH_OVERFLOW_RECOVERY)) - CAM_WARN_RATE_LIMIT(CAM_ISP, - "CSID:%d UDI :%d Overflow due to back pressure", - csid_hw->hw_intf->hw_idx, i); - - if (irq_status[CAM_IFE_CSID_IRQ_REG_UDI_0 + i] & - CSID_PATH_ERROR_FIFO_OVERFLOW) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID:%d UDI fifo over flow", - csid_hw->hw_intf->hw_idx); - /* Stop UDI path immediately */ - cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, - soc_info->reg_map[0].mem_base + - csid_reg->udi_reg[i]->csid_udi_ctrl_addr); - } - } - - if (log_en) - cam_csid_handle_hw_err_irq(csid_hw, - CAM_ISP_HW_ERROR_NONE, irq_status); - - if (csid_hw->irq_debug_cnt >= CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) { - cam_ife_csid_sof_irq_debug(csid_hw, &sof_irq_debug_en); - csid_hw->irq_debug_cnt = 0; - } - - CAM_DBG(CAM_ISP, "IRQ Handling exit"); - return IRQ_HANDLED; -} - -int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, - uint32_t csid_idx, bool is_custom) -{ - int rc = -EINVAL; - uint32_t i; - uint32_t num_paths; - struct cam_ife_csid_path_cfg *path_data; - struct cam_ife_csid_cid_data *cid_data; - struct cam_hw_info *csid_hw_info; - struct cam_ife_csid_hw *ife_csid_hw = NULL; - - if (csid_idx >= CAM_IFE_CSID_HW_NUM_MAX) { - CAM_ERR(CAM_ISP, "Invalid csid index:%d", csid_idx); - return rc; - } - - csid_hw_info = (struct cam_hw_info *) csid_hw_intf->hw_priv; - ife_csid_hw = (struct cam_ife_csid_hw *) csid_hw_info->core_info; - - ife_csid_hw->hw_intf = csid_hw_intf; - ife_csid_hw->hw_info = csid_hw_info; - - CAM_DBG(CAM_ISP, "type %d index %d", - ife_csid_hw->hw_intf->hw_type, csid_idx); - - - ife_csid_hw->device_enabled = 0; - ife_csid_hw->is_resetting = false; - ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; - mutex_init(&ife_csid_hw->hw_info->hw_mutex); - spin_lock_init(&ife_csid_hw->hw_info->hw_lock); - spin_lock_init(&ife_csid_hw->lock_state); - init_completion(&ife_csid_hw->hw_info->hw_complete); - - init_completion(&ife_csid_hw->csid_top_complete); - init_completion(&ife_csid_hw->csid_csi2_complete); - init_completion(&ife_csid_hw->csid_ipp_complete); - init_completion(&ife_csid_hw->csid_ppp_complete); - for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++) - init_completion(&ife_csid_hw->csid_rdin_complete[i]); - - for (i = 0; i < CAM_IFE_CSID_UDI_MAX; i++) - init_completion(&ife_csid_hw->csid_udin_complete[i]); - - rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info, - cam_ife_csid_irq, ife_csid_hw, is_custom); - if (rc < 0) { - CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", csid_idx); - goto err; - } - - if (cam_cpas_is_feature_supported(CAM_CPAS_QCFA_BINNING_ENABLE, - CAM_CPAS_HW_IDX_ANY, NULL)) - ife_csid_hw->binning_enable = 1; - - ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps; - ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_init_hw; - ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_deinit_hw; - ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_reset; - ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_reserve; - ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_release; - ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_start; - ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_stop; - ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_read; - ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_write; - ife_csid_hw->hw_intf->hw_ops.process_cmd = cam_ife_csid_process_cmd; - - num_paths = ife_csid_hw->csid_info->csid_reg->cmn_reg->num_pix + - ife_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis + - ife_csid_hw->csid_info->csid_reg->cmn_reg->num_udis; - - /* Initialize the CID resource */ - for (i = 0; i < num_paths; i++) { - ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID; - ife_csid_hw->cid_res[i].res_id = i; - ife_csid_hw->cid_res[i].res_state = - CAM_ISP_RESOURCE_STATE_AVAILABLE; - ife_csid_hw->cid_res[i].hw_intf = ife_csid_hw->hw_intf; - - cid_data = kzalloc(sizeof(struct cam_ife_csid_cid_data), - GFP_KERNEL); - if (!cid_data) { - rc = -ENOMEM; - goto err; - } - ife_csid_hw->cid_res[i].res_priv = cid_data; - } - - /* Initialize the IPP resources */ - if (ife_csid_hw->csid_info->csid_reg->cmn_reg->num_pix) { - ife_csid_hw->ipp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH; - ife_csid_hw->ipp_res.res_id = CAM_IFE_PIX_PATH_RES_IPP; - ife_csid_hw->ipp_res.res_state = - CAM_ISP_RESOURCE_STATE_AVAILABLE; - ife_csid_hw->ipp_res.hw_intf = ife_csid_hw->hw_intf; - path_data = kzalloc(sizeof(*path_data), - GFP_KERNEL); - if (!path_data) { - rc = -ENOMEM; - goto err; - } - ife_csid_hw->ipp_res.res_priv = path_data; - } - - /* Initialize PPP resource */ - if (ife_csid_hw->csid_info->csid_reg->cmn_reg->num_ppp) { - ife_csid_hw->ppp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH; - ife_csid_hw->ppp_res.res_id = CAM_IFE_PIX_PATH_RES_PPP; - ife_csid_hw->ppp_res.res_state = - CAM_ISP_RESOURCE_STATE_AVAILABLE; - ife_csid_hw->ppp_res.hw_intf = ife_csid_hw->hw_intf; - path_data = kzalloc(sizeof(*path_data), - GFP_KERNEL); - if (!path_data) { - rc = -ENOMEM; - goto err; - } - ife_csid_hw->ppp_res.res_priv = path_data; - } - - /* Initialize the RDI resource */ - for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; - i++) { - /* res type is from RDI 0 to RDI3 */ - ife_csid_hw->rdi_res[i].res_type = - CAM_ISP_RESOURCE_PIX_PATH; - ife_csid_hw->rdi_res[i].res_id = i; - ife_csid_hw->rdi_res[i].res_state = - CAM_ISP_RESOURCE_STATE_AVAILABLE; - ife_csid_hw->rdi_res[i].hw_intf = ife_csid_hw->hw_intf; - - path_data = kzalloc(sizeof(*path_data), - GFP_KERNEL); - if (!path_data) { - rc = -ENOMEM; - goto err; - } - ife_csid_hw->rdi_res[i].res_priv = path_data; - } - - /* Initialize the UDI resource */ - for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->num_udis; - i++) { - /* res type is from UDI0 to UDI3 */ - ife_csid_hw->udi_res[i].res_type = - CAM_ISP_RESOURCE_PIX_PATH; - ife_csid_hw->udi_res[i].res_id = i + - CAM_IFE_PIX_PATH_RES_UDI_0; - ife_csid_hw->udi_res[i].res_state = - CAM_ISP_RESOURCE_STATE_AVAILABLE; - ife_csid_hw->udi_res[i].hw_intf = ife_csid_hw->hw_intf; - - path_data = kzalloc(sizeof(*path_data), - GFP_KERNEL); - if (!path_data) { - rc = -ENOMEM; - goto err; - } - ife_csid_hw->udi_res[i].res_priv = path_data; - } - - rc = cam_tasklet_init(&ife_csid_hw->tasklet, ife_csid_hw, csid_idx); - if (rc) { - CAM_ERR(CAM_ISP, "Unable to create CSID tasklet rc %d", rc); - goto err; - } - - INIT_LIST_HEAD(&ife_csid_hw->free_payload_list); - for (i = 0; i < CAM_CSID_EVT_PAYLOAD_MAX; i++) { - INIT_LIST_HEAD(&ife_csid_hw->evt_payload[i].list); - list_add_tail(&ife_csid_hw->evt_payload[i].list, - &ife_csid_hw->free_payload_list); - } - - ife_csid_hw->csid_debug = 0; - ife_csid_hw->error_irq_count = 0; - ife_csid_hw->ipp_path_config.measure_enabled = 0; - ife_csid_hw->ppp_path_config.measure_enabled = 0; - ife_csid_hw->epd_supported = 0; - for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) - ife_csid_hw->rdi_path_config[i].measure_enabled = 0; - - return 0; -err: - if (rc) { - kfree(ife_csid_hw->ipp_res.res_priv); - kfree(ife_csid_hw->ppp_res.res_priv); - for (i = 0; i < - ife_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; - i++) - kfree(ife_csid_hw->rdi_res[i].res_priv); - - for (i = 0; i < - ife_csid_hw->csid_info->csid_reg->cmn_reg->num_udis; - i++) - kfree(ife_csid_hw->udi_res[i].res_priv); - - for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) - kfree(ife_csid_hw->cid_res[i].res_priv); - - } - - return rc; -} -EXPORT_SYMBOL(cam_ife_csid_hw_probe_init); - -int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw) -{ - int rc = -EINVAL; - uint32_t i; - - if (!ife_csid_hw) { - CAM_ERR(CAM_ISP, "Invalid param"); - return rc; - } - - /* release the privdate data memory from resources */ - kfree(ife_csid_hw->ipp_res.res_priv); - kfree(ife_csid_hw->ppp_res.res_priv); - for (i = 0; i < - ife_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; - i++) { - kfree(ife_csid_hw->rdi_res[i].res_priv); - } - for (i = 0; i < - ife_csid_hw->csid_info->csid_reg->cmn_reg->num_udis; - i++) { - kfree(ife_csid_hw->udi_res[i].res_priv); - } - for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) - kfree(ife_csid_hw->cid_res[i].res_priv); - - cam_ife_csid_deinit_soc_resources(&ife_csid_hw->hw_info->soc_info); - - return 0; -} -EXPORT_SYMBOL(cam_ife_csid_hw_deinit); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h deleted file mode 100644 index 55d2356606..0000000000 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ /dev/null @@ -1,675 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - */ - -#ifndef _CAM_IFE_CSID_HW_H_ -#define _CAM_IFE_CSID_HW_H_ - -#include "cam_hw.h" -#include "cam_ife_csid_hw_intf.h" -#include "cam_ife_csid_soc.h" -#include "cam_ife_csid_core.h" - -#define CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED BIT(0) -#define CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED BIT(1) -#define CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED BIT(2) -#define CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED BIT(3) -#define CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED BIT(4) -#define CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED BIT(5) -#define CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED BIT(6) -#define CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED BIT(7) -#define CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED BIT(8) -#define CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED BIT(9) -#define CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED BIT(10) -#define CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION BIT(11) -#define CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION BIT(12) -#define CSID_CSI2_RX_ERROR_CPHY_PH_CRC BIT(13) -#define CSID_CSI2_RX_WARNING_ECC BIT(14) -#define CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW BIT(15) -#define CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW BIT(16) -#define CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW BIT(17) -#define CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW BIT(18) -#define CSID_CSI2_RX_ERROR_CRC BIT(19) -#define CSID_CSI2_RX_ERROR_ECC BIT(20) -#define CSID_CSI2_RX_ERROR_MMAPPED_VC_DT BIT(21) -#define CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT BIT(22) -#define CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW BIT(23) -#define CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME BIT(24) -#define CSID_CSI2_RX_INFO_TG_DONE BIT(25) -#define CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW BIT(26) -#define CSID_CSI2_RX_INFO_RST_DONE BIT(27) - -#define CSID_TOP_IRQ_DONE BIT(0) -#define CSID_PATH_INFO_RST_DONE BIT(1) -#define CSID_PATH_ERROR_FIFO_OVERFLOW BIT(2) -#define CSID_PATH_INFO_SUBSAMPLED_EOF BIT(3) -#define CSID_PATH_INFO_SUBSAMPLED_SOF BIT(4) -#define CSID_PATH_INFO_FRAME_DROP_EOF BIT(5) -#define CSID_PATH_INFO_FRAME_DROP_EOL BIT(6) -#define CSID_PATH_INFO_FRAME_DROP_SOL BIT(7) -#define CSID_PATH_INFO_FRAME_DROP_SOF BIT(8) -#define CSID_PATH_INFO_INPUT_EOF BIT(9) -#define CSID_PATH_INFO_INPUT_EOL BIT(10) -#define CSID_PATH_INFO_INPUT_SOL BIT(11) -#define CSID_PATH_INFO_INPUT_SOF BIT(12) -#define CSID_PATH_ERROR_PIX_COUNT BIT(13) -#define CSID_PATH_ERROR_LINE_COUNT BIT(14) -#define CSID_PATH_ERROR_CCIF_VIOLATION BIT(15) -#define CSID_PATH_OVERFLOW_RECOVERY BIT(17) - -/* - * Debug values enable the corresponding interrupts and debug logs provide - * necessary information - */ -#define CSID_DEBUG_ENABLE_SOF_IRQ BIT(0) -#define CSID_DEBUG_ENABLE_EOF_IRQ BIT(1) -#define CSID_DEBUG_ENABLE_SOT_IRQ BIT(2) -#define CSID_DEBUG_ENABLE_EOT_IRQ BIT(3) -#define CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE BIT(4) -#define CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE BIT(5) -#define CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE BIT(6) -#define CSID_DEBUG_ENABLE_HBI_VBI_INFO BIT(7) -#define CSID_DEBUG_DISABLE_EARLY_EOF BIT(8) -#define CSID_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ BIT(9) - -#define CAM_CSID_EVT_PAYLOAD_MAX 10 -#define CAM_CSID_MIN_HBI_CFG_MAX_VAL 0xF - -#define CAM_CSID_RESOLUTION_22MP_WIDTH 5612 -#define CAM_CSID_RESOLUTION_25MP_WIDTH 6048 -#define CAM_CSID_RESOLUTION_28MP_WIDTH 7308 - -/* enum cam_csid_path_halt_mode select the path halt mode control */ -enum cam_csid_path_halt_mode { - CSID_HALT_MODE_INTERNAL, - CSID_HALT_MODE_GLOBAL, - CSID_HALT_MODE_MASTER, - CSID_HALT_MODE_SLAVE, -}; - -/** - *enum cam_csid_path_timestamp_stb_sel - select the sof/eof strobes used to - * capture the timestamp - */ -enum cam_csid_path_timestamp_stb_sel { - CSID_TIMESTAMP_STB_PRE_HALT, - CSID_TIMESTAMP_STB_POST_HALT, - CSID_TIMESTAMP_STB_POST_IRQ, - CSID_TIMESTAMP_STB_MAX, -}; - -/** - * enum cam_ife_pix_path_res_id - Specify the csid patch - */ -enum cam_ife_csid_irq_reg { - CAM_IFE_CSID_IRQ_REG_RDI_0, - CAM_IFE_CSID_IRQ_REG_RDI_1, - CAM_IFE_CSID_IRQ_REG_RDI_2, - CAM_IFE_CSID_IRQ_REG_RDI_3, - CAM_IFE_CSID_IRQ_REG_TOP, - CAM_IFE_CSID_IRQ_REG_RX, - CAM_IFE_CSID_IRQ_REG_IPP, - CAM_IFE_CSID_IRQ_REG_PPP, - CAM_IFE_CSID_IRQ_REG_UDI_0, - CAM_IFE_CSID_IRQ_REG_UDI_1, - CAM_IFE_CSID_IRQ_REG_UDI_2, - CAM_IFE_CSID_IRQ_REG_MAX, -}; - -struct cam_ife_csid_pxl_reg_offset { - /* Pxl path register offsets*/ - uint32_t csid_pxl_irq_status_addr; - uint32_t csid_pxl_irq_mask_addr; - uint32_t csid_pxl_irq_clear_addr; - uint32_t csid_pxl_irq_set_addr; - - uint32_t csid_pxl_cfg0_addr; - uint32_t csid_pxl_cfg1_addr; - uint32_t csid_pxl_ctrl_addr; - uint32_t csid_pxl_frm_drop_pattern_addr; - uint32_t csid_pxl_frm_drop_period_addr; - uint32_t csid_pxl_irq_subsample_pattern_addr; - uint32_t csid_pxl_irq_subsample_period_addr; - uint32_t csid_pxl_hcrop_addr; - uint32_t csid_pxl_vcrop_addr; - uint32_t csid_pxl_pix_drop_pattern_addr; - uint32_t csid_pxl_pix_drop_period_addr; - uint32_t csid_pxl_line_drop_pattern_addr; - uint32_t csid_pxl_line_drop_period_addr; - uint32_t csid_pxl_rst_strobes_addr; - uint32_t csid_pxl_status_addr; - uint32_t csid_pxl_misr_val_addr; - uint32_t csid_pxl_format_measure_cfg0_addr; - uint32_t csid_pxl_format_measure_cfg1_addr; - uint32_t csid_pxl_format_measure0_addr; - uint32_t csid_pxl_format_measure1_addr; - uint32_t csid_pxl_format_measure2_addr; - uint32_t csid_pxl_timestamp_curr0_sof_addr; - uint32_t csid_pxl_timestamp_curr1_sof_addr; - uint32_t csid_pxl_timestamp_perv0_sof_addr; - uint32_t csid_pxl_timestamp_perv1_sof_addr; - uint32_t csid_pxl_timestamp_curr0_eof_addr; - uint32_t csid_pxl_timestamp_curr1_eof_addr; - uint32_t csid_pxl_timestamp_perv0_eof_addr; - uint32_t csid_pxl_timestamp_perv1_eof_addr; - uint32_t csid_pxl_err_recovery_cfg0_addr; - uint32_t csid_pxl_err_recovery_cfg1_addr; - uint32_t csid_pxl_err_recovery_cfg2_addr; - uint32_t csid_pxl_multi_vcdt_cfg0_addr; - - /* configuration */ - uint32_t pix_store_en_shift_val; - uint32_t early_eof_en_shift_val; - uint32_t horizontal_bin_en_shift_val; - uint32_t quad_cfa_bin_en_shift_val; - uint32_t ccif_violation_en; - uint32_t overflow_ctrl_en; - uint32_t hblank_cfg_shift_val; - uint32_t halt_master_sel_en; - uint32_t halt_sel_internal_master_val; -}; - -struct cam_ife_csid_rdi_reg_offset { - uint32_t csid_rdi_irq_status_addr; - uint32_t csid_rdi_irq_mask_addr; - uint32_t csid_rdi_irq_clear_addr; - uint32_t csid_rdi_irq_set_addr; - - /*RDI N register address */ - uint32_t csid_rdi_cfg0_addr; - uint32_t csid_rdi_cfg1_addr; - uint32_t csid_rdi_ctrl_addr; - uint32_t csid_rdi_frm_drop_pattern_addr; - uint32_t csid_rdi_frm_drop_period_addr; - uint32_t csid_rdi_irq_subsample_pattern_addr; - uint32_t csid_rdi_irq_subsample_period_addr; - uint32_t csid_rdi_rpp_hcrop_addr; - uint32_t csid_rdi_rpp_vcrop_addr; - uint32_t csid_rdi_rpp_pix_drop_pattern_addr; - uint32_t csid_rdi_rpp_pix_drop_period_addr; - uint32_t csid_rdi_rpp_line_drop_pattern_addr; - uint32_t csid_rdi_rpp_line_drop_period_addr; - uint32_t csid_rdi_yuv_chroma_conversion_addr; - uint32_t csid_rdi_rst_strobes_addr; - uint32_t csid_rdi_status_addr; - uint32_t csid_rdi_misr_val0_addr; - uint32_t csid_rdi_misr_val1_addr; - uint32_t csid_rdi_misr_val2_addr; - uint32_t csid_rdi_misr_val3_addr; - uint32_t csid_rdi_format_measure_cfg0_addr; - uint32_t csid_rdi_format_measure_cfg1_addr; - uint32_t csid_rdi_format_measure0_addr; - uint32_t csid_rdi_format_measure1_addr; - uint32_t csid_rdi_format_measure2_addr; - uint32_t csid_rdi_timestamp_curr0_sof_addr; - uint32_t csid_rdi_timestamp_curr1_sof_addr; - uint32_t csid_rdi_timestamp_prev0_sof_addr; - uint32_t csid_rdi_timestamp_prev1_sof_addr; - uint32_t csid_rdi_timestamp_curr0_eof_addr; - uint32_t csid_rdi_timestamp_curr1_eof_addr; - uint32_t csid_rdi_timestamp_prev0_eof_addr; - uint32_t csid_rdi_timestamp_prev1_eof_addr; - uint32_t csid_rdi_err_recovery_cfg0_addr; - uint32_t csid_rdi_err_recovery_cfg1_addr; - uint32_t csid_rdi_err_recovery_cfg2_addr; - uint32_t csid_rdi_multi_vcdt_cfg0_addr; - uint32_t csid_rdi_byte_cntr_ping_addr; - uint32_t csid_rdi_byte_cntr_pong_addr; - - /* configuration */ - uint32_t packing_format; - uint32_t ccif_violation_en; - uint32_t overflow_ctrl_en; -}; - -struct cam_ife_csid_udi_reg_offset { - uint32_t csid_udi_irq_status_addr; - uint32_t csid_udi_irq_mask_addr; - uint32_t csid_udi_irq_clear_addr; - uint32_t csid_udi_irq_set_addr; - - /* UDI N register address */ - uint32_t csid_udi_cfg0_addr; - uint32_t csid_udi_cfg1_addr; - uint32_t csid_udi_ctrl_addr; - uint32_t csid_udi_frm_drop_pattern_addr; - uint32_t csid_udi_frm_drop_period_addr; - uint32_t csid_udi_irq_subsample_pattern_addr; - uint32_t csid_udi_irq_subsample_period_addr; - uint32_t csid_udi_rpp_hcrop_addr; - uint32_t csid_udi_rpp_vcrop_addr; - uint32_t csid_udi_rpp_pix_drop_pattern_addr; - uint32_t csid_udi_rpp_pix_drop_period_addr; - uint32_t csid_udi_rpp_line_drop_pattern_addr; - uint32_t csid_udi_rpp_line_drop_period_addr; - uint32_t csid_udi_yuv_chroma_conversion_addr; - uint32_t csid_udi_rst_strobes_addr; - uint32_t csid_udi_status_addr; - uint32_t csid_udi_misr_val0_addr; - uint32_t csid_udi_misr_val1_addr; - uint32_t csid_udi_misr_val2_addr; - uint32_t csid_udi_misr_val3_addr; - uint32_t csid_udi_format_measure_cfg0_addr; - uint32_t csid_udi_format_measure_cfg1_addr; - uint32_t csid_udi_format_measure0_addr; - uint32_t csid_udi_format_measure1_addr; - uint32_t csid_udi_format_measure2_addr; - uint32_t csid_udi_timestamp_curr0_sof_addr; - uint32_t csid_udi_timestamp_curr1_sof_addr; - uint32_t csid_udi_timestamp_prev0_sof_addr; - uint32_t csid_udi_timestamp_prev1_sof_addr; - uint32_t csid_udi_timestamp_curr0_eof_addr; - uint32_t csid_udi_timestamp_curr1_eof_addr; - uint32_t csid_udi_timestamp_prev0_eof_addr; - uint32_t csid_udi_timestamp_prev1_eof_addr; - uint32_t csid_udi_err_recovery_cfg0_addr; - uint32_t csid_udi_err_recovery_cfg1_addr; - uint32_t csid_udi_err_recovery_cfg2_addr; - uint32_t csid_udi_multi_vcdt_cfg0_addr; - uint32_t csid_udi_byte_cntr_ping_addr; - uint32_t csid_udi_byte_cntr_pong_addr; - - /* configuration */ - uint32_t packing_format; - uint32_t ccif_violation_en; - uint32_t overflow_ctrl_en; -}; - -struct cam_ife_csid_csi2_rx_reg_offset { - uint32_t csid_csi2_rx_irq_status_addr; - uint32_t csid_csi2_rx_irq_mask_addr; - uint32_t csid_csi2_rx_irq_clear_addr; - uint32_t csid_csi2_rx_irq_set_addr; - uint32_t csid_csi2_rx_cfg0_addr; - uint32_t csid_csi2_rx_cfg1_addr; - uint32_t csid_csi2_rx_capture_ctrl_addr; - uint32_t csid_csi2_rx_rst_strobes_addr; - uint32_t csid_csi2_rx_de_scramble_cfg0_addr; - uint32_t csid_csi2_rx_de_scramble_cfg1_addr; - uint32_t csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr; - uint32_t csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr; - uint32_t csid_csi2_rx_captured_short_pkt_0_addr; - uint32_t csid_csi2_rx_captured_short_pkt_1_addr; - uint32_t csid_csi2_rx_captured_long_pkt_0_addr; - uint32_t csid_csi2_rx_captured_long_pkt_1_addr; - uint32_t csid_csi2_rx_captured_long_pkt_ftr_addr; - uint32_t csid_csi2_rx_captured_cphy_pkt_hdr_addr; - uint32_t csid_csi2_rx_lane0_misr_addr; - uint32_t csid_csi2_rx_lane1_misr_addr; - uint32_t csid_csi2_rx_lane2_misr_addr; - uint32_t csid_csi2_rx_lane3_misr_addr; - uint32_t csid_csi2_rx_total_pkts_rcvd_addr; - uint32_t csid_csi2_rx_stats_ecc_addr; - uint32_t csid_csi2_rx_total_crc_err_addr; - uint32_t csid_csi2_rx_de_scramble_type3_cfg0_addr; - uint32_t csid_csi2_rx_de_scramble_type3_cfg1_addr; - uint32_t csid_csi2_rx_de_scramble_type2_cfg0_addr; - uint32_t csid_csi2_rx_de_scramble_type2_cfg1_addr; - uint32_t csid_csi2_rx_de_scramble_type1_cfg0_addr; - uint32_t csid_csi2_rx_de_scramble_type1_cfg1_addr; - uint32_t csid_csi2_rx_de_scramble_type0_cfg0_addr; - uint32_t csid_csi2_rx_de_scramble_type0_cfg1_addr; - - /*configurations */ - uint32_t csi2_rst_srb_all; - uint32_t csi2_rst_done_shift_val; - uint32_t csi2_irq_mask_all; - uint32_t csi2_misr_enable_shift_val; - uint32_t csi2_vc_mode_shift_val; - uint32_t csi2_capture_long_pkt_en_shift; - uint32_t csi2_capture_short_pkt_en_shift; - uint32_t csi2_capture_cphy_pkt_en_shift; - uint32_t csi2_capture_long_pkt_dt_shift; - uint32_t csi2_capture_long_pkt_vc_shift; - uint32_t csi2_capture_short_pkt_vc_shift; - uint32_t csi2_capture_cphy_pkt_dt_shift; - uint32_t csi2_capture_cphy_pkt_vc_shift; - uint32_t csi2_rx_phy_num_mask; -}; - -struct cam_ife_csid_csi2_tpg_reg_offset { - uint32_t csid_tpg_ctrl_addr; - uint32_t csid_tpg_vc_cfg0_addr; - uint32_t csid_tpg_vc_cfg1_addr; - uint32_t csid_tpg_lfsr_seed_addr; - uint32_t csid_tpg_dt_n_cfg_0_addr; - uint32_t csid_tpg_dt_n_cfg_1_addr; - uint32_t csid_tpg_dt_n_cfg_2_addr; - uint32_t csid_tpg_color_bars_cfg_addr; - uint32_t csid_tpg_color_box_cfg_addr; - uint32_t csid_tpg_common_gen_cfg_addr; - uint32_t csid_tpg_cgen_n_cfg_addr; - uint32_t csid_tpg_cgen_n_x0_addr; - uint32_t csid_tpg_cgen_n_x1_addr; - uint32_t csid_tpg_cgen_n_x2_addr; - uint32_t csid_tpg_cgen_n_xy_addr; - uint32_t csid_tpg_cgen_n_y1_addr; - uint32_t csid_tpg_cgen_n_y2_addr; - - /*configurations */ - uint32_t tpg_dtn_cfg_offset; - uint32_t tpg_cgen_cfg_offset; - uint32_t tpg_cpas_ife_reg_offset; - -}; -struct cam_ife_csid_common_reg_offset { - /* MIPI CSID registers */ - uint32_t csid_hw_version_addr; - uint32_t csid_cfg0_addr; - uint32_t csid_ctrl_addr; - uint32_t csid_reset_addr; - uint32_t csid_rst_strobes_addr; - - uint32_t csid_test_bus_ctrl_addr; - uint32_t csid_top_irq_status_addr; - uint32_t csid_top_irq_mask_addr; - uint32_t csid_top_irq_clear_addr; - uint32_t csid_top_irq_set_addr; - uint32_t csid_irq_cmd_addr; - - /*configurations */ - uint32_t major_version; - uint32_t minor_version; - uint32_t version_incr; - uint32_t num_udis; - uint32_t num_rdis; - uint32_t num_pix; - uint32_t num_ppp; - uint32_t csid_reg_rst_stb; - uint32_t csid_rst_stb; - uint32_t csid_rst_stb_sw_all; - uint32_t path_rst_stb_all; - uint32_t path_rst_done_shift_val; - uint32_t path_en_shift_val; - uint32_t packing_fmt_shift_val; - uint32_t dt_id_shift_val; - uint32_t vc_shift_val; - uint32_t dt_shift_val; - uint32_t fmt_shift_val; - uint32_t plain_fmt_shit_val; - uint32_t crop_v_en_shift_val; - uint32_t crop_h_en_shift_val; - uint32_t drop_v_en_shift_val; - uint32_t drop_h_en_shift_val; - uint32_t crop_shift; - uint32_t ipp_irq_mask_all; - uint32_t rdi_irq_mask_all; - uint32_t ppp_irq_mask_all; - uint32_t udi_irq_mask_all; - uint32_t measure_en_hbi_vbi_cnt_mask; - uint32_t format_measure_en_val; - uint32_t num_bytes_out_shift_val; - uint32_t format_measure_width_shift_val; - uint32_t format_measure_width_mask_val; - uint32_t format_measure_height_shift_val; - uint32_t format_measure_height_mask_val; -}; - -/** - * struct cam_ife_csid_reg_offset- CSID instance register info - * - * @cmn_reg: csid common registers info - * @ipp_reg: ipp register offset information - * @ppp_reg: ppp register offset information - * @rdi_reg: rdi register offset information - * @udi_reg: udi register offset information - * @tpg_reg: tpg register offset information - * - */ -struct cam_ife_csid_reg_offset { - const struct cam_ife_csid_common_reg_offset *cmn_reg; - const struct cam_ife_csid_csi2_rx_reg_offset *csi2_reg; - const struct cam_ife_csid_pxl_reg_offset *ipp_reg; - const struct cam_ife_csid_pxl_reg_offset *ppp_reg; - const struct cam_ife_csid_rdi_reg_offset *rdi_reg[CAM_IFE_CSID_RDI_MAX]; - const struct cam_ife_csid_udi_reg_offset *udi_reg[CAM_IFE_CSID_UDI_MAX]; - const struct cam_ife_csid_csi2_tpg_reg_offset *tpg_reg; -}; - - -/** - * struct cam_ife_csid_hw_info- CSID HW info - * - * @csid_reg: csid register offsets - * @hw_dts_version: HW DTS version - * @hw_reg_version: HW Version read from register - * @csid_max_clk: maximim csid clock - * - */ -struct cam_ife_csid_hw_info { - const struct cam_ife_csid_reg_offset *csid_reg; - uint32_t hw_dts_version; - uint32_t hw_reg_version; - uint32_t csid_max_clk; - -}; - - - -/** - * struct cam_ife_csid_csi2_rx_cfg- csid csi2 rx configuration data - * @phy_sel: input resource type for sensor only - * @lane_type: lane type: c-phy or d-phy - * @lane_num : active lane number - * @lane_cfg: lane configurations: 4 bits per lane - * - */ -struct cam_ife_csid_csi2_rx_cfg { - uint32_t phy_sel; - uint32_t lane_type; - uint32_t lane_num; - uint32_t lane_cfg; -}; - -/** - * struct cam_ife_csid_tpg_cfg- csid tpg configuration data - * @width: width - * @height: height - * @test_pattern : pattern - * @in_format: decode format - * @usage_type: whether dual isp is required - * - */ -struct cam_ife_csid_tpg_cfg { - uint32_t width; - uint32_t height; - uint32_t test_pattern; - uint32_t in_format; - uint32_t usage_type; -}; - -/** - * struct cam_ife_csid_cid_data- cid configuration private data - * - * @vc: Virtual channel - * @dt: Data type - * @cnt: Cid resource reference count. - * @tpg_set: Tpg used for this cid resource - * @is_valid_vc1_dt1: Valid vc1 and dt1 - * - */ -struct cam_ife_csid_cid_data { - uint32_t vc; - uint32_t dt; - uint32_t vc1; - uint32_t dt1; - uint32_t cnt; - uint32_t tpg_set; - uint32_t is_valid_vc1_dt1; -}; - - -/** - * struct cam_ife_csid_path_cfg- csid path configuration details. It is stored - * as private data for IPP/ RDI paths - * @vc : Virtual channel number - * @dt : Data type number - * @cid cid number, it is same as DT_ID number in HW - * @in_format: input decode format - * @out_format: output format - * @crop_enable: crop is enable or disabled, if enabled - * then remaining parameters are valid. - * @drop_enable: flag to indicate pixel drop enable or disable - * @start_pixel: start pixel - * @end_pixel: end_pixel - * @width: width - * @start_line: start line - * @end_line: end_line - * @height: heigth - * @sync_mode: Applicable for IPP/RDI path reservation - * Reserving the path for master IPP or slave IPP - * master (set value 1), Slave ( set value 2) - * for RDI, set mode to none - * @master_idx: For Slave reservation, Give master IFE instance Index. - * Slave will synchronize with master Start and stop operations - * @clk_rate Clock rate - * @num_bytes_out: Number of output bytes per cycle - * @hblank_cnt: HBI count - * - */ -struct cam_ife_csid_path_cfg { - uint32_t vc; - uint32_t dt; - uint32_t vc1; - uint32_t dt1; - uint32_t is_valid_vc1_dt1; - uint32_t cid; - uint32_t in_format; - uint32_t out_format; - bool crop_enable; - bool drop_enable; - uint32_t start_pixel; - uint32_t end_pixel; - uint32_t width; - uint32_t start_line; - uint32_t end_line; - uint32_t height; - enum cam_isp_hw_sync_mode sync_mode; - uint32_t master_idx; - uint64_t clk_rate; - uint32_t horizontal_bin; - uint32_t qcfa_bin; - uint32_t num_bytes_out; - uint32_t hblank_cnt; -}; - -/** - * struct cam_csid_evt_payload- payload for csid hw event - * @list : list head - * @evt_type : Event type from CSID - * @irq_status : IRQ Status register - * @hw_idx : Hw index - * @priv : Private data of payload - */ -struct cam_csid_evt_payload { - struct list_head list; - uint32_t evt_type; - uint32_t irq_status[CAM_IFE_CSID_IRQ_REG_MAX]; - uint32_t hw_idx; - void *priv; -}; - -/** - * struct cam_ife_csid_hw- csid hw device resources data - * - * @hw_intf: contain the csid hw interface information - * @hw_info: csid hw device information - * @csid_info: csid hw specific information - * @tasklet: tasklet to handle csid errors - * @priv: private data to be sent with callback - * @free_payload_list: list head for payload - * @evt_payload: Event payload to be passed to tasklet - * @res_type: CSID in resource type - * @csi2_rx_cfg: Csi2 rx decoder configuration for csid - * @tpg_cfg: TPG configuration - * @csi2_rx_reserve_cnt: CSI2 reservations count value - * @csi2_cfg_cnt: csi2 configuration count - * @tpg_start_cnt: tpg start count - * @ipp_res: image pixel path resource - * @ppp_res: phase pxl path resource - * @rdi_res: raw dump image path resources - * @udi_res: udi path resources - * @cid_res: cid resources state - * @csid_top_reset_complete: csid top reset completion - * @csid_csi2_reset_complete: csi2 reset completion - * @csid_ipp_reset_complete: ipp reset completion - * @csid_ppp_complete: ppp reset completion - * @csid_rdin_reset_complete: rdi n completion - * @csid_udin_reset_complete: udi n completion - * @csid_debug: csid debug information to enable the SOT, EOT, - * SOF, EOF, measure etc in the csid hw - * @clk_rate Clock rate - * @sof_irq_triggered: Flag is set on receiving event to enable sof irq - * incase of SOF freeze. - * @is_resetting: informs whether reset is started or not. - * @irq_debug_cnt: Counter to track sof irq's when above flag is set. - * @error_irq_count Error IRQ count, if continuous error irq comes - * need to stop the CSID and mask interrupts. - * @binning_enable Flag is set if hardware supports QCFA binning - * @binning_supported Flag is set if sensor supports QCFA binning - * @first_sof_ts first bootime stamp at the start - * @prev_qtimer_ts stores csid timestamp - * @epd_supported Flag is set if sensor supports EPD - * @fatal_err_detected flag to indicate fatal errror is reported - * @event_cb Callback to hw manager if CSID event reported - */ -struct cam_ife_csid_hw { - struct cam_hw_intf *hw_intf; - struct cam_hw_info *hw_info; - struct cam_ife_csid_hw_info *csid_info; - void *tasklet; - void *priv; - struct list_head free_payload_list; - struct cam_csid_evt_payload evt_payload[CAM_CSID_EVT_PAYLOAD_MAX]; - uint32_t res_type; - struct cam_ife_csid_csi2_rx_cfg csi2_rx_cfg; - struct cam_ife_csid_tpg_cfg tpg_cfg; - uint32_t csi2_reserve_cnt; - uint32_t csi2_cfg_cnt; - uint32_t tpg_start_cnt; - struct cam_isp_resource_node ipp_res; - struct cam_isp_resource_node ppp_res; - struct cam_isp_resource_node rdi_res[CAM_IFE_CSID_RDI_MAX]; - struct cam_isp_resource_node udi_res[CAM_IFE_CSID_UDI_MAX]; - struct cam_isp_resource_node cid_res[CAM_IFE_CSID_CID_MAX]; - struct completion csid_top_complete; - struct completion csid_csi2_complete; - struct completion csid_ipp_complete; - struct completion csid_ppp_complete; - struct completion csid_rdin_complete[CAM_IFE_CSID_RDI_MAX]; - struct completion csid_udin_complete[CAM_IFE_CSID_UDI_MAX]; - uint64_t csid_debug; - uint64_t clk_rate; - struct cam_isp_sensor_dimension ipp_path_config; - struct cam_isp_sensor_dimension ppp_path_config; - struct cam_isp_sensor_dimension rdi_path_config[CAM_IFE_CSID_RDI_MAX]; - uint32_t hbi; - uint32_t vbi; - bool sof_irq_triggered; - bool is_resetting; - uint32_t irq_debug_cnt; - uint32_t error_irq_count; - uint32_t device_enabled; - spinlock_t lock_state; - uint32_t binning_enable; - uint32_t binning_supported; - uint64_t prev_boot_timestamp; - uint64_t prev_qtimer_ts; - uint32_t epd_supported; - bool fatal_err_detected; - cam_hw_mgr_event_cb_func event_cb; -}; - -int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, - uint32_t csid_idx, bool is_custom); - -int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw); - -int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw, - struct cam_csid_hw_reserve_resource_args *cid_reserv); - -int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw, - struct cam_csid_hw_reserve_resource_args *reserve); - -#endif /* _CAM_IFE_CSID_HW_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.c index 55c8cd4274..208ac1f52f 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.c @@ -6,7 +6,7 @@ #include #include #include -#include "cam_ife_csid_core.h" +#include "cam_ife_csid_common.h" #include "cam_ife_csid_dev.h" #include "cam_ife_csid_hw_intf.h" #include "cam_debug_util.h" @@ -20,35 +20,28 @@ static char csid_dev_name[8]; static int cam_ife_csid_component_bind(struct device *dev, struct device *master_dev, void *data) { - struct cam_hw_intf *csid_hw_intf; - struct cam_hw_info *csid_hw_info; - struct cam_ife_csid_hw *csid_dev = NULL; + struct cam_hw_intf *hw_intf; + struct cam_hw_info *hw_info; const struct of_device_id *match_dev = NULL; - struct cam_ife_csid_hw_info *csid_hw_data = NULL; + struct cam_ife_csid_core_info *csid_core_info = NULL; uint32_t csid_dev_idx; int rc = 0; struct platform_device *pdev = to_platform_device(dev); CAM_DBG(CAM_ISP, "Binding IFE CSID component"); - csid_hw_intf = kzalloc(sizeof(*csid_hw_intf), GFP_KERNEL); - if (!csid_hw_intf) { + hw_intf = kzalloc(sizeof(*hw_intf), GFP_KERNEL); + if (!hw_intf) { rc = -ENOMEM; goto err; } - csid_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); - if (!csid_hw_info) { + hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); + if (!hw_info) { rc = -ENOMEM; goto free_hw_intf; } - csid_dev = kzalloc(sizeof(struct cam_ife_csid_hw), GFP_KERNEL); - if (!csid_dev) { - rc = -ENOMEM; - goto free_hw_info; - } - /* get ife csid hw index */ of_property_read_u32(pdev->dev.of_node, "cell-index", &csid_dev_idx); /* get ife csid hw information */ @@ -57,49 +50,49 @@ static int cam_ife_csid_component_bind(struct device *dev, if (!match_dev) { CAM_ERR(CAM_ISP, "No matching table for the IFE CSID HW!"); rc = -EINVAL; - goto free_dev; + goto free_hw_info; } memset(csid_dev_name, 0, sizeof(csid_dev_name)); snprintf(csid_dev_name, sizeof(csid_dev_name), "csid%1u", csid_dev_idx); - csid_hw_intf->hw_idx = csid_dev_idx; - csid_hw_intf->hw_type = CAM_ISP_HW_TYPE_IFE_CSID; - csid_hw_intf->hw_priv = csid_hw_info; + hw_intf->hw_idx = csid_dev_idx; + hw_intf->hw_type = CAM_ISP_HW_TYPE_IFE_CSID; + hw_intf->hw_priv = hw_info; - csid_hw_info->core_info = csid_dev; - csid_hw_info->soc_info.pdev = pdev; - csid_hw_info->soc_info.dev = &pdev->dev; - csid_hw_info->soc_info.dev_name = csid_dev_name; - csid_hw_info->soc_info.index = csid_dev_idx; + hw_info->soc_info.pdev = pdev; + hw_info->soc_info.dev = &pdev->dev; + hw_info->soc_info.dev_name = csid_dev_name; + hw_info->soc_info.index = csid_dev_idx; - csid_hw_data = (struct cam_ife_csid_hw_info *)match_dev->data; - /* need to setup the pdev before call the ife hw probe init */ - csid_dev->csid_info = csid_hw_data; + csid_core_info = (struct cam_ife_csid_core_info *)match_dev->data; - rc = cam_ife_csid_hw_probe_init(csid_hw_intf, csid_dev_idx, false); - if (rc) - goto free_dev; + /* call the driver init and fill csid_hw_info->core_info */ + rc = cam_ife_csid_hw_probe_init(hw_intf, csid_core_info, false); - platform_set_drvdata(pdev, csid_dev); + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] probe init failed", + csid_dev_idx); + goto free_hw_info; + } + + platform_set_drvdata(pdev, hw_intf); CAM_DBG(CAM_ISP, "CSID:%d component bound successfully", - csid_hw_intf->hw_idx); + hw_intf->hw_idx); - if (csid_hw_intf->hw_idx < CAM_IFE_CSID_HW_NUM_MAX) - cam_ife_csid_hw_list[csid_hw_intf->hw_idx] = csid_hw_intf; + if (hw_intf->hw_idx < CAM_IFE_CSID_HW_NUM_MAX) + cam_ife_csid_hw_list[hw_intf->hw_idx] = hw_intf; else - goto free_dev; + goto free_hw_info; return 0; -free_dev: - kfree(csid_dev); free_hw_info: - kfree(csid_hw_info); + kfree(hw_info); free_hw_intf: - kfree(csid_hw_intf); + kfree(hw_intf); err: return rc; } @@ -107,24 +100,30 @@ err: static void cam_ife_csid_component_unbind(struct device *dev, struct device *master_dev, void *data) { - struct cam_ife_csid_hw *csid_dev = NULL; - struct cam_hw_intf *csid_hw_intf; - struct cam_hw_info *csid_hw_info; + struct cam_hw_intf *hw_intf; + struct cam_hw_info *hw_info; + struct cam_ife_csid_core_info *core_info = NULL; struct platform_device *pdev = to_platform_device(dev); + const struct of_device_id *match_dev = NULL; - csid_dev = (struct cam_ife_csid_hw *)platform_get_drvdata(pdev); - csid_hw_intf = csid_dev->hw_intf; - csid_hw_info = csid_dev->hw_info; - + hw_intf = (struct cam_hw_intf *)platform_get_drvdata(pdev); + hw_info = hw_intf->hw_priv; CAM_DBG(CAM_ISP, "CSID:%d component unbind", - csid_dev->hw_intf->hw_idx); + hw_intf->hw_idx); + match_dev = of_match_device(pdev->dev.driver->of_match_table, + &pdev->dev); - cam_ife_csid_hw_deinit(csid_dev); + if (!match_dev) { + CAM_ERR(CAM_ISP, "No matching table for the IFE CSID HW!"); + goto free_mem; + } + cam_ife_csid_hw_deinit(hw_intf, core_info); + +free_mem: /*release the csid device memory */ - kfree(csid_dev); - kfree(csid_hw_info); - kfree(csid_hw_intf); + kfree(hw_info); + kfree(hw_intf); } const static struct component_ops cam_ife_csid_component_ops = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.h index 61bd875c18..e6cf2173fb 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_DEV_H_ @@ -17,7 +17,7 @@ int cam_ife_csid_remove(struct platform_device *pdev); * @brief : API to register CSID hw to platform framework. * @return struct platform_device pointer on on success, or ERR_PTR() on error. */ -int cam_ife_csid17x_init_module(void); +int cam_ife_csid_init_module(void); /** * @brief : API to register CSID Lite hw to platform framework. @@ -28,7 +28,7 @@ int cam_ife_csid_lite_init_module(void); /** * @brief : API to remove CSID Hw from platform framework. */ -void cam_ife_csid17x_exit_module(void); +void cam_ife_csid_exit_module(void); /** * @brief : API to remove CSID Lite Hw from platform framework. diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c new file mode 100644 index 0000000000..072cb99404 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c @@ -0,0 +1,4643 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include + +#include +#include + +#include + +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" +#include "cam_isp_hw.h" +#include "cam_soc_util.h" +#include "cam_io_util.h" +#include "cam_debug_util.h" +#include "cam_cpas_api.h" +#include "cam_isp_hw_mgr_intf.h" +#include "cam_tasklet_util.h" + +#define IFE_CSID_TIMEOUT 1000 + +/* Timeout values in usec */ +#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000 +#define CAM_IFE_CSID_TIMEOUT_ALL_US 100000 + +#define CAM_IFE_CSID_RESET_TIMEOUT_MS 100 + +/* + * Constant Factors needed to change QTimer ticks to nanoseconds + * QTimer Freq = 19.2 MHz + * Time(us) = ticks/19.2 + * Time(ns) = ticks/19.2 * 1000 + */ +#define CAM_IFE_CSID_QTIMER_MUL_FACTOR 10000 +#define CAM_IFE_CSID_QTIMER_DIV_FACTOR 192 + +/* Max number of sof irq's triggered in case of SOF freeze */ +#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12 + +/* Max CSI Rx irq error count threshold value */ +#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100 + +#define CAM_IFE_CSID_VER1_STATUS_MAX_NUM 32 + +static const struct cam_ife_csid_irq_desc ver1_rx_irq_desc[] = { + { + .desc = "DL0_EOT", + }, + { + .desc = "DL1_EOT", + }, + { + .desc = "DL2_EOT", + }, + { + .desc = "DL3_EOT", + }, + { + .desc = "DL0_SOT", + }, + { + .desc = "DL1_SOT", + }, + { + .desc = "DL2_SOT", + }, + { + .desc = "DL3_SOT", + }, + { + .desc = "LONG_PKT", + }, + { + .desc = "SHORT_PKT", + }, + { + .desc = "CPHY_PKT_HDR", + }, + { + .desc = "ERROR_CPHY_EOT_RECEPTION", + }, + { + .desc = "ERROR_CPHY_SOT_RECEPTION", + }, + { + .desc = "ERROR_CPHY_PH_CRC", + }, + { + .desc = "WARNING_ECC", + }, + { + .desc = "ERROR_LANE0_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_LANE1_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_LANE2_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_LANE3_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_CRC", + }, + { + .desc = "ERROR_ECC", + }, + { + .desc = "ERROR_MMAPPED_VC_DT", + }, + { + .desc = "ERROR_UNMAPPED_VC_DT", + }, + { + .desc = "ERROR_STREAM_UNDERFLOW", + }, + { + .desc = "ERROR_UNBOUNDED_FRAME", + }, + { + .desc = "RST_DONE", + }, +}; + +static const struct cam_ife_csid_irq_desc ver1_path_irq_desc[] = { + { + .desc = "", + }, + { + .desc = "Reset_Done", + }, + { + .desc = "ERROR_FIFO_OVERFLOW", + }, + { + .desc = "SUBSAMPLED_EOF", + }, + { + .desc = "SUBSAMPLED_SOF", + }, + { + .desc = "FRAME_DROP_EOF", + }, + { + .desc = "FRAME_DROP_EOL", + }, + { + .desc = "FRAME_DROP_SOL", + }, + { + .desc = "FRAME_DROP_SOF", + }, + { + .desc = "INPUT_EOF", + }, + { + .desc = "INPUT_EOL", + }, + { + .desc = "INPUT_SOL", + }, + { + .desc = "INPUT_SOF", + }, + { + .desc = "ERROR_PIX_COUNT", + }, + { + .desc = "ERROR_LINE_COUNT", + }, + { + .desc = "FRAME_DROP", + }, + { + .desc = "OVERFLOW_RECOVERY", + }, + { + .desc = "ERROR_REC_CCIF_VIOLATION", + }, + { + .desc = "CCIF_VIOLATION", + }, + { + .desc = "VCDT_GRP0_SEL", + }, + { + .desc = "VCDT_GRP1_SEL", + }, + { + .desc = "VCDT_GRP_CHANGE", + }, +}; + +static int cam_ife_csid_ver1_set_debug( + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t debug_val) +{ + int bit_pos = 0; + uint32_t val; + + csid_hw->debug_info.debug_val = debug_val; + + while (debug_val) { + + if (!(debug_val & 0x1)) { + debug_val >>= 1; + bit_pos++; + continue; + } + + val = BIT(bit_pos); + + switch (val) { + case CAM_IFE_CSID_DEBUG_ENABLE_SOF_IRQ: + csid_hw->debug_info.path_mask |= + IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_EOF_IRQ: + csid_hw->debug_info.path_mask |= + IFE_CSID_VER1_PATH_INFO_INPUT_EOF; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_SOT_IRQ: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER1_RX_DL0_SOT_CAPTURED | + IFE_CSID_VER1_RX_DL1_SOT_CAPTURED | + IFE_CSID_VER1_RX_DL2_SOT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_EOT_IRQ: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER1_RX_DL0_EOT_CAPTURED | + IFE_CSID_VER1_RX_DL1_EOT_CAPTURED | + IFE_CSID_VER1_RX_DL2_EOT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER1_RX_SHORT_PKT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER1_RX_LONG_PKT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER1_RX_CPHY_PKT_HDR_CAPTURED; + break; + default: + break; + } + + debug_val >>= 1; + bit_pos++; + } + + return 0; +} + +int cam_ife_csid_ver1_get_hw_caps(void *hw_priv, + void *get_hw_cap_args, uint32_t arg_size) +{ + int rc = 0; + struct cam_ife_csid_hw_caps *hw_caps; + struct cam_ife_csid_ver1_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_ife_csid_ver1_reg_info *csid_reg; + + + if (!hw_priv || !get_hw_cap_args) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + hw_caps->num_rdis = csid_reg->cmn_reg->num_rdis; + hw_caps->num_pix = csid_reg->cmn_reg->num_pix; + hw_caps->num_ppp = csid_reg->cmn_reg->num_ppp; + hw_caps->major_version = csid_reg->cmn_reg->major_version; + hw_caps->minor_version = csid_reg->cmn_reg->minor_version; + hw_caps->version_incr = csid_reg->cmn_reg->version_incr; + hw_caps->global_reset_en = csid_reg->cmn_reg->global_reset; + hw_caps->rup_en = csid_reg->cmn_reg->rup_supported; + + CAM_DBG(CAM_ISP, + "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d", + csid_hw->hw_intf->hw_idx, hw_caps->num_rdis, + hw_caps->num_pix, hw_caps->major_version, + hw_caps->minor_version, hw_caps->version_incr); + + return rc; +} + +static int cam_ife_csid_ver1_prepare_reset( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_ver1_reg_info *csid_reg; + uint32_t i; + unsigned long flags; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d", + csid_hw->hw_intf->hw_idx, + csid_hw->hw_info->hw_state); + return -EINVAL; + } + + CAM_DBG(CAM_ISP, "CSID:%d Csid reset", + csid_hw->hw_intf->hw_idx); + + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); + + /* Mask all interrupts */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->irq_mask_addr); + + if (csid_reg->cmn_reg->num_pix) + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_mask_addr); + + if (csid_reg->cmn_reg->num_ppp) + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->irq_mask_addr); + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->irq_mask_addr); + + /* clear all interrupts */ + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_clear_addr); + + cam_io_w_mb(csid_reg->csi2_reg->irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->irq_clear_addr); + + if (csid_reg->cmn_reg->num_pix) + cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_clear_addr); + + if (csid_reg->cmn_reg->num_ppp) + cam_io_w_mb(csid_reg->cmn_reg->ppp_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->irq_clear_addr); + + for (i = 0 ; i < csid_reg->cmn_reg->num_rdis; i++) + cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->irq_clear_addr); + + for (i = 0 ; i < csid_reg->cmn_reg->num_udis; i++) + cam_io_w_mb(csid_reg->cmn_reg->udi_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->udi_reg[i]->irq_clear_addr); + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); + + cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->cfg1_addr); + + /* enable the IPP and RDI format measure */ + if (csid_reg->cmn_reg->num_pix) + cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->cfg0_addr); + + if (csid_reg->cmn_reg->num_ppp) + cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->cfg0_addr); + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) + cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->cfg0_addr); + return 0; +} + +static int cam_ife_csid_ver1_hw_reset( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + uint32_t val = 0; + unsigned long flags, rem_jiffies = 0; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + reinit_completion( + &csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]); + + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); + + csid_hw->flags.process_reset = true; + + /* clear the top interrupt first */ + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_clear_addr); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + + /* enable top reset complete IRQ */ + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_mask_addr); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + + /* perform the top CSID registers reset */ + val = csid_reg->cmn_reg->rst_hw_reg_stb; + + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->rst_strobes_addr); + + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); + CAM_DBG(CAM_ISP, "CSID reset start"); + + rem_jiffies = wait_for_completion_timeout( + &csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP], + msecs_to_jiffies(CAM_IFE_CSID_RESET_TIMEOUT_MS)); + + if (rem_jiffies == 0) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_status_addr); + if (val & 0x1) { + /* clear top reset IRQ */ + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_clear_addr); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + CAM_DBG(CAM_ISP, "CSID:%d HW reset completed %d", + csid_hw->hw_intf->hw_idx, + rem_jiffies); + goto end; + } + CAM_ERR(CAM_ISP, "CSID:%d hw csid_reset fail rc = %d", + rem_jiffies); + rc = -ETIMEDOUT; + } else { + CAM_DBG(CAM_ISP, "CSID:%d hw reset completed %d", + csid_hw->hw_intf->hw_idx, + rem_jiffies); + } +end: + csid_hw->flags.process_reset = false; + return rc; +} + +static int cam_ife_csid_ver1_sw_reset( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + uint32_t val = 0; + unsigned long flags, rem_jiffies = 0; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + reinit_completion( + &csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]); + + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); + + csid_hw->flags.process_reset = true; + + /* clear the top interrupt first */ + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_clear_addr); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + + /* perform the top CSID registers reset */ + val = csid_reg->cmn_reg->rst_sw_reg_stb; + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->rst_strobes_addr); + + /* + * for SW reset, we enable the IRQ after since the mask + * register has been reset + */ + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_mask_addr); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + + spin_unlock_irqrestore(&csid_hw->hw_info->hw_lock, flags); + CAM_DBG(CAM_ISP, "CSID[%d] top reset start", + csid_hw->hw_intf->hw_idx); + + rem_jiffies = wait_for_completion_timeout( + &csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP], + msecs_to_jiffies(CAM_IFE_CSID_RESET_TIMEOUT_MS)); + + if (rem_jiffies == 0) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_status_addr); + if (val & 0x1) { + /* clear top reset IRQ */ + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_clear_addr); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + CAM_DBG(CAM_ISP, "CSID:%d sw reset completed %d", + csid_hw->hw_intf->hw_idx, + rem_jiffies); + goto end; + } + CAM_ERR(CAM_ISP, "CSID:%d sw csid_reset fail rc = %d", + csid_hw->hw_intf->hw_idx, + rem_jiffies); + rc = -ETIMEDOUT; + } else { + CAM_DBG(CAM_ISP, "CSID:%d sw reset completed %d", + csid_hw->hw_intf->hw_idx, + rem_jiffies); + } +end: + csid_hw->flags.process_reset = false; + return rc; +} + +static int cam_ife_csid_ver1_global_reset( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + + rc = cam_ife_csid_ver1_prepare_reset(csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] prepare reset failed"); + goto end; + } + + rc = cam_ife_csid_ver1_hw_reset(csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] hw reset failed"); + goto end; + } + + rc = cam_ife_csid_ver1_sw_reset(csid_hw); + + if (rc) + CAM_ERR(CAM_ISP, "CSID[%d] sw reset failed"); +end: + return rc; +} + +static int cam_ife_csid_path_reset( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_csid_reset_cfg_args *reset) +{ + const struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_isp_resource_node *res; + struct cam_hw_soc_info *soc_info; + unsigned long rem_jiffies; + uint32_t val; + int rc = 0; + int irq_reg = 0; + int id = 0; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + res = reset->node_res; + + if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d", + csid_hw->hw_intf->hw_idx, + csid_hw->hw_info->hw_state); + return -EINVAL; + } + + if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + CAM_DBG(CAM_ISP, "CSID:%d reset res:%d", + csid_hw->hw_intf->hw_idx, res->res_id); + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + path_reg = csid_reg->ipp_reg; + break; + case CAM_IFE_PIX_PATH_RES_PPP: + path_reg = csid_reg->ppp_reg; + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + path_reg = csid_reg->rdi_reg[res->res_id]; + break; + case CAM_IFE_PIX_PATH_RES_UDI_0: + case CAM_IFE_PIX_PATH_RES_UDI_1: + case CAM_IFE_PIX_PATH_RES_UDI_2: + id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; + path_reg = csid_reg->udi_reg[id]; + break; + default: + break; + } + + if (!path_reg) { + CAM_ERR(CAM_ISP, "Invalid res %d", res->res_id); + return -EINVAL; + } + + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + path_reg->irq_mask_addr); + val |= 1 << csid_reg->cmn_reg->rst_done_shift_val; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + path_reg->irq_mask_addr); + cam_io_w_mb(csid_reg->cmn_reg->path_rst_stb_all, + soc_info->reg_map[0].mem_base + path_reg->rst_strobes_addr); + + irq_reg = cam_ife_csid_convert_res_to_irq_reg(res->res_id); + reinit_completion(&csid_hw->irq_complete[irq_reg]); + + rem_jiffies = wait_for_completion_timeout( + &csid_hw->irq_complete[irq_reg], + msecs_to_jiffies(IFE_CSID_TIMEOUT)); + + CAM_DBG(CAM_ISP, "CSID:%d resource :%d reset done", + csid_hw->hw_intf->hw_idx, res->res_id); + + if (!rem_jiffies) { + rc = -ETIMEDOUT; + CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d", + csid_hw->hw_intf->hw_idx, + res->res_id, rc); + } + + return rc; +} + +int cam_ife_csid_ver1_reset(void *hw_priv, + void *reset_args, uint32_t arg_size) +{ + struct cam_hw_info *hw_info; + struct cam_ife_csid_ver1_hw *csid_hw; + struct cam_csid_reset_cfg_args *reset; + int rc = 0; + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + reset = (struct cam_csid_reset_cfg_args *)reset_args; + + mutex_lock(&csid_hw->hw_info->hw_mutex); + + switch (reset->reset_type) { + case CAM_IFE_CSID_RESET_GLOBAL: + rc = cam_ife_csid_ver1_global_reset(csid_hw); + break; + case CAM_IFE_CSID_RESET_PATH: + rc = cam_ife_csid_path_reset(csid_hw, reset); + break; + default: + CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d", + reset->reset_type); + rc = -EINVAL; + break; + } + + CAM_DBG(CAM_ISP, "CSID[%d] reset type :%d", + csid_hw->hw_intf->hw_idx, + reset->reset_type); + + mutex_unlock(&csid_hw->hw_info->hw_mutex); + return rc; +} + +static int cam_ife_csid_ver1_deinit_rdi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + const struct cam_ife_csid_ver1_path_reg_info *path_reg; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_core_info *core_info; + struct cam_hw_soc_info *soc_info; + void __iomem *mem_base; + int rc = 0; + uint32_t val; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || + res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + core_info = csid_hw->core_info; + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *)core_info->csid_reg; + + path_reg = csid_reg->rdi_reg[res->res_id]; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[0].mem_base; + + if (path_reg->overflow_ctrl_en) + cam_io_w_mb(0, mem_base + + path_reg->err_recovery_cfg0_addr); + + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + + if (val & path_reg->format_measure_en_shift_val) { + val &= ~path_reg->format_measure_en_shift_val; + cam_io_w_mb(val, mem_base + + path_reg->cfg0_addr); + + /* Disable the HBI/VBI counter */ + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg0_addr); + } + + res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + + return rc; +} + +static int cam_ife_csid_ver1_deinit_udi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + const struct cam_ife_csid_ver1_path_reg_info *path_reg; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_core_info *core_info; + struct cam_hw_soc_info *soc_info; + void __iomem *mem_base; + uint32_t val, id; + int rc = 0; + + if ((res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) || + (res->res_id < CAM_IFE_PIX_PATH_RES_UDI_0 || + res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + core_info = csid_hw->core_info; + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *)core_info->csid_reg; + + id = res->res_id > CAM_IFE_PIX_PATH_RES_UDI_0; + path_reg = csid_reg->udi_reg[id]; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[0].mem_base; + + if (path_reg->overflow_ctrl_en) + cam_io_w_mb(0, mem_base + + path_reg->err_recovery_cfg0_addr); + + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + + if (val & BIT(path_reg->format_measure_en_shift_val)) { + val &= ~BIT(path_reg->format_measure_en_shift_val); + cam_io_w_mb(val, mem_base + + path_reg->cfg0_addr); + + /* Disable the HBI/VBI counter */ + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg0_addr); + } + + res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + + return rc; +} +static int cam_ife_csid_ver1_deinit_pxl_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + void __iomem *mem_base; + uint32_t val; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + const struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + struct cam_ife_csid_core_info *core_info; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + core_info = csid_hw->core_info; + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *)core_info->csid_reg; + + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + path_reg = csid_reg->ipp_reg; + else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + path_reg = csid_reg->ppp_reg; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d PIX:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[0].mem_base; + + if (path_reg->overflow_ctrl_en) + cam_io_w_mb(0, mem_base + + path_reg->err_recovery_cfg0_addr); + + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + + if (val & path_reg->format_measure_en_shift_val) { + val &= ~path_reg->format_measure_en_shift_val; + cam_io_w_mb(val, mem_base + + path_reg->cfg0_addr); + + /* Disable the HBI/VBI counter */ + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val &= ~csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg0_addr); + } + + res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + return rc; +} + +static int cam_ife_csid_ver1_stop_pxl_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res, + enum cam_ife_csid_halt_cmd stop_cmd) +{ + int rc = 0; + uint32_t val; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + const struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + struct cam_ife_csid_ver1_path_cfg *path_cfg; + uint32_t halt_cmd = 0; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + path_reg = csid_reg->ipp_reg; + else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + path_reg = csid_reg->ppp_reg; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d PIX:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + + if (stop_cmd == CAM_CSID_HALT_IMMEDIATELY) { + halt_cmd = path_reg->halt_immediate; + } else if (stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY) { + halt_cmd = path_reg->halt_frame_boundary; + } else { + CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d", + csid_hw->hw_intf->hw_idx, stop_cmd); + return -EINVAL; + } + + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + path_reg->irq_mask_addr); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + path_reg->ctrl_addr); + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER || + path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) { + /* configure Halt for master */ + val &= ~0x3; + val |= halt_cmd; + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + path_reg->ctrl_addr); + } + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_SLAVE && + stop_cmd == CAM_CSID_HALT_IMMEDIATELY) { + /* configure Halt for slave */ + val &= ~0xF; + val |= halt_cmd; + val |= (path_reg->halt_mode_master << + path_reg->halt_mode_shift); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + path_reg->ctrl_addr); + } + + return rc; +} + +static int cam_ife_csid_ver1_stop_rdi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res, + enum cam_ife_csid_halt_cmd stop_cmd) +{ + const struct cam_ife_csid_ver1_path_reg_info *path_reg; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_core_info *core_info; + struct cam_hw_soc_info *soc_info; + void __iomem *mem_base; + uint32_t val; + int rc = 0; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + core_info = csid_hw->core_info; + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *)core_info->csid_reg; + path_reg = csid_reg->rdi_reg[res->res_id]; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d PIX:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[0].mem_base; + + if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY && + stop_cmd != CAM_CSID_HALT_IMMEDIATELY) { + CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d", + csid_hw->hw_intf->hw_idx, stop_cmd); + return -EINVAL; + } + + cam_io_w_mb(0, mem_base + path_reg->irq_mask_addr); + + val = cam_io_r_mb(mem_base + path_reg->ctrl_addr); + val &= ~0x3; + val |= stop_cmd; + cam_io_w_mb(val, mem_base + path_reg->ctrl_addr); + + return rc; +} + +static int cam_ife_csid_ver1_stop_udi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res, + enum cam_ife_csid_halt_cmd stop_cmd) +{ + const struct cam_ife_csid_ver1_path_reg_info *path_reg; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_core_info *core_info; + struct cam_hw_soc_info *soc_info; + void __iomem *mem_base; + uint32_t val, id; + int rc = 0; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; + core_info = csid_hw->core_info; + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *)core_info->csid_reg; + path_reg = csid_reg->udi_reg[id]; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[0].mem_base; + + if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY && + stop_cmd != CAM_CSID_HALT_IMMEDIATELY) { + CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d", + csid_hw->hw_intf->hw_idx, stop_cmd); + return -EINVAL; + } + + cam_io_w_mb(0, mem_base + path_reg->irq_mask_addr); + + val = cam_io_r_mb(mem_base + path_reg->ctrl_addr); + val &= ~0x3; + val |= stop_cmd; + cam_io_w_mb(val, mem_base + path_reg->ctrl_addr); + + return rc; +} + +static int cam_ife_csid_hw_ver1_path_cfg( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_ife_csid_ver1_path_cfg *path_cfg, + struct cam_csid_hw_reserve_resource_args *reserve, + uint32_t cid) +{ + + path_cfg->cid = cid; + path_cfg->in_format = reserve->in_port->format; + path_cfg->out_format = reserve->out_port->format; + path_cfg->sync_mode = reserve->sync_mode; + path_cfg->height = reserve->in_port->height; + path_cfg->start_line = reserve->in_port->line_start; + path_cfg->end_line = reserve->in_port->line_stop; + path_cfg->crop_enable = reserve->crop_enable; + path_cfg->drop_enable = reserve->drop_enable; + path_cfg->horizontal_bin = reserve->in_port->horizontal_bin; + path_cfg->qcfa_bin = reserve->in_port->qcfa_bin; + path_cfg->num_bytes_out = reserve->in_port->num_bytes_out; + + if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) { + path_cfg->start_pixel = reserve->in_port->left_start; + path_cfg->end_pixel = reserve->in_port->left_stop; + path_cfg->width = reserve->in_port->left_width; + + if (reserve->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0 && + reserve->res_id <= (CAM_IFE_PIX_PATH_RES_RDI_0 + + CAM_IFE_CSID_RDI_MAX - 1)) { + path_cfg->end_pixel = reserve->in_port->right_stop; + path_cfg->width = path_cfg->end_pixel - + path_cfg->start_pixel + 1; + } + + CAM_DBG(CAM_ISP, + "CSID:%d res:%d master:startpixel 0x%x endpixel:0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_pixel, path_cfg->end_pixel); + CAM_DBG(CAM_ISP, + "CSID:%d res:%d master:line start:0x%x line end:0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_line, path_cfg->end_line); + } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) { + path_cfg->start_pixel = reserve->in_port->right_start; + path_cfg->end_pixel = reserve->in_port->right_stop; + path_cfg->width = reserve->in_port->right_width; + CAM_DBG(CAM_ISP, + "CSID:%d res:%d slave:start:0x%x end:0x%x width 0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_pixel, path_cfg->end_pixel, + path_cfg->width); + CAM_DBG(CAM_ISP, + "CSID:%d res:%d slave:line start:0x%x line end:0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_line, path_cfg->end_line); + } else { + path_cfg->width = reserve->in_port->left_width; + path_cfg->start_pixel = reserve->in_port->left_start; + path_cfg->end_pixel = reserve->in_port->left_stop; + CAM_DBG(CAM_ISP, + "CSID:%d res:%d left width %d start: %d stop:%d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + reserve->in_port->left_width, + reserve->in_port->left_start, + reserve->in_port->left_stop); + } + return 0; +} + +static int cam_ife_csid_ver1_rx_capture_config( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + uint32_t vc, dt, i; + uint32_t val = 0; + + for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) + if (csid_hw->cid_data[i].cid_cnt) + break; + + if (i == CAM_IFE_CSID_CID_MAX) { + CAM_WARN(CAM_ISP, "CSID[%d] no valid cid", + csid_hw->hw_intf->hw_idx); + return 0; + } + + vc = csid_hw->cid_data[i].vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc; + dt = csid_hw->cid_data[i].vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) + val = ((1 << + csid_reg->csi2_reg->capture_short_pkt_en_shift) | + (vc << + csid_reg->csi2_reg->capture_short_pkt_vc_shift)); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) + val |= ((1 << + csid_reg->csi2_reg->capture_long_pkt_en_shift) | + (dt << + csid_reg->csi2_reg->capture_long_pkt_dt_shift) | + (vc << + csid_reg->csi2_reg->capture_long_pkt_vc_shift)); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) + val |= ((1 << + csid_reg->csi2_reg->capture_cphy_pkt_en_shift) | + (dt << + csid_reg->csi2_reg->capture_cphy_pkt_dt_shift) | + (vc << + csid_reg->csi2_reg->capture_cphy_pkt_vc_shift)); + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->capture_ctrl_addr); + return 0; +} + +static int cam_ife_csid_ver1_tpg_config( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_csid_hw_reserve_resource_args *reserve) +{ + + if (csid_hw->flags.tpg_configured) + return 0; + + switch (reserve->in_port->test_pattern) { + case CAM_ISP_PATTERN_BAYER_RGRGRG: + case CAM_ISP_PATTERN_BAYER_GRGRGR: + case CAM_ISP_PATTERN_BAYER_BGBGBG: + case CAM_ISP_PATTERN_BAYER_GBGBGB: + csid_hw->tpg_cfg.test_pattern = reserve->in_port->test_pattern; + break; + case CAM_ISP_PATTERN_YUV_YCBYCR: + case CAM_ISP_PATTERN_YUV_YCRYCB: + case CAM_ISP_PATTERN_YUV_CBYCRY: + case CAM_ISP_PATTERN_YUV_CRYCBY: + csid_hw->tpg_cfg.test_pattern = + CAM_IFE_CSID_TPG_TEST_PATTERN_YUV; + break; + default: + CAM_ERR(CAM_ISP, "CSID[%d] invalid test_pattern %d", + csid_hw->hw_intf->hw_idx, + reserve->in_port->test_pattern); + return -EINVAL; + } + + switch (reserve->in_port->format) { + case CAM_FORMAT_MIPI_RAW_8: + csid_hw->tpg_cfg.encode_format = CAM_IFE_CSID_TPG_ENCODE_RAW8; + break; + case CAM_FORMAT_MIPI_RAW_10: + csid_hw->tpg_cfg.encode_format = CAM_IFE_CSID_TPG_ENCODE_RAW10; + break; + case CAM_FORMAT_MIPI_RAW_12: + csid_hw->tpg_cfg.encode_format = CAM_IFE_CSID_TPG_ENCODE_RAW12; + break; + case CAM_FORMAT_MIPI_RAW_14: + csid_hw->tpg_cfg.encode_format = CAM_IFE_CSID_TPG_ENCODE_RAW14; + break; + case CAM_FORMAT_MIPI_RAW_16: + csid_hw->tpg_cfg.encode_format = CAM_IFE_CSID_TPG_ENCODE_RAW16; + break; + case CAM_FORMAT_YUV422: + csid_hw->tpg_cfg.encode_format = CAM_IFE_CSID_TPG_ENCODE_RAW8; + break; + default: + CAM_ERR(CAM_ISP, "CSID[%d] invalid input format %d", + csid_hw->hw_intf->hw_idx, + reserve->in_port->format); + return -EINVAL; + } + + if (reserve->in_port->usage_type) + csid_hw->tpg_cfg.width = reserve->in_port->right_stop + 1; + else + csid_hw->tpg_cfg.width = reserve->in_port->left_width; + csid_hw->tpg_cfg.height = reserve->in_port->height; + csid_hw->flags.tpg_configured = true; + csid_hw->tpg_cfg.vc = reserve->in_port->vc[0]; + csid_hw->tpg_cfg.dt = reserve->in_port->dt[0]; + return 0; +} + +static int cam_ife_csid_ver1_tpg_start( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + uint32_t val = 0; + uint32_t i; + uint32_t base; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_reg_info *csid_reg = NULL; + + if (csid_hw->flags.tpg_enabled) + return 0; + + /*Enable the TPG */ + CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG", + csid_hw->hw_intf->hw_idx); + + soc_info = &csid_hw->hw_info->soc_info; + + CAM_DBG(CAM_ISP, "================ TPG ============"); + base = 0x600; + + for (i = 0; i < 16; i++) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + base + i * 4); + CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", + (base + i*4), val); + } + + CAM_DBG(CAM_ISP, "================ IPP ============="); + base = 0x200; + for (i = 0; i < 10; i++) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + base + i * 4); + CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", + (base + i*4), val); + } + + CAM_DBG(CAM_ISP, "================ RX ============="); + base = 0x100; + for (i = 0; i < 5; i++) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + base + i * 4); + CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", + (base + i*4), val); + } + + /* Enable the IFE force clock on for dual isp case */ + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (csid_hw->tpg_cfg.usage_type) { + rc = cam_ife_csid_enable_ife_force_clock_on(soc_info, + csid_reg->tpg_reg->cpas_ife_reg_offset); + if (rc) + return rc; + } + + CAM_DBG(CAM_ISP, "============ TPG control ============"); + val = csid_reg->tpg_reg->ctrl_cfg | + ((csid_hw->rx_cfg.lane_num - 1) & + csid_reg->tpg_reg->num_active_lanes_mask); + + csid_hw->flags.tpg_enabled = true; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->tpg_reg->ctrl_addr); + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600); + CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val); + + return 0; +} + +static int cam_ife_csid_ver1_tpg_stop(struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_reg_info *csid_reg = NULL; + + if (!csid_hw->flags.tpg_enabled) + return 0; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + /* disable the TPG */ + CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG", + csid_hw->hw_intf->hw_idx); + + /* Disable the IFE force clock on for dual isp case */ + if (csid_hw->tpg_cfg.usage_type) + rc = cam_ife_csid_disable_ife_force_clock_on(soc_info, + csid_reg->tpg_reg->cpas_ife_reg_offset); + + /*stop the TPG */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->tpg_reg->ctrl_addr); + csid_hw->flags.tpg_enabled = false; + csid_hw->flags.tpg_configured = false; + + return 0; +} + +static int cam_ife_csid_ver1_init_tpg_hw( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_ver1_tpg_reg_info *tpg_reg; + struct cam_hw_soc_info *soc_info; + uint32_t val = 0; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + tpg_reg = csid_reg->tpg_reg; + soc_info = &csid_hw->hw_info->soc_info; + + CAM_DBG(CAM_ISP, "CSID:%d TPG config", + csid_hw->hw_intf->hw_idx); + + /* configure one DT, infinite frames */ + val = (tpg_reg->num_frames << tpg_reg->num_frame_shift) | + csid_hw->tpg_cfg.vc; + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->vc_cfg0_addr); + + /* vertical blanking count = 0x3FF, horzontal blanking count = 0x740*/ + val = (tpg_reg->vbi << tpg_reg->vbi_shift) | + (tpg_reg->hbi << tpg_reg->hbi_shift); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->vc_cfg1_addr); + + cam_io_w_mb(tpg_reg->lfsr_seed, soc_info->reg_map[0].mem_base + + tpg_reg->lfsr_seed_addr); + + val = csid_hw->tpg_cfg.width << tpg_reg->width_shift | + csid_hw->tpg_cfg.height; + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->dt_n_cfg_0_addr); + + cam_io_w_mb(csid_hw->tpg_cfg.dt, soc_info->reg_map[0].mem_base + + csid_reg->tpg_reg->dt_n_cfg_1_addr); + + /* + * in_format is the same as the input resource format. + * it is one larger than the register spec format. + */ + val = ((csid_hw->tpg_cfg.encode_format) << tpg_reg->fmt_shift) | + tpg_reg->payload_mode; + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->tpg_reg->dt_n_cfg_2_addr); + + /* static frame with split color bar */ + val = tpg_reg->color_bar << tpg_reg->color_bar_shift; + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->color_bars_cfg_addr); + /* config pix pattern */ + cam_io_w_mb(csid_hw->tpg_cfg.test_pattern, + soc_info->reg_map[0].mem_base + + tpg_reg->common_gen_cfg_addr); + + return 0; +} + +static int cam_ife_csid_hw_ver1_rx_cfg( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_csid_hw_reserve_resource_args *reserve) +{ + + if (csid_hw->counters.csi2_reserve_cnt) { + csid_hw->counters.csi2_reserve_cnt++; + CAM_DBG(CAM_ISP, "CSID %u Rx already reserved cnt %u", + csid_hw->hw_intf->hw_idx, + csid_hw->counters.csi2_reserve_cnt); + return 0; + } + + csid_hw->rx_cfg.lane_cfg = + reserve->in_port->lane_cfg; + csid_hw->rx_cfg.lane_type = + reserve->in_port->lane_type; + csid_hw->rx_cfg.lane_num = + reserve->in_port->lane_num; + csid_hw->res_type = reserve->in_port->res_type; + + switch (reserve->in_port->res_type) { + case CAM_ISP_IFE_IN_RES_TPG: + csid_hw->rx_cfg.phy_sel = 0; + break; + case CAM_ISP_IFE_IN_RES_CPHY_TPG_0: + csid_hw->rx_cfg.phy_sel = 1; + break; + case CAM_ISP_IFE_IN_RES_CPHY_TPG_1: + csid_hw->rx_cfg.phy_sel = 2; + break; + case CAM_ISP_IFE_IN_RES_CPHY_TPG_2: + csid_hw->rx_cfg.phy_sel = 3; + break; + default: + csid_hw->rx_cfg.phy_sel = + (reserve->in_port->res_type & 0xFF) - 1; + break; + } + + csid_hw->counters.csi2_reserve_cnt++; + CAM_DBG(CAM_ISP, + "CSID:%u Lane cfg:0x%x type:%u num:%u res:0x%x, res_cnt %u", + csid_hw->hw_intf->hw_idx, + reserve->in_port->lane_cfg, reserve->in_port->lane_type, + reserve->in_port->lane_num, reserve->in_port->res_type, + csid_hw->counters.csi2_reserve_cnt); + + return 0; + +} + +int cam_ife_csid_hw_ver1_hw_cfg( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_ife_csid_ver1_path_cfg *path_cfg, + struct cam_csid_hw_reserve_resource_args *reserve, + uint32_t cid) +{ + int rc = 0; + + cam_ife_csid_hw_ver1_rx_cfg(csid_hw, reserve); + cam_ife_csid_hw_ver1_path_cfg(csid_hw, path_cfg, + reserve, cid); + + if (reserve->res_type == CAM_ISP_IFE_IN_RES_TPG) { + rc = cam_ife_csid_ver1_tpg_config(csid_hw, reserve); + + if (rc) + CAM_ERR(CAM_ISP, + "CSID[%d] Res_id %d tpg config fail", + csid_hw->hw_intf->hw_idx, reserve->res_id); + } + + return rc; +} + +static int cam_ife_csid_check_cust_node( + struct cam_csid_hw_reserve_resource_args *reserve, + struct cam_ife_csid_ver1_hw *csid_hw) +{ + struct cam_ife_csid_ver1_reg_info *csid_reg; + + if (!reserve->in_port->cust_node) + return 0; + + if (reserve->in_port->usage_type == CAM_ISP_RES_USAGE_DUAL) { + CAM_ERR(CAM_ISP, + "Dual IFE is not supported for cust_node %u", + reserve->in_port->cust_node); + return -EINVAL; + } + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (!(csid_reg->csid_cust_node_map[csid_hw->hw_intf->hw_idx] & + BIT(reserve->in_port->cust_node))) { + CAM_ERR(CAM_ISP, + "Invalid CSID:%u cust_node %u", + csid_hw->hw_intf->hw_idx, + reserve->in_port->cust_node); + return -EINVAL; + } + + return 0; +} + +static bool cam_ife_csid_ver1_is_width_valid_by_fuse( + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t width) +{ + struct cam_ife_csid_ver1_reg_info *csid_reg; + uint32_t fuse_val = UINT_MAX; + + cam_cpas_is_feature_supported(CAM_CPAS_MP_LIMIT_FUSE, + CAM_CPAS_HW_IDX_ANY, &fuse_val); + + if (fuse_val == UINT_MAX) { + CAM_DBG(CAM_ISP, "CSID[%u] Fuse not present", + csid_hw->hw_intf->hw_idx); + return true; + } + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (fuse_val > csid_reg->width_fuse_max_val) { + CAM_ERR(CAM_ISP, "Invalid fuse value %u", fuse_val); + return false; + } + + if (width > csid_reg->fused_max_width[fuse_val]) { + CAM_ERR(CAM_ISP, + "CSID[%u] Resolution not supported required_width: %d max_supported_width: %d", + csid_hw->hw_intf->hw_idx, + width, csid_reg->fused_max_width[fuse_val]); + return false; + } + + return true; +} + +static bool cam_ife_csid_ver1_is_width_valid_by_dt( + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t width) +{ + struct cam_csid_soc_private *soc_private = NULL; + + soc_private = (struct cam_csid_soc_private *) + csid_hw->hw_info->soc_info.soc_private; + + if (!soc_private->max_width_enabled) + return true; + + if (width > soc_private->max_width) { + CAM_ERR(CAM_ISP, + "CSID[%u] Resolution not supported required_width: %d max_supported_width: %d", + csid_hw->hw_intf->hw_idx, + width, soc_private->max_width); + return false; + } + + return true; +} + +bool cam_ife_csid_ver1_is_width_valid( + struct cam_csid_hw_reserve_resource_args *reserve, + struct cam_ife_csid_ver1_hw *csid_hw) +{ + uint32_t width = 0; + + if (reserve->res_id != CAM_IFE_PIX_PATH_RES_IPP) + return true; + + if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER || + reserve->sync_mode == CAM_ISP_HW_SYNC_NONE) + width = reserve->in_port->left_stop - + reserve->in_port->left_start + 1; + else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) + width = reserve->in_port->right_stop - + reserve->in_port->right_start + 1; + + if (!cam_ife_csid_ver1_is_width_valid_by_fuse(csid_hw, width)) { + CAM_ERR(CAM_ISP, "CSID[%u] width limited by fuse", + csid_hw->hw_intf->hw_idx); + return false; + } + + if (!cam_ife_csid_ver1_is_width_valid_by_dt(csid_hw, width)) { + CAM_ERR(CAM_ISP, "CSID[%u] width limited by dt", + csid_hw->hw_intf->hw_idx); + return false; + } + + return true; +} + +static int cam_ife_csid_ver1_in_port_validate( + struct cam_csid_hw_reserve_resource_args *reserve, + struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + struct cam_ife_csid_ver1_reg_info *csid_reg; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + /* check in port args */ + rc = cam_ife_csid_check_in_port_args(reserve, + csid_hw->hw_intf->hw_idx); + if (rc) + goto err; + + if (!cam_ife_csid_ver1_is_width_valid(reserve, csid_hw)) + goto err; + + if (reserve->in_port->cust_node) { + rc = cam_ife_csid_check_cust_node(reserve, csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "Custom node config error"); + goto err; + } + } + + if (csid_hw->counters.csi2_reserve_cnt) { + + if (csid_hw->res_type != reserve->in_port->res_type) { + CAM_ERR(CAM_ISP, + "CSID[%d ]Invalid res[%x] in_res_type[%x]", + csid_hw->hw_intf->hw_idx, + csid_hw->res_type, + reserve->in_port->res_type); + rc = -EINVAL; + goto err; + } + + if (csid_hw->rx_cfg.lane_cfg != + reserve->in_port->lane_cfg || + csid_hw->rx_cfg.lane_type != + reserve->in_port->lane_type || + csid_hw->rx_cfg.lane_num != + reserve->in_port->lane_num) { + CAM_ERR(CAM_ISP, + "[%d] lane: num[%d %d] type[%d %d] cfg[%d %d]", + csid_hw->hw_intf->hw_idx, + csid_hw->rx_cfg.lane_num, + reserve->in_port->lane_num, + csid_hw->rx_cfg.lane_type, + reserve->in_port->lane_type, + csid_hw->rx_cfg.lane_cfg, + reserve->in_port->lane_cfg); + rc = -EINVAL; + goto err; + } + } + + return rc; +err: + CAM_ERR(CAM_ISP, "Invalid args csid[%d] rc %d", + csid_hw->hw_intf->hw_idx, rc); + return rc; +} + + +int cam_ife_csid_ver1_reserve(void *hw_priv, + void *reserve_args, uint32_t arg_size) +{ + + struct cam_ife_csid_ver1_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_isp_resource_node *res = NULL; + struct cam_csid_hw_reserve_resource_args *reserve; + struct cam_ife_csid_ver1_path_cfg *path_cfg; + uint32_t cid; + int rc = 0; + + reserve = (struct cam_csid_hw_reserve_resource_args *)reserve_args; + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + + res = &csid_hw->path_res[reserve->res_id]; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) { + CAM_DBG(CAM_ISP, "CSID %d Res_id %d state %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state); + return -EINVAL; + } + + rc = cam_ife_csid_ver1_in_port_validate(reserve, csid_hw); + + CAM_DBG(CAM_ISP, "CSID[%d] res_id %d", + csid_hw->hw_intf->hw_idx, reserve->res_id); + + if (rc) { + CAM_DBG(CAM_ISP, "CSID %d Res_id %d port validation failed", + csid_hw->hw_intf->hw_idx, reserve->res_id); + return rc; + } + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + + if (!path_cfg) { + CAM_ERR(CAM_ISP, + "CSID %d Unallocated Res_id %d state %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state); + return -EINVAL; + } + + rc = cam_ife_csid_cid_reserve(csid_hw->cid_data, &cid, + csid_hw->hw_intf->hw_idx, reserve); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID %d Res_id %d state %d invalid cid %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state, cid); + return rc; + } + + rc = cam_ife_csid_hw_ver1_hw_cfg(csid_hw, path_cfg, + reserve, cid); + res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + reserve->node_res = res; + csid_hw->event_cb = reserve->event_cb; + csid_hw->token = reserve->cb_priv; + + CAM_DBG(CAM_ISP, "CSID %d Res_id %d state %d cid %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state, cid); + + return 0; +} + +int cam_ife_csid_ver1_release(void *hw_priv, + void *release_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver1_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_isp_resource_node *res = NULL; + struct cam_ife_csid_ver1_path_cfg *path_cfg; + int rc = 0; + + if (!hw_priv || !release_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + res = (struct cam_isp_resource_node *)release_args; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + return -EINVAL; + } + + mutex_lock(&csid_hw->hw_info->hw_mutex); + + if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH && + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + rc = -EINVAL; + goto end; + } + + if ((res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) || + (res->res_state >= CAM_ISP_RESOURCE_STATE_STREAMING)) { + CAM_WARN(CAM_ISP, + "CSID:%d res type:%d Res %d in state %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, + res->res_state); + goto end; + } + + CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + cam_ife_csid_cid_release(&csid_hw->cid_data[path_cfg->cid], + csid_hw->hw_intf->hw_idx, + path_cfg->cid); + memset(path_cfg, 0, sizeof(*path_cfg)); + + if (csid_hw->counters.csi2_reserve_cnt) + csid_hw->counters.csi2_reserve_cnt--; + if (!csid_hw->counters.csi2_reserve_cnt) { + memset(&csid_hw->rx_cfg, 0, + sizeof(struct cam_ife_csid_rx_cfg)); + csid_hw->event_cb = NULL; + csid_hw->token = NULL; + } + + CAM_DBG(CAM_ISP, + "CSID:%d res type :%d Resource id:%d csi2_reserve_cnt:%d", + csid_hw->hw_intf->hw_idx, res->res_type, res->res_id, + csid_hw->counters.csi2_reserve_cnt); + + res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; +end: + mutex_unlock(&csid_hw->hw_info->hw_mutex); + return rc; +} + +static int cam_ife_csid_ver1_start_rdi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_path_reg_info *path_reg; + struct cam_ife_csid_core_info *core_info; + void __iomem *mem_base; + uint32_t val; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || + res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + core_info = csid_hw->core_info; + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *)core_info->csid_reg; + + path_reg = csid_reg->rdi_reg[res->res_id]; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[0].mem_base; + /* Resume at frame boundary */ + cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + mem_base + path_reg->ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID:%d Rdi res: %d", + csid_hw->hw_intf->hw_idx, res->res_id); + + val = path_reg->fatal_err_mask | path_reg->non_fatal_err_mask | + csid_hw->debug_info.path_mask | + IFE_CSID_VER1_PATH_INFO_RST_DONE; + cam_io_w_mb(val, mem_base + path_reg->irq_mask_addr); + + res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; + return rc; +} + +static int cam_ife_csid_ver1_start_udi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_path_reg_info *path_reg; + struct cam_ife_csid_core_info *core_info; + void __iomem *mem_base; + uint32_t val, id; + + if ((res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) || + (res->res_id < CAM_IFE_PIX_PATH_RES_UDI_0 || + res->res_id > CAM_IFE_PIX_PATH_RES_UDI_2)) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + core_info = csid_hw->core_info; + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *)core_info->csid_reg; + + id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_2; + + path_reg = csid_reg->udi_reg[id]; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d UDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[0].mem_base; + /* Resume at frame boundary */ + cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + mem_base + path_reg->ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID:%d Udi res: %d", + csid_hw->hw_intf->hw_idx, res->res_id); + + val = path_reg->fatal_err_mask | path_reg->non_fatal_err_mask | + csid_hw->debug_info.path_mask | + IFE_CSID_VER1_PATH_INFO_RST_DONE; + cam_io_w_mb(val, mem_base + path_reg->irq_mask_addr); + + res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; + return rc; +} + +static int cam_ife_csid_ver1_start_pix_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + + int rc = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + uint32_t val = 0; + struct cam_ife_csid_ver1_path_cfg *path_cfg; + struct cam_ife_csid_ver1_path_cfg *ipp_path_cfg; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + path_reg = csid_reg->ipp_reg; + else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + path_reg = csid_reg->ppp_reg; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d PIX:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { + + path_reg = csid_reg->ipp_reg; + val = path_reg->halt_master_sel_master_val << + path_reg->halt_master_sel_shift; + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER) { + /* Set start mode as master */ + val |= path_reg->halt_mode_master << + path_reg->halt_mode_shift; + } else if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_SLAVE) { + /* Set start mode as slave */ + val |= path_reg->halt_mode_slave << + path_reg->halt_mode_shift; + } else { + /* Default is internal halt mode */ + val = 0; + } + } else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) { + + path_reg = csid_reg->ppp_reg; + + /* for dual case + * set ppp as slave + * if current csid is set as master set + * start_master_sel_val as 3 + */ + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) { + val = 0; + } else { + val = path_reg->halt_mode_slave << + path_reg->halt_mode_shift; + /* Set halt mode as master */ + + ipp_path_cfg = (struct cam_ife_csid_ver1_path_cfg *) + csid_hw->path_res + [CAM_IFE_PIX_PATH_RES_IPP].res_priv; + + if (ipp_path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER) + val |= path_reg->halt_master_sel_master_val << + path_reg->halt_master_sel_shift; + } + } + + /* + * Resume at frame boundary if Master or No Sync. + * Slave will get resume command from Master. + */ + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER || + path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) + val |= path_reg->resume_frame_boundary; + + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + path_reg->ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID:%d Pix res: %d ctrl val: 0x%x", + csid_hw->hw_intf->hw_idx, + res->res_id, val); + + val = path_reg->fatal_err_mask | path_reg->non_fatal_err_mask | + csid_hw->debug_info.path_mask | + IFE_CSID_VER1_PATH_INFO_RST_DONE; + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + path_reg->irq_mask_addr); + + res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; + return rc; +} + +static int cam_ife_csid_ver1_enable_csi2(struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + uint32_t val = 0; + struct cam_ife_csid_rx_cfg *rx_cfg; + int vc_full_width; + + if (csid_hw->flags.rx_enabled) + return 0; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + soc_info = &csid_hw->hw_info->soc_info; + rx_cfg = &csid_hw->rx_cfg; + + /*Configure Rx cfg0 */ + + val = (rx_cfg->lane_cfg << csi2_reg->lane_cfg_shift) | + ((rx_cfg->lane_num - 1) << csi2_reg->lane_num_shift) | + (rx_cfg->lane_type << csi2_reg->phy_type_shift) | + (rx_cfg->phy_sel << csi2_reg->phy_num_shift); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csi2_reg->cfg0_addr); + + /*Configure Rx cfg1*/ + val = 1 << csi2_reg->misr_enable_shift_val; + val |= 1 << csi2_reg->ecc_correction_shift_en; + + vc_full_width = cam_ife_csid_is_vc_full_width(csid_hw->cid_data); + + if (vc_full_width == 1) { + val |= 1 << csi2_reg->vc_mode_shift_val; + } else if (vc_full_width < 0) { + CAM_ERR(CAM_ISP, "Error VC DT"); + return -EINVAL; + } + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csi2_reg->cfg1_addr); + rc = cam_ife_csid_ver1_hw_reset(csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] hw reset fail", + csid_hw->hw_intf->hw_idx); + return rc; + } + + csid_hw->flags.rx_enabled = true; + + if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) + cam_ife_csid_ver1_init_tpg_hw(csid_hw); + + /* Enable the interrupt based on csid debug info set + * Fatal error mask + * Partly fatal error mask + * Rx reset done irq + */ + val = csi2_reg->fatal_err_mask | csi2_reg->part_fatal_err_mask | + csid_hw->debug_info.rx_mask | IFE_CSID_VER1_RX_RST_DONE; + + /*EPD supported sensors do not send EOT, error will be generated + * if this irq is enabled + */ + if (csid_hw->flags.epd_supported) + val &= ~IFE_CSID_VER1_RX_CPHY_EOT_RECEPTION; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csi2_reg->irq_mask_addr); + cam_ife_csid_ver1_rx_capture_config(csid_hw); + + return rc; +} + +static int cam_ife_csid_ver1_init_config_rdi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + const struct cam_ife_csid_ver1_common_reg_info *cmn_reg = NULL; + uint32_t val; + struct cam_ife_csid_ver1_path_cfg *path_cfg; + struct cam_ife_csid_cid_data *cid_data; + bool is_rpp = false; + void __iomem *mem_base; + struct cam_ife_csid_path_format path_format = {0}; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (!csid_reg->rdi_reg[res->res_id]) { + CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + cmn_reg = csid_reg->cmn_reg; + path_reg = csid_reg->rdi_reg[res->res_id]; + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + cid_data = &csid_hw->cid_data[path_cfg->cid]; + mem_base = soc_info->reg_map[0].mem_base; + is_rpp = path_cfg->crop_enable || path_cfg->drop_enable; + rc = cam_ife_csid_get_format_rdi(path_cfg->in_format, + path_cfg->out_format, &path_format, is_rpp); + if (rc) + return rc; + + /*Configure cfg0: + * Timestamp enable + * VC + * DT + * DT_ID cobination + * Decode Format + * Crop/Drop parameters + * Plain format + * Packing format + */ + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc << + cmn_reg->vc_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt << + cmn_reg->dt_shift_val) | + (path_cfg->cid << cmn_reg->dt_id_shift_val) | + (path_format.decode_fmt << + cmn_reg->decode_format_shift_val); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) + val |= 1 << path_reg->format_measure_en_shift_val; + + val |= (path_cfg->crop_enable << path_reg->crop_h_en_shift_val) | + (path_cfg->crop_enable << + path_reg->crop_v_en_shift_val); + + if (cmn_reg->drop_supported) + val |= (path_cfg->drop_enable << + path_reg->drop_v_en_shift_val) | + (path_cfg->drop_enable << + path_reg->drop_h_en_shift_val); + + if (path_reg->mipi_pack_supported) + val |= path_format.packing_fmt << + path_reg->packing_fmt_shift_val; + + val |= path_format.plain_fmt << path_reg->plain_fmt_shift_val; + + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + /*Configure Multi VC DT combo */ + if (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].valid) { + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].vc << + cmn_reg->multi_vcdt_vc1_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].dt << + cmn_reg->multi_vcdt_dt1_shift_val) | + (1 << cmn_reg->multi_vcdt_en_shift_val); + + cam_io_w_mb(val, mem_base + path_reg->multi_vcdt_cfg0_addr); + } + + val = 0; + /*configure cfg1 addr + * Timestamp strobe selection + */ + val |= (1 << path_reg->timestamp_en_shift_val) | + (cmn_reg->timestamp_strobe_val << + cmn_reg->timestamp_stb_sel_shift_val); + + cam_io_w_mb(val, mem_base + path_reg->cfg1_addr); + + if (path_cfg->crop_enable) { + val = (((path_cfg->end_pixel & cmn_reg->crop_pix_start_mask) << + cmn_reg->crop_shift_val) | + (path_cfg->start_pixel & cmn_reg->crop_pix_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->hcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + + val = (((path_cfg->end_line & cmn_reg->crop_line_start_mask) << + csid_reg->cmn_reg->crop_shift_val) | + (path_cfg->start_line & cmn_reg->crop_line_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->vcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + } + + /* set frame drop pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->frm_drop_period_addr); + cam_io_w_mb(0, mem_base + path_reg->frm_drop_pattern_addr); + /* set irq sub sample pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->irq_subsample_period_addr); + cam_io_w_mb(0, mem_base + path_reg->irq_subsample_pattern_addr); + + /*TODO Need to check for any hw errata like 480 and 580*/ + /* set pxl drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->pix_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->pix_drop_period_addr); + + /* set line drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->line_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->line_drop_period_addr); + + if (path_reg->overflow_ctrl_en) { + val = path_reg->overflow_ctrl_en | + path_reg->overflow_ctrl_mode_val; + cam_io_w_mb(val, mem_base + path_reg->err_recovery_cfg0_addr); + } + + if (path_cfg->fmt_measure_enable) { + val = (path_cfg->sensor_height & + cmn_reg->fmt_measure_num_line_mask) << + cmn_reg->fmt_measure_num_lines_shift_val; + if (path_format.decode_fmt == 0xf) + val |= (__KERNEL_DIV_ROUND_UP( + (path_cfg->sensor_width * + path_format.bits_per_pxl), 8) & + cmn_reg->fmt_measure_num_pxl_mask); + + else + val |= (path_cfg->sensor_width & + cmn_reg->fmt_measure_num_pxl_mask); + + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg1_addr); + cam_io_w_mb(cmn_reg->measure_pixel_line_en_mask, + mem_base + path_reg->format_measure_cfg0_addr); + } + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg0_addr); + } + + /* Enable the RDI path */ + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + val |= (1 << cmn_reg->path_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; + + return rc; +} + +static int cam_ife_csid_ver1_init_config_udi_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + const struct cam_ife_csid_ver1_common_reg_info *cmn_reg = NULL; + uint32_t val; + struct cam_ife_csid_ver1_path_cfg *path_cfg; + struct cam_ife_csid_cid_data *cid_data; + bool is_rpp = false; + void __iomem *mem_base; + struct cam_ife_csid_path_format path_format = {0}; + uint32_t id; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + id = res->res_id - CAM_IFE_PIX_PATH_RES_UDI_0; + + if (!csid_reg->udi_reg[id]) { + CAM_ERR(CAM_ISP, "CSID:%d UDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + cmn_reg = csid_reg->cmn_reg; + path_reg = csid_reg->udi_reg[id]; + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + cid_data = &csid_hw->cid_data[path_cfg->cid]; + mem_base = soc_info->reg_map[0].mem_base; + is_rpp = path_cfg->crop_enable || path_cfg->drop_enable; + rc = cam_ife_csid_get_format_rdi(path_cfg->in_format, + path_cfg->out_format, &path_format, is_rpp); + if (rc) + return rc; + + /*Configure cfg0: + * Timestamp enable + * VC + * DT + * DT_ID cobination + * Decode Format + * Crop/Drop parameters + * Plain format + * Packing format + */ + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc << + cmn_reg->vc_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt << + cmn_reg->dt_shift_val) | + (path_cfg->cid << cmn_reg->dt_id_shift_val) | + (path_format.decode_fmt << cmn_reg->decode_format_shift_val); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) + val |= 1 << path_reg->format_measure_en_shift_val; + + val |= (path_cfg->crop_enable << path_reg->crop_h_en_shift_val) | + (path_cfg->crop_enable << + path_reg->crop_v_en_shift_val); + + if (cmn_reg->drop_supported) + val |= (path_cfg->drop_enable << + path_reg->drop_v_en_shift_val) | + (path_cfg->drop_enable << + path_reg->drop_h_en_shift_val); + + if (path_reg->mipi_pack_supported) + val |= path_format.packing_fmt << + path_reg->packing_fmt_shift_val; + + val |= path_format.plain_fmt << path_reg->plain_fmt_shift_val; + + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + val = 0; + /*configure cfg1 addr + * Timestamp strobe selection + */ + val |= (1 << path_reg->timestamp_en_shift_val) | + (cmn_reg->timestamp_strobe_val << + cmn_reg->timestamp_stb_sel_shift_val); + + cam_io_w_mb(val, mem_base + path_reg->cfg1_addr); + + if (path_cfg->crop_enable) { + val = (((path_cfg->end_pixel & cmn_reg->crop_pix_start_mask) << + cmn_reg->crop_shift_val) | + (path_cfg->start_pixel & cmn_reg->crop_pix_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->hcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + + val = (((path_cfg->end_line & cmn_reg->crop_line_start_mask) << + csid_reg->cmn_reg->crop_shift_val) | + (path_cfg->start_line & cmn_reg->crop_line_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->vcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + } + + /* set frame drop pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->frm_drop_period_addr); + cam_io_w_mb(0, mem_base + path_reg->frm_drop_pattern_addr); + /* set irq sub sample pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->irq_subsample_period_addr); + cam_io_w_mb(0, mem_base + path_reg->irq_subsample_pattern_addr); + + /*TODO Need to check for any hw errata like 480 and 580*/ + /* set pxl drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->pix_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->pix_drop_period_addr); + + /* set line drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->line_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->line_drop_period_addr); + + /* Enable the UDI path */ + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + val |= (1 << cmn_reg->path_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + if (path_reg->overflow_ctrl_en) { + val = path_reg->overflow_ctrl_en | + path_reg->overflow_ctrl_mode_val; + cam_io_w_mb(val, mem_base + path_reg->err_recovery_cfg0_addr); + } + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg0_addr); + } + + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; + return rc; +} + +static int cam_ife_csid_ver1_init_config_pxl_path( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + const struct cam_ife_csid_ver1_common_reg_info *cmn_reg = NULL; + uint32_t val = 0; + struct cam_ife_csid_ver1_path_cfg *path_cfg; + struct cam_ife_csid_cid_data *cid_data; + void __iomem *mem_base; + struct cam_ife_csid_path_format path_format = {0}; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + path_reg = csid_reg->ipp_reg; + else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + path_reg = csid_reg->ppp_reg; + + if (!path_reg) + return -EINVAL; + + cmn_reg = csid_reg->cmn_reg; + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + cid_data = &csid_hw->cid_data[path_cfg->cid]; + mem_base = soc_info->reg_map[0].mem_base; + + rc = cam_ife_csid_get_format_ipp_ppp(path_cfg->in_format, + &path_format); + + /*Configure: + * VC + * DT + * DT_ID cobination + * Decode Format + * Early eof + * timestamp enable + * crop/drop enable + * Binning + */ + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc << + cmn_reg->vc_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt << + cmn_reg->dt_shift_val) | + (path_cfg->cid << cmn_reg->dt_id_shift_val) | + (path_format.decode_fmt << + cmn_reg->decode_format_shift_val); + + /*enable early eof based on crop enable */ + if (!(csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_DISABLE_EARLY_EOF) && + cmn_reg->early_eof_supported && + path_cfg->crop_enable) + val |= (1 << path_reg->early_eof_en_shift_val); + + if (cmn_reg->drop_supported) + val |= (path_cfg->drop_enable << + path_reg->drop_v_en_shift_val) | + (path_cfg->drop_enable << + path_reg->drop_h_en_shift_val); + + val |= (1 << path_reg->pix_store_en_shift_val) | + (1 << path_reg->timestamp_en_shift_val); + + val |= (path_cfg->crop_enable << path_reg->crop_h_en_shift_val) | + (path_cfg->crop_enable << + path_reg->crop_v_en_shift_val); + + if ((path_reg->binning_supported & CAM_IFE_CSID_BIN_HORIZONTAL) && + path_cfg->horizontal_bin) + val |= 1 << path_reg->bin_h_en_shift_val; + + if ((path_reg->binning_supported & CAM_IFE_CSID_BIN_VERTICAL) && + path_cfg->vertical_bin) + val |= 1 << path_reg->bin_v_en_shift_val; + + if ((path_reg->binning_supported & CAM_IFE_CSID_BIN_QCFA) && + path_cfg->qcfa_bin) + val |= 1 << path_reg->bin_qcfa_en_shift_val; + + if ((path_cfg->qcfa_bin || path_cfg->vertical_bin || + path_cfg->horizontal_bin) && path_reg->binning_supported) + val |= 1 << path_reg->bin_en_shift_val; + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) + val |= 1 << path_reg->format_measure_en_shift_val; + + CAM_DBG(CAM_ISP, "CSID[%u] cfg0_addr val %x", + csid_hw->hw_intf->hw_idx, val); + + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + /*Configure Multi VC DT combo */ + if (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].valid) { + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].vc << + cmn_reg->multi_vcdt_vc1_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].dt << + cmn_reg->multi_vcdt_dt1_shift_val) | + (1 << cmn_reg->multi_vcdt_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->multi_vcdt_cfg0_addr); + } + + /*configure cfg1 addr + * timestamp strobe selection + */ + + val = cmn_reg->timestamp_strobe_val << + cmn_reg->timestamp_stb_sel_shift_val; + + cam_io_w_mb(val, mem_base + path_reg->cfg1_addr); + + if (path_cfg->crop_enable) { + val = (((path_cfg->end_pixel & cmn_reg->crop_pix_start_mask) << + cmn_reg->crop_shift_val) | + (path_cfg->start_pixel & cmn_reg->crop_pix_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->hcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + + val = (((path_cfg->end_line & cmn_reg->crop_line_start_mask) << + csid_reg->cmn_reg->crop_shift_val) | + (path_cfg->start_line & cmn_reg->crop_line_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->vcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + } + + /* set frame drop pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->frm_drop_period_addr); + cam_io_w_mb(0, mem_base + path_reg->frm_drop_pattern_addr); + /* set irq sub sample pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->irq_subsample_period_addr); + cam_io_w_mb(0, mem_base + path_reg->irq_subsample_pattern_addr); + /* set pxl drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->pix_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->pix_drop_period_addr); + /* set line drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->line_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->line_drop_period_addr); + + if (path_reg->overflow_ctrl_en) { + val = path_reg->overflow_ctrl_en | + path_reg->overflow_ctrl_mode_val; + cam_io_w_mb(val, mem_base + path_reg->err_recovery_cfg0_addr); + } + + if (path_cfg->fmt_measure_enable) { + val = (path_cfg->sensor_height & + cmn_reg->fmt_measure_num_line_mask) << + cmn_reg->fmt_measure_num_lines_shift_val; + val |= path_cfg->sensor_width & + csid_reg->cmn_reg->fmt_measure_num_pxl_mask; + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg1_addr); + cam_io_w_mb(cmn_reg->measure_pixel_line_en_mask, mem_base + + path_reg->format_measure_cfg0_addr); + } + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, + mem_base + path_reg->format_measure_cfg0_addr); + } + + /* Enable the Pxl path */ + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + val |= (1 << cmn_reg->path_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; + + return rc; +} + +static int cam_ife_csid_ver1_enable_hw(struct cam_ife_csid_ver1_hw *csid_hw) +{ + int rc = 0; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + uint32_t clk_lvl, i, val; + unsigned long flags; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + /* overflow check before increment */ + if (csid_hw->hw_info->open_count == UINT_MAX) { + CAM_ERR(CAM_ISP, "CSID:%d Open count reached max", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + /* Increment ref Count */ + csid_hw->hw_info->open_count++; + + if (csid_hw->hw_info->open_count > 1) { + CAM_DBG(CAM_ISP, "CSID hw has already been enabled"); + return rc; + } + + rc = cam_soc_util_get_clk_level(soc_info, csid_hw->clk_rate, + soc_info->src_clk_idx, &clk_lvl); + CAM_DBG(CAM_ISP, "CSID clock lvl %u", clk_lvl); + + rc = cam_ife_csid_enable_soc_resources(soc_info, clk_lvl); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed", + csid_hw->hw_intf->hw_idx); + goto err; + } + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP; + + rc = cam_ife_csid_ver1_global_reset(csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] global reset failed"); + goto disable_soc; + } + + + /* Clear IRQs */ + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_clear_addr); + + cam_io_w_mb(csid_reg->csi2_reg->irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->irq_clear_addr); + + if (csid_reg->cmn_reg->num_pix) + cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_clear_addr); + + if (csid_reg->cmn_reg->num_ppp) + cam_io_w_mb(csid_reg->cmn_reg->ppp_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_clear_addr); + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) + cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->irq_clear_addr); + + for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) + cam_io_w_mb(csid_reg->cmn_reg->udi_irq_mask_all, + soc_info->reg_map[0].mem_base + + csid_reg->udi_reg[i]->irq_clear_addr); + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + + /* Read hw version */ + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->hw_version_addr); + + CAM_DBG(CAM_ISP, "CSID:%d Enabled CSID HW version: 0x%x", + csid_hw->hw_intf->hw_idx, val); + memset(&csid_hw->timestamp, 0, sizeof(struct cam_ife_csid_timestamp)); + spin_lock_irqsave(&csid_hw->lock_state, flags); + csid_hw->flags.fatal_err_detected = false; + csid_hw->flags.device_enabled = true; + spin_unlock_irqrestore(&csid_hw->lock_state, flags); + cam_tasklet_start(csid_hw->tasklet); + + return rc; + +disable_soc: + cam_ife_csid_disable_soc_resources(soc_info); + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; +err: + csid_hw->hw_info->open_count--; + return rc; +} + +int cam_ife_csid_ver1_init_hw(void *hw_priv, + void *init_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver1_hw *csid_hw = NULL; + struct cam_isp_resource_node *res; + struct cam_hw_info *hw_info; + int rc = 0; + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + + if (!hw_priv || !init_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + rc = cam_ife_csid_ver1_enable_hw(csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID:%d Enable hw fail", + csid_hw->hw_intf->hw_idx); + return rc; + } + + mutex_lock(&csid_hw->hw_info->hw_mutex); + res = (struct cam_isp_resource_node *)init_args; + if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + rc = -EINVAL; + goto end; + } + + if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) && + (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) { + CAM_ERR(CAM_ISP, + "CSID:%d res type:%d res_id:%dInvalid state %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + rc = -EINVAL; + goto end; + } + + CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); + res = (struct cam_isp_resource_node *)init_args; + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + case CAM_IFE_PIX_PATH_RES_PPP: + rc = cam_ife_csid_ver1_init_config_pxl_path( + csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver1_init_config_rdi_path( + csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_UDI_0: + case CAM_IFE_PIX_PATH_RES_UDI_1: + case CAM_IFE_PIX_PATH_RES_UDI_2: + rc = cam_ife_csid_ver1_init_config_udi_path( + csid_hw, res); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid Res id %d", + csid_hw->hw_intf->hw_idx, res->res_id); + break; + } + + rc = cam_ife_csid_ver1_hw_reset(csid_hw); + + if (rc < 0) + CAM_ERR(CAM_ISP, "CSID:%d Failed in HW reset", + csid_hw->hw_intf->hw_idx); + + mutex_unlock(&csid_hw->hw_info->hw_mutex); + + return 0; +end: + mutex_unlock(&csid_hw->hw_info->hw_mutex); + return rc; +} + +static int cam_ife_csid_ver1_disable_csi2( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + if (!csid_hw->flags.rx_enabled) { + CAM_DBG(CAM_ISP, "CSID:%d Rx already disabled", + csid_hw->hw_intf->hw_idx); + return 0; + } + + /* Disable the CSI2 rx inerrupts */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->irq_mask_addr); + + /* Reset the Rx CFG registers */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->cfg0_addr); + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->cfg1_addr); + csid_hw->flags.rx_enabled = false; + + CAM_DBG(CAM_ISP, "CSID:%d Disable csi2 rx", + csid_hw->hw_intf->hw_idx); + + return 0; +} + +static int cam_ife_csid_ver1_disable_hw( + struct cam_ife_csid_ver1_hw *csid_hw) +{ + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + int rc = 0; + unsigned long flags; + + /* Check for refcount */ + if (!csid_hw->hw_info->open_count) { + CAM_WARN(CAM_ISP, "Unbalanced disable_hw"); + return rc; + } + + /* Decrement ref Count */ + csid_hw->hw_info->open_count--; + + if (csid_hw->hw_info->open_count) + return rc; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + cam_ife_csid_ver1_disable_csi2(csid_hw); + cam_ife_csid_ver1_global_reset(csid_hw); + /* Disable the top IRQ interrupt */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_mask_addr); + + rc = cam_ife_csid_disable_soc_resources(soc_info); + if (rc) + CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed", + csid_hw->hw_intf->hw_idx); + + cam_tasklet_stop(csid_hw->tasklet); + spin_lock_irqsave(&csid_hw->lock_state, flags); + csid_hw->flags.device_enabled = false; + spin_unlock_irqrestore(&csid_hw->lock_state, flags); + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; + csid_hw->counters.error_irq_count = 0; + + return rc; +} + +int cam_ife_csid_ver1_deinit_hw(void *hw_priv, + void *deinit_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver1_hw *csid_hw = NULL; + struct cam_isp_resource_node *res; + struct cam_hw_info *hw_info; + int rc = 0; + + if (!hw_priv || !deinit_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "CSID:Invalid arguments"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + res = (struct cam_isp_resource_node *)deinit_args; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d", + csid_hw->hw_intf->hw_idx, + res->res_type); + return -EINVAL; + } + + if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { + CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state", + csid_hw->hw_intf->hw_idx, + res->res_id); + return -EINVAL; + } + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + case CAM_IFE_PIX_PATH_RES_PPP: + rc = cam_ife_csid_ver1_deinit_pxl_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver1_deinit_rdi_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_UDI_0: + case CAM_IFE_PIX_PATH_RES_UDI_1: + case CAM_IFE_PIX_PATH_RES_UDI_2: + rc = cam_ife_csid_ver1_deinit_udi_path(csid_hw, res); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + break; + } + + /* Disable CSID HW */ + cam_ife_csid_ver1_disable_hw(csid_hw); + CAM_DBG(CAM_ISP, "De-Init CSID %d Path: %d", + csid_hw->hw_intf->hw_idx, res->res_id); + + return rc; +} + +int cam_ife_csid_ver1_start(void *hw_priv, void *start_args, + uint32_t arg_size) +{ + struct cam_ife_csid_ver1_hw *csid_hw = NULL; + struct cam_isp_resource_node *res; + struct cam_hw_info *hw_info; + int rc = 0; + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + res = (struct cam_isp_resource_node *)start_args; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + rc = -EINVAL; + goto end; + } + + if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + rc = -EINVAL; + goto end; + } + + csid_hw->flags.sof_irq_triggered = false; + csid_hw->counters.irq_debug_cnt = 0; + + CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); + + cam_ife_csid_ver1_enable_csi2(csid_hw); + + if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) + cam_ife_csid_ver1_tpg_start(csid_hw); + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + case CAM_IFE_PIX_PATH_RES_PPP: + rc = cam_ife_csid_ver1_start_pix_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver1_start_rdi_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_UDI_0: + case CAM_IFE_PIX_PATH_RES_UDI_1: + case CAM_IFE_PIX_PATH_RES_UDI_2: + rc = cam_ife_csid_ver1_start_udi_path(csid_hw, res); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + rc = -EINVAL; + break; + } + + if (rc) + CAM_ERR(CAM_ISP, "CSID:%d start fail res type:%d res id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); +end: + return rc; +} + +static int cam_ife_csid_poll_stop_status( + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t res_mask) +{ + int rc = 0, id; + uint32_t status_addr = 0, val = 0, res_id = 0; + const struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + for (; res_id < CAM_IFE_PIX_PATH_RES_MAX; res_id++, res_mask >>= 1) { + if ((res_mask & 0x1) == 0) + continue; + val = 0; + + if (res_id == CAM_IFE_PIX_PATH_RES_IPP) { + status_addr = + csid_reg->ipp_reg->status_addr; + } else if (res_id == CAM_IFE_PIX_PATH_RES_PPP) { + status_addr = + csid_reg->ppp_reg->status_addr; + } else if (res_id == CAM_IFE_PIX_PATH_RES_RDI_0 || + res_id == CAM_IFE_PIX_PATH_RES_RDI_1 || + res_id == CAM_IFE_PIX_PATH_RES_RDI_2 || + res_id == CAM_IFE_PIX_PATH_RES_RDI_3 || + res_id == CAM_IFE_PIX_PATH_RES_RDI_4) { + status_addr = + csid_reg->rdi_reg[res_id]->status_addr; + } else if (res_id == CAM_IFE_PIX_PATH_RES_UDI_0 || + res_id == CAM_IFE_PIX_PATH_RES_UDI_1 || + res_id == CAM_IFE_PIX_PATH_RES_UDI_2) { + id = res_id - CAM_IFE_PIX_PATH_RES_UDI_0; + status_addr = + csid_reg->udi_reg[id]->status_addr; + } else { + CAM_ERR(CAM_ISP, "Invalid res_id: %u", res_id); + rc = -EINVAL; + break; + } + + CAM_DBG(CAM_ISP, "start polling CSID:%d res_id:%d", + csid_hw->hw_intf->hw_idx, res_id); + + rc = readl_poll_timeout(soc_info->reg_map[0].mem_base + + status_addr, val, (val & 0x1) == 0x1, + CAM_IFE_CSID_TIMEOUT_SLEEP_US, + CAM_IFE_CSID_TIMEOUT_ALL_US); + if (rc < 0) { + CAM_ERR(CAM_ISP, "CSID:%d res:%d halt failed rc %d", + csid_hw->hw_intf->hw_idx, res_id, rc); + rc = -ETIMEDOUT; + break; + } + CAM_DBG(CAM_ISP, "End polling CSID:%d res_id:%d", + csid_hw->hw_intf->hw_idx, res_id); + } + + return rc; +} + +int cam_ife_csid_ver1_stop(void *hw_priv, + void *stop_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver1_hw *csid_hw = NULL; + struct cam_isp_resource_node *res; + struct cam_hw_info *hw_info; + int rc = 0; + uint32_t i; + struct cam_csid_hw_stop_args *csid_stop; + uint32_t res_mask = 0; + + if (!hw_priv || !stop_args || + (arg_size != sizeof(struct cam_csid_hw_stop_args))) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + csid_stop = (struct cam_csid_hw_stop_args *) stop_args; + + if (!csid_stop->num_res) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + CAM_DBG(CAM_ISP, "CSID:%d num_res %d", + csid_hw->hw_intf->hw_idx, + csid_stop->num_res); + cam_ife_csid_ver1_tpg_stop(csid_hw); + /* Stop the resource first */ + for (i = 0; i < csid_stop->num_res; i++) { + + res = csid_stop->node_res[i]; + res_mask |= (1 << res->res_id); + CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id); + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + case CAM_IFE_PIX_PATH_RES_PPP: + rc = cam_ife_csid_ver1_stop_pxl_path(csid_hw, + res, csid_stop->stop_cmd); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver1_stop_rdi_path(csid_hw, + res, csid_stop->stop_cmd); + break; + case CAM_IFE_PIX_PATH_RES_UDI_0: + case CAM_IFE_PIX_PATH_RES_UDI_1: + case CAM_IFE_PIX_PATH_RES_UDI_2: + rc = cam_ife_csid_ver1_stop_udi_path(csid_hw, + res, csid_stop->stop_cmd); + break; + default: + CAM_ERR(CAM_ISP, "Invalid res_id: %u", + res->res_id); + break; + } + } + + if (res_mask) + rc = cam_ife_csid_poll_stop_status(csid_hw, res_mask); + + for (i = 0; i < csid_stop->num_res; i++) { + res = csid_stop->node_res[i]; + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; + } + + return rc; +} + +int cam_ife_csid_ver1_read(void *hw_priv, + void *read_args, uint32_t arg_size) +{ + CAM_ERR(CAM_ISP, "CSID: un supported"); + + return -EINVAL; +} + +int cam_ife_csid_ver1_write(void *hw_priv, + void *write_args, uint32_t arg_size) +{ + CAM_ERR(CAM_ISP, "CSID: un supported"); + return -EINVAL; +} + +static int cam_ife_csid_ver1_sof_irq_debug( + struct cam_ife_csid_ver1_hw *csid_hw, + void *cmd_args) +{ + int i = 0; + uint32_t val = 0; + bool sof_irq_enable = false; + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_ver1_reg_info *csid_reg; + + if (*((uint32_t *)cmd_args) == 1) + sof_irq_enable = true; + + if (csid_hw->hw_info->hw_state == + CAM_HW_STATE_POWER_DOWN) { + CAM_WARN(CAM_ISP, + "CSID powered down unable to %s sof irq", + (sof_irq_enable) ? "enable" : "disable"); + return 0; + } + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + for (i = 0; i < csid_reg->cmn_reg->num_pix; i++) { + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_mask_addr); + + if (sof_irq_enable) + val |= IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + else + val &= ~IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_mask_addr); + } + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->irq_mask_addr); + + if (sof_irq_enable) + val |= IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + else + val &= ~IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->irq_mask_addr); + } + + for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->udi_reg[i]->irq_mask_addr); + + if (sof_irq_enable) + val |= IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + else + val &= ~IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->udi_reg[i]->irq_mask_addr); + } + + if (sof_irq_enable) { + csid_hw->debug_info.path_mask |= + IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + csid_hw->debug_info.debug_val |= + CAM_IFE_CSID_DEBUG_ENABLE_SOF_IRQ; + csid_hw->flags.sof_irq_triggered = true; + } else { + csid_hw->debug_info.path_mask &= + ~IFE_CSID_VER1_PATH_INFO_INPUT_SOF; + csid_hw->debug_info.debug_val &= + ~CAM_IFE_CSID_DEBUG_ENABLE_SOF_IRQ; + csid_hw->flags.sof_irq_triggered = false; + } + + CAM_INFO(CAM_ISP, "SOF freeze: CSID SOF irq %s", + (sof_irq_enable) ? "enabled" : "disabled"); + + return 0; +} + + +static int cam_ife_csid_ver1_print_hbi_vbi( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + uint32_t hbi, vbi; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH || + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + return -EINVAL; + } + + if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d", + csid_hw->hw_intf->hw_idx, + csid_hw->hw_info->hw_state); + return -EINVAL; + } + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + path_reg = csid_reg->ipp_reg; + break; + case CAM_IFE_PIX_PATH_RES_PPP: + path_reg = csid_reg->ppp_reg; + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + path_reg = csid_reg->rdi_reg[res->res_id]; + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d invalid res %d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d invalid res %d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + path_reg->format_measure1_addr); + vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + path_reg->format_measure2_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID: %d res: %d hbi %u vbi %u", + res->res_id, hbi, vbi); + + return 0; +} + +static int cam_ife_csid_ver1_get_time_stamp( + struct cam_ife_csid_ver1_hw *csid_hw, void *cmd_args) +{ + struct cam_isp_resource_node *res = NULL; + uint64_t time_lo, time_hi; + struct cam_hw_soc_info *soc_info; + struct cam_csid_get_time_stamp_args *timestamp_args; + struct cam_ife_csid_ver1_reg_info *csid_reg; + uint64_t time_delta; + struct timespec64 ts; + uint32_t curr_0_sof_addr, curr_1_sof_addr; + + timestamp_args = (struct cam_csid_get_time_stamp_args *)cmd_args; + res = timestamp_args->node_res; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH || + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + return -EINVAL; + } + + if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d", + csid_hw->hw_intf->hw_idx, + csid_hw->hw_info->hw_state); + return -EINVAL; + } + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + curr_0_sof_addr = csid_reg->ipp_reg->timestamp_curr0_sof_addr; + curr_1_sof_addr = csid_reg->ipp_reg->timestamp_curr1_sof_addr; + break; + case CAM_IFE_PIX_PATH_RES_PPP: + curr_0_sof_addr = csid_reg->ppp_reg->timestamp_curr0_sof_addr; + curr_1_sof_addr = csid_reg->ppp_reg->timestamp_curr1_sof_addr; + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + curr_0_sof_addr = + csid_reg->rdi_reg + [res->res_id]->timestamp_curr0_sof_addr; + curr_1_sof_addr = + csid_reg->rdi_reg + [res->res_id]->timestamp_curr1_sof_addr; + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d invalid res %d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + time_hi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + curr_1_sof_addr); + time_lo = cam_io_r_mb(soc_info->reg_map[0].mem_base + + curr_0_sof_addr); + timestamp_args->time_stamp_val = (time_hi << 32) | time_lo; + + timestamp_args->time_stamp_val = mul_u64_u32_div( + timestamp_args->time_stamp_val, + CAM_IFE_CSID_QTIMER_MUL_FACTOR, + CAM_IFE_CSID_QTIMER_DIV_FACTOR); + + time_delta = timestamp_args->time_stamp_val - + csid_hw->timestamp.prev_sof_ts; + + if (!csid_hw->timestamp.prev_boot_ts) { + ktime_get_boottime_ts64(&ts); + timestamp_args->boot_timestamp = + (uint64_t)((ts.tv_sec * 1000000000) + + ts.tv_nsec); + } else { + timestamp_args->boot_timestamp = + csid_hw->timestamp.prev_boot_ts + time_delta; + } + + CAM_DBG(CAM_ISP, "timestamp:%lld", + timestamp_args->boot_timestamp); + csid_hw->timestamp.prev_sof_ts = timestamp_args->time_stamp_val; + csid_hw->timestamp.prev_boot_ts = timestamp_args->boot_timestamp; + + return 0; +} + +static int cam_ife_csid_ver1_set_csid_clock( + struct cam_ife_csid_ver1_hw *csid_hw, + void *cmd_args) +{ + struct cam_ife_csid_clock_update_args *clk_update = NULL; + + if (!csid_hw) + return -EINVAL; + + clk_update = + (struct cam_ife_csid_clock_update_args *)cmd_args; + + csid_hw->clk_rate = clk_update->clk_rate; + CAM_INFO(CAM_ISP, "CSID clock rate %llu", csid_hw->clk_rate); + + return 0; +} + +int cam_ife_csid_ver1_set_csid_qcfa( + struct cam_ife_csid_ver1_hw *csid_hw, + void *cmd_args) +{ + struct cam_ife_csid_ver1_path_cfg *path_cfg = NULL; + struct cam_ife_csid_qcfa_update_args *qcfa_update = NULL; + struct cam_isp_resource_node *res = NULL; + + if (!csid_hw || !cmd_args) { + CAM_ERR(CAM_ISP, "Invalid param %pK %pK", + csid_hw, cmd_args); + return -EINVAL; + } + + qcfa_update = + (struct cam_ife_csid_qcfa_update_args *)cmd_args; + res = qcfa_update->res; + + if (!res) { + CAM_ERR(CAM_ISP, "CSID[%u] NULL res", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + + if (!path_cfg) { + CAM_ERR(CAM_ISP, "CSID[%u] Invalid res_id %u", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + path_cfg->qcfa_bin = qcfa_update->qcfa_binning; + + CAM_DBG(CAM_ISP, "CSID %u QCFA binning %d", + csid_hw->hw_intf->hw_idx, + path_cfg->qcfa_bin); + + return 0; +} + +static int cam_ife_csid_ver1_dump_hw( + struct cam_ife_csid_ver1_hw *csid_hw, void *cmd_args) +{ + int i; + uint8_t *dst; + uint32_t *addr, *start; + uint32_t min_len; + uint32_t num_reg; + size_t remain_len; + struct cam_isp_hw_dump_header *hdr; + struct cam_isp_hw_dump_args *dump_args = + (struct cam_isp_hw_dump_args *)cmd_args; + struct cam_hw_soc_info *soc_info; + + if (!dump_args) { + CAM_ERR(CAM_ISP, "Invalid args"); + return -EINVAL; + } + if (!dump_args->cpu_addr || !dump_args->buf_len) { + CAM_ERR(CAM_ISP, + "Invalid params %pK %zu", + (void *)dump_args->cpu_addr, + dump_args->buf_len); + return -EINVAL; + } + soc_info = &csid_hw->hw_info->soc_info; + if (dump_args->buf_len <= dump_args->offset) { + CAM_WARN(CAM_ISP, + "Dump offset overshoot offset %zu buf_len %zu", + dump_args->offset, dump_args->buf_len); + return -ENOSPC; + } + min_len = soc_info->reg_map[0].size + + sizeof(struct cam_isp_hw_dump_header) + + sizeof(uint32_t); + remain_len = dump_args->buf_len - dump_args->offset; + if (remain_len < min_len) { + CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu, min %u", + remain_len, min_len); + return -ENOSPC; + } + dst = (uint8_t *)dump_args->cpu_addr + dump_args->offset; + hdr = (struct cam_isp_hw_dump_header *)dst; + scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "CSID_REG:"); + addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); + + start = addr; + num_reg = soc_info->reg_map[0].size/4; + hdr->word_size = sizeof(uint32_t); + *addr = soc_info->index; + addr++; + for (i = 0; i < num_reg; i++) { + addr[0] = soc_info->mem_block[0]->start + (i*4); + addr[1] = cam_io_r(soc_info->reg_map[0].mem_base + + (i*4)); + addr += 2; + } + hdr->size = hdr->word_size * (addr - start); + dump_args->offset += hdr->size + + sizeof(struct cam_isp_hw_dump_header); + CAM_DBG(CAM_ISP, "offset %zu", dump_args->offset); + return 0; +} + +static int cam_ife_csid_ver1_set_sensor_dimension( + struct cam_ife_csid_ver1_hw *csid_hw, void *cmd_args) +{ + struct cam_ife_sensor_dimension_update_args *update_args = NULL; + struct cam_isp_resource_node *res = NULL; + struct cam_ife_csid_ver1_path_cfg *path_cfg = NULL; + + if (!csid_hw || !cmd_args) { + CAM_ERR(CAM_ISP, "Invalid param %pK %pK", + csid_hw, cmd_args); + return -EINVAL; + } + + update_args = + (struct cam_ife_sensor_dimension_update_args *)cmd_args; + + res = update_args->res; + + if (!res) { + CAM_ERR(CAM_ISP, "CSID[%d] NULL res", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + + if (!path_cfg) { + CAM_ERR(CAM_ISP, "CSID[%d] Invalid res_id %u", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + path_cfg->fmt_measure_enable = update_args->sensor_data.measure_enabled; + path_cfg->sensor_width = update_args->sensor_data.width; + path_cfg->sensor_height = update_args->sensor_data.height; + + CAM_DBG(CAM_ISP, + "CSID[%d] path[%d] width %u height %u", + csid_hw->hw_intf->hw_idx, res->res_id, + path_cfg->sensor_width, + path_cfg->sensor_height); + + return 0; +} + +static int cam_ife_csid_log_acquire_data( + struct cam_ife_csid_ver1_hw *csid_hw, void *cmd_args) +{ + struct cam_isp_resource_node *res = NULL; + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_ver1_path_cfg *path_cfg = NULL; + struct cam_ife_csid_ver1_path_reg_info *rdi_reg = NULL; + uint32_t byte_cnt_ping, byte_cnt_pong; + + res = (struct cam_isp_resource_node *)cmd_args; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) { + CAM_ERR(CAM_ISP, + "CSID:%d invalid res id:%d res type: %d state:%d", + csid_hw->hw_intf->hw_idx, res->res_id, res->res_type, + res->res_state); + return -EINVAL; + } + + path_cfg = (struct cam_ife_csid_ver1_path_cfg *)res->res_priv; + /* Dump all the acquire data for this hardware */ + CAM_INFO(CAM_ISP, + "CSID:%d res id:%d type:%d state:%d in f:%d out f:%d st pix:%d end pix:%d st line:%d end line:%d h bin:%d qcfa bin:%d", + csid_hw->hw_intf->hw_idx, res->res_id, res->res_type, + res->res_type, path_cfg->in_format, path_cfg->out_format, + path_cfg->start_pixel, path_cfg->end_pixel, + path_cfg->start_line, path_cfg->end_line, + path_cfg->horizontal_bin, path_cfg->qcfa_bin); + + if (res->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0 && + res->res_id <= CAM_IFE_PIX_PATH_RES_RDI_3) { + rdi_reg = csid_reg->rdi_reg[res->res_id]; + /* read total number of bytes transmitted through RDI */ + byte_cnt_ping = cam_io_r_mb(soc_info->reg_map[0].mem_base + + rdi_reg->byte_cntr_ping_addr); + byte_cnt_pong = cam_io_r_mb(soc_info->reg_map[0].mem_base + + rdi_reg->byte_cntr_pong_addr); + CAM_INFO(CAM_ISP, + "CSID:%d res id:%d byte cnt val ping:%d pong:%d", + csid_hw->hw_intf->hw_idx, res->res_id, + byte_cnt_ping, byte_cnt_pong); + } + + return 0; +} + +static int cam_ife_csid_ver1_dump_csid_clock( + struct cam_ife_csid_ver1_hw *csid_hw, void *cmd_args) +{ + if (!csid_hw) + return -EINVAL; + + CAM_INFO(CAM_ISP, "CSID:%d clock rate %llu", + csid_hw->hw_intf->hw_idx, + csid_hw->clk_rate); + + return 0; +} + +static int cam_ife_csid_ver1_process_cmd(void *hw_priv, + uint32_t cmd_type, void *cmd_args, uint32_t arg_size) +{ + int rc = 0; + struct cam_ife_csid_ver1_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_isp_resource_node *res = NULL; + + if (!hw_priv || !cmd_args) { + CAM_ERR(CAM_ISP, "CSID: Invalid arguments"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_info->core_info; + + switch (cmd_type) { + case CAM_IFE_CSID_CMD_GET_TIME_STAMP: + rc = cam_ife_csid_ver1_get_time_stamp(csid_hw, cmd_args); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { + res = ((struct cam_csid_get_time_stamp_args *) + cmd_args)->node_res; + cam_ife_csid_ver1_print_hbi_vbi(csid_hw, res); + } + + break; + case CAM_IFE_CSID_SET_CSID_DEBUG: + rc = cam_ife_csid_ver1_set_debug(csid_hw, + *((uint32_t *)cmd_args)); + break; + case CAM_IFE_CSID_SOF_IRQ_DEBUG: + rc = cam_ife_csid_ver1_sof_irq_debug(csid_hw, cmd_args); + break; + case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE: + rc = cam_ife_csid_ver1_set_csid_clock(csid_hw, cmd_args); + break; + case CAM_ISP_HW_CMD_CSID_QCFA_SUPPORTED: + rc = cam_ife_csid_ver1_set_csid_qcfa(csid_hw, + cmd_args); + break; + case CAM_ISP_HW_CMD_DUMP_HW: + rc = cam_ife_csid_ver1_dump_hw(csid_hw, cmd_args); + break; + case CAM_ISP_HW_CMD_CSID_CLOCK_DUMP: + rc = cam_ife_csid_ver1_dump_csid_clock(csid_hw, cmd_args); + break; + case CAM_IFE_CSID_SET_CONFIG: + rc = cam_ife_csid_set_epd_config(&csid_hw->flags, cmd_args, + csid_hw->hw_intf->hw_idx); + break; + case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG: + rc = cam_ife_csid_ver1_set_sensor_dimension(csid_hw, + cmd_args); + break; + case CAM_IFE_CSID_TOP_CONFIG: + break; + case CAM_IFE_CSID_SET_DUAL_SYNC_CONFIG: + break; + case CAM_IFE_CSID_LOG_ACQUIRE_DATA: + cam_ife_csid_log_acquire_data(csid_hw, cmd_args); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", + csid_hw->hw_intf->hw_idx, cmd_type); + rc = -EINVAL; + break; + } + return rc; + +} + +static int cam_ife_csid_ver1_handle_rx_debug_event( + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t bit_pos) +{ + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_ver1_reg_info *csid_reg; + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + uint32_t mask, val; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + soc_info = &csid_hw->hw_info->soc_info; + mask = BIT(bit_pos); + + switch (mask) { + case IFE_CSID_VER1_RX_LONG_PKT_CAPTURED: + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_long_pkt_0_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt VC: %d DT: %d WC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->vc_mask, + val & csi2_reg->dt_mask, + val & csi2_reg->wc_mask); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_long_pkt_1_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt ECC: %d", + csid_hw->hw_intf->hw_idx, val); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_long_pkt_ftr_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt cal CRC: %d expected CRC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->calc_crc_mask, + val & csi2_reg->expected_crc_mask); + break; + + case IFE_CSID_VER1_RX_SHORT_PKT_CAPTURED: + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_short_pkt_0_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt VC: %d DT: %d LC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->vc_mask, + val & csi2_reg->dt_mask, + val & csi2_reg->wc_mask); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_short_pkt_1_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt ECC: %d", + csid_hw->hw_intf->hw_idx, val); + break; + case IFE_CSID_VER1_RX_CPHY_PKT_HDR_CAPTURED: + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_cphy_pkt_hdr_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d CPHY pkt VC: %d DT: %d LC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->vc_mask, + val & csi2_reg->dt_mask, + val & csi2_reg->wc_mask); + break; + default: + CAM_INFO_RATE_LIMIT(CAM_ISP, + "CSID[%d] RX_IRQ: %s", + csid_hw->hw_intf->hw_idx, + ver1_rx_irq_desc[bit_pos].desc); + break; + } + + return 0; +} + +static int cam_ife_csid_ver1_handle_event_err( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_ife_csid_ver1_evt_payload *evt_payload, + int err_type) +{ + struct cam_isp_hw_event_info event_info; + int rc = 0; + + event_info.err_type = err_type; + event_info.hw_idx = evt_payload->hw_idx; + + switch (err_type) { + + case CAM_ISP_HW_ERROR_CSID_FATAL: + rc = csid_hw->event_cb(NULL, + CAM_ISP_HW_EVENT_ERROR, (void *)&event_info); + break; + + default: + CAM_DBG(CAM_ISP, "CSID[%d] invalid error type %d", + csid_hw->hw_intf->hw_idx, + err_type); + break; + } + + return rc; +} + +static int cam_ife_csid_ver1_put_evt_payload( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_ife_csid_ver1_evt_payload **evt_payload, + struct list_head *payload_list) +{ + unsigned long flags; + + if (*evt_payload == NULL) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid payload core %d", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + spin_lock_irqsave(&csid_hw->lock_state, flags); + list_add_tail(&(*evt_payload)->list, + payload_list); + *evt_payload = NULL; + spin_unlock_irqrestore(&csid_hw->lock_state, flags); + + return 0; +} + +static int cam_ife_csid_ver1_get_evt_payload( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_ife_csid_ver1_evt_payload **evt_payload, + struct list_head *payload_list) +{ + + spin_lock(&csid_hw->lock_state); + + if (list_empty(payload_list)) { + *evt_payload = NULL; + spin_unlock(&csid_hw->lock_state); + CAM_ERR_RATE_LIMIT(CAM_ISP, "No free payload core %d", + csid_hw->hw_intf->hw_idx); + return -ENOMEM; + } + + *evt_payload = list_first_entry(payload_list, + struct cam_ife_csid_ver1_evt_payload, list); + list_del_init(&(*evt_payload)->list); + spin_unlock(&csid_hw->lock_state); + + return 0; +} + +static int cam_ife_csid_ver1_rx_bottom_half_handler( + struct cam_ife_csid_ver1_hw *csid_hw, + struct cam_ife_csid_ver1_evt_payload *evt_payload) +{ + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + struct cam_ife_csid_ver1_reg_info *csid_reg; + uint8_t *log_buf = NULL; + uint32_t irq_status; + size_t len = 0; + + if (!csid_hw || !evt_payload) { + CAM_ERR(CAM_ISP, + "Invalid Param handler_priv %pK evt_payload_priv %pK", + csid_hw, evt_payload); + return -EINVAL; + } + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + + irq_status = evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RX] + & csi2_reg->fatal_err_mask; + log_buf = csid_hw->log_buf; + memset(log_buf, 0, sizeof(csid_hw->log_buf)); + + if (irq_status) { + + cam_ife_csid_ver1_disable_csi2(csid_hw); + len += scnprintf(log_buf, CAM_IFE_CSID_LOG_BUF_LEN - len, + "Overflow:\n "); + + if (irq_status & IFE_CSID_VER1_RX_LANE0_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_0\n"); + + if (irq_status & IFE_CSID_VER1_RX_LANE1_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_1\n"); + + if (irq_status & IFE_CSID_VER1_RX_LANE2_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_2\n"); + + if (irq_status & IFE_CSID_VER1_RX_LANE3_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_3\n"); + } + + irq_status = evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RX] & + csi2_reg->part_fatal_err_mask; + + if (irq_status) { + + len += scnprintf(log_buf, CAM_IFE_CSID_LOG_BUF_LEN - len, + "Part-fatal-errors:\n"); + + if (irq_status & IFE_CSID_VER1_RX_CPHY_EOT_RECEPTION) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "CPHY_EOT_RECEPTION\n"); + + if (irq_status & IFE_CSID_VER1_RX_CPHY_SOT_RECEPTION) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "CPHY_SOT_RECEPTION\n"); + + if (irq_status & IFE_CSID_VER1_RX_STREAM_UNDERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "STREAM_UNDERFLOW\n"); + + if (irq_status & IFE_CSID_VER1_RX_UNBOUNDED_FRAME) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "UNBOUNDED_FRAME\n"); + } + + if (len) + CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%u] %s", + csid_hw->hw_intf->hw_idx, log_buf); + + if (csid_hw->flags.fatal_err_detected) + cam_ife_csid_ver1_handle_event_err(csid_hw, + evt_payload, CAM_ISP_HW_ERROR_CSID_FATAL); + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver1_path_bottom_half_handler( + const struct cam_ife_csid_ver1_path_reg_info *path_reg, + struct cam_ife_csid_ver1_evt_payload *evt_payload, + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t index) +{ + const uint8_t **irq_reg_tag; + uint8_t *log_buf = NULL; + uint32_t bit_pos = 0; + uint32_t irq_status; + size_t len = 0; + + if (!csid_hw || !evt_payload) { + CAM_ERR(CAM_ISP, + "Invalid Param csid_hw %pK evt_payload %pK", + csid_hw, evt_payload); + return 0; + } + + irq_status = evt_payload->irq_status[index] & path_reg->fatal_err_mask; + bit_pos = 0; + log_buf = csid_hw->log_buf; + memset(log_buf, 0, sizeof(csid_hw->log_buf)); + irq_reg_tag = cam_ife_csid_get_irq_reg_tag_ptr(); + + while (irq_status) { + if ((irq_status & 0x1)) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "%s\n", ver1_path_irq_desc[bit_pos]); + bit_pos++; + irq_status >>= 1; + } + + if (len) + CAM_ERR_RATE_LIMIT(CAM_ISP, + "CSID[%u] %s: %s", + csid_hw->hw_intf->hw_idx, + irq_reg_tag[index], + log_buf); + + return 0; +} + +static int cam_ife_csid_ver1_bottom_half_handler( + void *handler_priv, + void *evt_payload_priv) +{ + const struct cam_ife_csid_ver1_path_reg_info *path_reg; + struct cam_ife_csid_ver1_evt_payload *evt_payload; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_ver1_hw *csid_hw; + int i; + int id = 0; + + if (!handler_priv || !evt_payload_priv) { + CAM_ERR(CAM_ISP, + "Invalid Param handler_priv %pK evt_payload_priv %pK", + handler_priv, evt_payload_priv); + return -EINVAL; + } + + csid_hw = (struct cam_ife_csid_ver1_hw *)handler_priv; + evt_payload = (struct cam_ife_csid_ver1_evt_payload *)evt_payload_priv; + + if (evt_payload->irq_status[CAM_IFE_CSID_IRQ_REG_RX]) + cam_ife_csid_ver1_rx_bottom_half_handler( + csid_hw, evt_payload); + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + for (i = CAM_IFE_CSID_IRQ_REG_RDI_0; i < CAM_IFE_CSID_IRQ_REG_MAX; + i++) { + + if (!evt_payload->irq_status[i]) + continue; + + path_reg = NULL; + + switch (i) { + case CAM_IFE_CSID_IRQ_REG_IPP: + path_reg = csid_reg->ipp_reg; + break; + case CAM_IFE_CSID_IRQ_REG_PPP: + path_reg = csid_reg->ppp_reg; + break; + case CAM_IFE_CSID_IRQ_REG_RDI_0: + case CAM_IFE_CSID_IRQ_REG_RDI_1: + case CAM_IFE_CSID_IRQ_REG_RDI_2: + case CAM_IFE_CSID_IRQ_REG_RDI_3: + case CAM_IFE_CSID_IRQ_REG_RDI_4: + id = i - CAM_IFE_CSID_IRQ_REG_RDI_0; + path_reg = csid_reg->rdi_reg[id]; + break; + case CAM_IFE_CSID_IRQ_REG_UDI_0: + case CAM_IFE_CSID_IRQ_REG_UDI_1: + case CAM_IFE_CSID_IRQ_REG_UDI_2: + id = i - CAM_IFE_CSID_IRQ_REG_UDI_0; + path_reg = csid_reg->udi_reg[id]; + break; + default: + break; + } + + if (!path_reg) + continue; + + cam_ife_csid_ver1_path_bottom_half_handler( + path_reg, evt_payload, csid_hw, i); + } + + cam_ife_csid_ver1_put_evt_payload(csid_hw, &evt_payload, + &csid_hw->free_payload_list); + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver1_rx_top_half( + uint32_t *irq_status, + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t *need_bh_sched) +{ + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + uint32_t status = 0; + uint32_t debug_bits; + uint32_t bit_pos = 0; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + soc_info = &csid_hw->hw_info->soc_info; + + status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->irq_status_addr); + irq_status[CAM_IFE_CSID_IRQ_REG_RX] = status; + + if (!status) + return IRQ_HANDLED; + + cam_io_w_mb(status, + soc_info->reg_map[0].mem_base + + csi2_reg->irq_clear_addr); + + if (csid_hw->flags.process_reset) + return 0; + + if (status & BIT(csi2_reg->rst_done_shift_val)) { + CAM_DBG(CAM_ISP, "CSID[%d] rx_reset done", + csid_hw->hw_intf->hw_idx); + complete(&csid_hw->irq_complete + [CAM_IFE_CSID_IRQ_REG_RX]); + return IRQ_HANDLED; + } + + if (csid_hw->flags.fatal_err_detected) { + CAM_DBG(CAM_ISP, "CSID[%u] already handling fatal error"); + return 0; + } + + if (status & csi2_reg->fatal_err_mask) { + csid_hw->flags.fatal_err_detected = true; + cam_ife_csid_ver1_disable_csi2(csid_hw); + } + + if (status & csi2_reg->part_fatal_err_mask) { + + if (status & IFE_CSID_VER1_RX_CPHY_EOT_RECEPTION) + csid_hw->counters.error_irq_count++; + + if (status & IFE_CSID_VER1_RX_CPHY_SOT_RECEPTION) + csid_hw->counters.error_irq_count++; + + if (status & IFE_CSID_VER1_RX_STREAM_UNDERFLOW) + csid_hw->counters.error_irq_count++; + + if (status & IFE_CSID_VER1_RX_UNBOUNDED_FRAME) + csid_hw->counters.error_irq_count++; + + if (csid_hw->counters.error_irq_count > + CAM_IFE_CSID_MAX_ERR_COUNT) { + csid_hw->flags.fatal_err_detected = true; + cam_ife_csid_ver1_disable_csi2(csid_hw); + } + } + + debug_bits = status & csid_hw->debug_info.rx_mask; + + while (debug_bits) { + + if (debug_bits & 0x1) + cam_ife_csid_ver1_handle_rx_debug_event(csid_hw, + bit_pos); + bit_pos++; + debug_bits >>= 1; + } + + *need_bh_sched = status & (csi2_reg->fatal_err_mask | + csi2_reg->part_fatal_err_mask); + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver1_path_top_half( + uint32_t *irq_status, + struct cam_ife_csid_ver1_hw *csid_hw, + uint32_t *need_bh, + uint32_t index) +{ + struct cam_ife_csid_ver1_path_reg_info *path_reg = NULL; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const uint8_t **irq_reg_tag; + uint32_t status = 0; + uint32_t debug_bits; + uint32_t bit_pos = 0; + int id = 0; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + + switch (index) { + case CAM_IFE_CSID_IRQ_REG_IPP: + path_reg = csid_reg->ipp_reg; + break; + case CAM_IFE_CSID_IRQ_REG_PPP: + path_reg = csid_reg->ppp_reg; + break; + case CAM_IFE_CSID_IRQ_REG_RDI_0: + case CAM_IFE_CSID_IRQ_REG_RDI_1: + case CAM_IFE_CSID_IRQ_REG_RDI_2: + case CAM_IFE_CSID_IRQ_REG_RDI_3: + case CAM_IFE_CSID_IRQ_REG_RDI_4: + id = index - CAM_IFE_CSID_IRQ_REG_RDI_0; + path_reg = csid_reg->rdi_reg[id]; + break; + case CAM_IFE_CSID_IRQ_REG_UDI_0: + case CAM_IFE_CSID_IRQ_REG_UDI_1: + case CAM_IFE_CSID_IRQ_REG_UDI_2: + id = index - CAM_IFE_CSID_IRQ_REG_UDI_0; + path_reg = csid_reg->udi_reg[id]; + break; + default: + break; + } + + if (!path_reg) + return 0; + + soc_info = &csid_hw->hw_info->soc_info; + status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + path_reg->irq_status_addr); + cam_io_w_mb(status, + soc_info->reg_map[0].mem_base + + path_reg->irq_clear_addr); + + irq_status[index] = status; + + if (csid_hw->flags.process_reset) + return 0; + + if (status & BIT(csid_reg->cmn_reg->rst_done_shift_val)) { + CAM_DBG(CAM_ISP, "irq_reg:%d reset done", index); + complete(&csid_hw->irq_complete[index]); + return 0; + } + + if (status & path_reg->fatal_err_mask) + cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY, + soc_info->reg_map[0].mem_base + + path_reg->ctrl_addr); + + debug_bits = status & csid_hw->debug_info.path_mask; + irq_reg_tag = cam_ife_csid_get_irq_reg_tag_ptr(); + + while (debug_bits) { + if ((debug_bits & 0x1)) + CAM_INFO_RATE_LIMIT(CAM_ISP, + "CSID[%d] IRQ %s %s ", + csid_hw->hw_intf->hw_idx, + irq_reg_tag[index], + ver1_path_irq_desc[bit_pos]); + + bit_pos++; + debug_bits >>= 1; + } + + *need_bh = status & (path_reg->fatal_err_mask | + path_reg->non_fatal_err_mask); + + return IRQ_HANDLED; +} + +static irqreturn_t cam_ife_csid_irq(int irq_num, void *data) +{ + struct cam_ife_csid_ver1_evt_payload *evt_payload = NULL; + struct cam_ife_csid_ver1_reg_info *csid_reg; + struct cam_ife_csid_ver1_hw *csid_hw; + struct cam_hw_soc_info *soc_info; + void *bh_cmd = NULL; + unsigned long flags; + uint32_t status[CAM_IFE_CSID_IRQ_REG_MAX]; + uint32_t need_rx_bh = 0; + uint32_t need_path_bh = 0; + uint32_t need_bh_sched = 0; + int i; + int rc = 0; + + csid_hw = (struct cam_ife_csid_ver1_hw *)data; + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + memset(status, 0, sizeof(status)); + + spin_lock_irqsave(&csid_hw->hw_info->hw_lock, flags); + + status[CAM_IFE_CSID_IRQ_REG_TOP] = + cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_status_addr); + cam_io_w_mb(status[CAM_IFE_CSID_IRQ_REG_TOP], + soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_clear_addr); + + for (i = CAM_IFE_CSID_IRQ_REG_RX; i < CAM_IFE_CSID_IRQ_REG_MAX; i++) { + + switch (i) { + case CAM_IFE_CSID_IRQ_REG_RX: + cam_ife_csid_ver1_rx_top_half( + status, csid_hw, &need_rx_bh); + break; + case CAM_IFE_CSID_IRQ_REG_IPP: + case CAM_IFE_CSID_IRQ_REG_PPP: + case CAM_IFE_CSID_IRQ_REG_RDI_0: + case CAM_IFE_CSID_IRQ_REG_RDI_1: + case CAM_IFE_CSID_IRQ_REG_RDI_2: + case CAM_IFE_CSID_IRQ_REG_RDI_3: + case CAM_IFE_CSID_IRQ_REG_RDI_4: + case CAM_IFE_CSID_IRQ_REG_UDI_0: + case CAM_IFE_CSID_IRQ_REG_UDI_1: + case CAM_IFE_CSID_IRQ_REG_UDI_2: + cam_ife_csid_ver1_path_top_half( + status, csid_hw, &need_path_bh, i); + break; + default: + break; + } + need_bh_sched |= (need_rx_bh | need_path_bh); + } + + if (status[CAM_IFE_CSID_IRQ_REG_TOP] & IFE_CSID_VER1_TOP_IRQ_DONE) { + csid_hw->flags.process_reset = false; + goto handle_top_reset; + } + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + spin_unlock_irqrestore( + &csid_hw->hw_info->hw_lock, flags); + + if (!need_bh_sched) + return IRQ_HANDLED; + + rc = cam_ife_csid_ver1_get_evt_payload(csid_hw, &evt_payload, + &csid_hw->free_payload_list); + + if (!evt_payload) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%u], no free tasklet", + csid_hw->hw_intf->hw_idx); + return IRQ_HANDLED; + } + + + rc = tasklet_bh_api.get_bh_payload_func(csid_hw->tasklet, &bh_cmd); + + if (rc || !bh_cmd) { + cam_ife_csid_ver1_put_evt_payload(csid_hw, &evt_payload, + &csid_hw->free_payload_list); + CAM_ERR_RATE_LIMIT(CAM_ISP, + "CSID[%d] Can not get cmd for tasklet, status %x", + csid_hw->hw_intf->hw_idx); + return IRQ_HANDLED; + } + + evt_payload->priv = csid_hw->token; + evt_payload->hw_idx = csid_hw->hw_intf->hw_idx; + + for (i = 0; i < CAM_IFE_CSID_IRQ_REG_MAX; i++) + evt_payload->irq_status[i] = status[i]; + + tasklet_bh_api.bottom_half_enqueue_func(csid_hw->tasklet, + bh_cmd, + csid_hw, + evt_payload, + cam_ife_csid_ver1_bottom_half_handler); + + return IRQ_HANDLED; + +handle_top_reset: + CAM_DBG(CAM_ISP, "csid top reset complete"); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->irq_cmd_addr); + spin_unlock_irqrestore( + &csid_hw->hw_info->hw_lock, flags); + complete(&csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]); + return IRQ_HANDLED; +} + +static void cam_ife_csid_ver1_free_res(struct cam_ife_csid_ver1_hw *ife_csid_hw) +{ + struct cam_isp_resource_node *res; + uint32_t num_paths; + int i; + struct cam_ife_csid_ver1_reg_info *csid_reg; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + ife_csid_hw->core_info->csid_reg; + num_paths = csid_reg->cmn_reg->num_udis; + + for (i = 0; i < num_paths; i++) { + res = &ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_UDI_0 + i]; + kfree(res->res_priv); + res->res_priv = NULL; + } + + num_paths = csid_reg->cmn_reg->num_rdis; + + for (i = 0; i < num_paths; i++) { + res = &ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_RDI_0 + i]; + kfree(res->res_priv); + res->res_priv = NULL; + } + + kfree(ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP].res_priv); + ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP].res_priv = NULL; + kfree(ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP].res_priv); + ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP].res_priv = NULL; +} + +static int cam_ife_ver1_hw_alloc_res( + struct cam_isp_resource_node *res, + uint32_t res_type, + struct cam_hw_intf *hw_intf, + uint32_t res_id) + +{ + struct cam_ife_csid_ver1_path_cfg *path_cfg = NULL; + + path_cfg = kzalloc(sizeof(*path_cfg), GFP_KERNEL); + + if (!path_cfg) + return -ENOMEM; + + res->res_id = res_id; + res->res_type = res_type; + res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; + res->hw_intf = hw_intf; + res->res_priv = path_cfg; + + return 0; +} + +static int cam_ife_csid_ver1_hw_init_path_res( + struct cam_ife_csid_ver1_hw *ife_csid_hw) +{ + int rc = 0; + int i; + struct cam_ife_csid_ver1_reg_info *csid_reg; + + csid_reg = (struct cam_ife_csid_ver1_reg_info *) + ife_csid_hw->core_info->csid_reg; + + /* Initialize the IPP resources */ + if (csid_reg->cmn_reg->num_pix) { + rc = cam_ife_ver1_hw_alloc_res( + &ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP], + CAM_ISP_RESOURCE_PIX_PATH, + ife_csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_IPP); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d IPP res init fail", + ife_csid_hw->hw_intf->hw_idx); + goto free_res; + } + } + + /* Initialize PPP resource */ + if (csid_reg->cmn_reg->num_ppp) { + rc = cam_ife_ver1_hw_alloc_res( + &ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP], + CAM_ISP_RESOURCE_PIX_PATH, + ife_csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_PPP); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d PPP res init fail", + ife_csid_hw->hw_intf->hw_idx); + goto free_res; + } + } + + /* Initialize the RDI resource */ + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + /* res type is from RDI 0 to RDI3 */ + rc = cam_ife_ver1_hw_alloc_res( + &ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_RDI_0 + i], + CAM_ISP_RESOURCE_PIX_PATH, + ife_csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_RDI_0 + i); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d RDI[%d] res init fail", + ife_csid_hw->hw_intf->hw_idx, i); + goto free_res; + } + } + + /* Initialize the UDI resource */ + for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { + /* res type is from UDI0 to UDI3 */ + rc = cam_ife_ver1_hw_alloc_res( + &ife_csid_hw->path_res[CAM_IFE_PIX_PATH_RES_UDI_0 + i], + CAM_ISP_RESOURCE_PIX_PATH, + ife_csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_UDI_0 + i); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d UDI[%d] res init fail", + ife_csid_hw->hw_intf->hw_idx, i); + goto free_res; + } + } + + return rc; + +free_res: + cam_ife_csid_ver1_free_res(ife_csid_hw); + return rc; +} + +int cam_ife_csid_hw_ver1_init(struct cam_hw_intf *hw_intf, + struct cam_ife_csid_core_info *csid_core_info, + bool is_custom) +{ + int rc = -EINVAL; + uint32_t i; + struct cam_hw_info *hw_info; + struct cam_ife_csid_ver1_hw *ife_csid_hw = NULL; + + if (!hw_intf || !csid_core_info) { + CAM_ERR(CAM_ISP, "Invalid parameters intf: %pK hw_info: %pK", + hw_intf, csid_core_info); + return rc; + } + + hw_info = (struct cam_hw_info *)hw_intf->hw_priv; + + ife_csid_hw = kzalloc(sizeof(struct cam_ife_csid_ver1_hw), GFP_KERNEL); + + if (!ife_csid_hw) { + CAM_ERR(CAM_ISP, "Csid core %d hw allocation fails", + hw_intf->hw_idx); + return -ENOMEM; + } + + ife_csid_hw->hw_intf = hw_intf; + ife_csid_hw->hw_info = hw_info; + ife_csid_hw->core_info = csid_core_info; + hw_info->core_info = ife_csid_hw; + + CAM_DBG(CAM_ISP, "type %d index %d", + hw_intf->hw_type, + hw_intf->hw_idx); + + ife_csid_hw->flags.device_enabled = false; + ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; + mutex_init(&ife_csid_hw->hw_info->hw_mutex); + spin_lock_init(&ife_csid_hw->hw_info->hw_lock); + spin_lock_init(&ife_csid_hw->lock_state); + init_completion(&ife_csid_hw->hw_info->hw_complete); + + for (i = 0; i < CAM_IFE_CSID_IRQ_REG_MAX; i++) + init_completion(&ife_csid_hw->irq_complete[i]); + + rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info, + cam_ife_csid_irq, ife_csid_hw, is_custom); + if (rc < 0) { + CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", + hw_intf->hw_idx); + return rc; + } + + if (cam_cpas_is_feature_supported(CAM_CPAS_QCFA_BINNING_ENABLE, + CAM_CPAS_HW_IDX_ANY, NULL)) + ife_csid_hw->flags.binning_enabled = true; + + ife_csid_hw->hw_intf->hw_ops.get_hw_caps = + cam_ife_csid_ver1_get_hw_caps; + ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_ver1_init_hw; + ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_ver1_deinit_hw; + ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_ver1_reset; + ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_ver1_reserve; + ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_ver1_release; + ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_ver1_start; + ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_ver1_stop; + ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_ver1_read; + ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_ver1_write; + ife_csid_hw->hw_intf->hw_ops.process_cmd = + cam_ife_csid_ver1_process_cmd; + + rc = cam_ife_csid_ver1_hw_init_path_res(ife_csid_hw); + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] Probe Init failed", + hw_intf->hw_idx); + return rc; + } + + rc = cam_tasklet_init(&ife_csid_hw->tasklet, ife_csid_hw, + hw_intf->hw_idx); + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] init tasklet failed", + hw_intf->hw_idx); + goto err; + } + + INIT_LIST_HEAD(&ife_csid_hw->free_payload_list); + for (i = 0; i < CAM_IFE_CSID_VER1_EVT_PAYLOAD_MAX; i++) { + INIT_LIST_HEAD(&ife_csid_hw->evt_payload[i].list); + list_add_tail(&ife_csid_hw->evt_payload[i].list, + &ife_csid_hw->free_payload_list); + } + + ife_csid_hw->debug_info.debug_val = 0; + ife_csid_hw->counters.error_irq_count = 0; + + return 0; +err: + cam_ife_csid_ver1_free_res(ife_csid_hw); + return rc; +} +EXPORT_SYMBOL(cam_ife_csid_hw_ver1_init); + +int cam_ife_csid_hw_ver1_deinit(struct cam_hw_info *hw_priv) +{ + struct cam_ife_csid_ver1_hw *csid_hw; + int rc = -EINVAL; + + + if (!hw_priv) { + CAM_ERR(CAM_ISP, "Invalid param"); + return rc; + } + + csid_hw = (struct cam_ife_csid_ver1_hw *)hw_priv->core_info; + + /* release the privdate data memory from resources */ + cam_ife_csid_ver1_free_res(csid_hw); + + cam_ife_csid_deinit_soc_resources(&csid_hw->hw_info->soc_info); + + return 0; +} +EXPORT_SYMBOL(cam_ife_csid_hw_ver1_deinit); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.h new file mode 100644 index 0000000000..032379c340 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.h @@ -0,0 +1,457 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_IFE_CSID_HW_VER1_H_ +#define _CAM_IFE_CSID_HW_VER1_H_ + +#define IFE_CSID_VER1_RX_DL0_EOT_CAPTURED BIT(0) +#define IFE_CSID_VER1_RX_DL1_EOT_CAPTURED BIT(1) +#define IFE_CSID_VER1_RX_DL2_EOT_CAPTURED BIT(2) +#define IFE_CSID_VER1_RX_DL3_EOT_CAPTURED BIT(3) +#define IFE_CSID_VER1_RX_DL0_SOT_CAPTURED BIT(4) +#define IFE_CSID_VER1_RX_DL1_SOT_CAPTURED BIT(5) +#define IFE_CSID_VER1_RX_DL2_SOT_CAPTURED BIT(6) +#define IFE_CSID_VER1_RX_DL3_SOT_CAPTURED BIT(7) +#define IFE_CSID_VER1_RX_LONG_PKT_CAPTURED BIT(8) +#define IFE_CSID_VER1_RX_SHORT_PKT_CAPTURED BIT(9) +#define IFE_CSID_VER1_RX_CPHY_PKT_HDR_CAPTURED BIT(10) +#define IFE_CSID_VER1_RX_CPHY_EOT_RECEPTION BIT(11) +#define IFE_CSID_VER1_RX_CPHY_SOT_RECEPTION BIT(12) +#define IFE_CSID_VER1_RX_CPHY_PH_CRC BIT(13) +#define IFE_CSID_VER1_RX_WARNING_ECC BIT(14) +#define IFE_CSID_VER1_RX_LANE0_FIFO_OVERFLOW BIT(15) +#define IFE_CSID_VER1_RX_LANE1_FIFO_OVERFLOW BIT(16) +#define IFE_CSID_VER1_RX_LANE2_FIFO_OVERFLOW BIT(17) +#define IFE_CSID_VER1_RX_LANE3_FIFO_OVERFLOW BIT(18) +#define IFE_CSID_VER1_RX_CRC BIT(19) +#define IFE_CSID_VER1_RX_ERROR_ECC BIT(20) +#define IFE_CSID_VER1_RX_MMAPPED_VC_DT BIT(21) +#define IFE_CSID_VER1_RX_UNMAPPED_VC_DT BIT(22) +#define IFE_CSID_VER1_RX_STREAM_UNDERFLOW BIT(23) +#define IFE_CSID_VER1_RX_UNBOUNDED_FRAME BIT(24) +#define IFE_CSID_VER1_RX_TG_DONE BIT(25) +#define IFE_CSID_VER1_RX_TG_FIFO_OVERFLOW BIT(26) +#define IFE_CSID_VER1_RX_RST_DONE BIT(27) + +#define IFE_CSID_VER1_TOP_IRQ_DONE BIT(0) +#define IFE_CSID_VER1_PATH_INFO_RST_DONE BIT(1) +#define IFE_CSID_VER1_PATH_ERROR_FIFO_OVERFLOW BIT(2) +#define IFE_CSID_VER1_PATH_INFO_SUBSAMPLED_EOF BIT(3) +#define IFE_CSID_VER1_PATH_INFO_SUBSAMPLED_SOF BIT(4) +#define IFE_CSID_VER1_PATH_INFO_FRAME_DROP_EOF BIT(5) +#define IFE_CSID_VER1_PATH_INFO_FRAME_DROP_EOL BIT(6) +#define IFE_CSID_VER1_PATH_INFO_FRAME_DROP_SOL BIT(7) +#define IFE_CSID_VER1_PATH_INFO_FRAME_DROP_SOF BIT(8) +#define IFE_CSID_VER1_PATH_INFO_INPUT_EOF BIT(9) +#define IFE_CSID_VER1_PATH_INFO_INPUT_EOL BIT(10) +#define IFE_CSID_VER1_PATH_INFO_INPUT_SOL BIT(11) +#define IFE_CSID_VER1_PATH_INFO_INPUT_SOF BIT(12) +#define IFE_CSID_VER1_PATH_ERROR_PIX_COUNT BIT(13) +#define IFE_CSID_VER1_PATH_ERROR_LINE_COUNT BIT(14) +#define IFE_CSID_VER1_PATH_ERROR_CCIF_VIOLATION BIT(15) +#define IFE_CSID_VER1_PATH_OVERFLOW_RECOVERY BIT(17) + +#define CAM_IFE_CSID_VER1_EVT_PAYLOAD_MAX 256 + +/* + * struct cam_ife_csid_ver1_common_reg_info: Structure to hold Common info + * holds register address offsets + * shift values + * masks + */ +struct cam_ife_csid_ver1_common_reg_info { + /* MIPI CSID registers */ + uint32_t hw_version_addr; + uint32_t cfg0_addr; + uint32_t ctrl_addr; + uint32_t reset_addr; + uint32_t rst_strobes_addr; + uint32_t test_bus_ctrl_addr; + uint32_t top_irq_status_addr; + uint32_t top_irq_mask_addr; + uint32_t top_irq_clear_addr; + uint32_t top_irq_set_addr; + uint32_t irq_cmd_addr; + + /*Shift Bit Configurations*/ + uint32_t rst_done_shift_val; + uint32_t timestamp_stb_sel_shift_val; + uint32_t decode_format_shift_val; + uint32_t path_en_shift_val; + uint32_t dt_id_shift_val; + uint32_t vc_shift_val; + uint32_t dt_shift_val; + uint32_t fmt_shift_val; + uint32_t num_bytes_out_shift_val; + uint32_t crop_shift_val; + uint32_t debug_frm_drop_rst_shift_val; + uint32_t debug_timestamp_rst_shift_val; + uint32_t debug_format_measure_rst_shift_val; + uint32_t debug_misr_rst_shift_val; + uint32_t num_padding_pixels_shift_val; + uint32_t num_padding_rows_shift_val; + uint32_t fmt_measure_num_lines_shift_val; + uint32_t num_vbi_lines_shift_val; + uint32_t num_hbi_cycles_shift_val; + uint32_t multi_vcdt_vc1_shift_val; + uint32_t multi_vcdt_dt1_shift_val; + uint32_t multi_vcdt_ts_combo_en_shift_val; + uint32_t multi_vcdt_en_shift_val; + + /* config Values */ + uint32_t major_version; + uint32_t minor_version; + uint32_t version_incr; + uint32_t num_udis; + uint32_t num_rdis; + uint32_t num_pix; + uint32_t num_ppp; + uint32_t rst_sw_reg_stb; + uint32_t rst_hw_reg_stb; + uint32_t rst_sw_hw_reg_stb; + uint32_t path_rst_stb_all; + uint32_t drop_supported; + uint32_t multi_vcdt_supported; + uint32_t timestamp_strobe_val; + uint32_t early_eof_supported; + uint32_t global_reset; + uint32_t rup_supported; + + /* Masks */ + uint32_t ipp_irq_mask_all; + uint32_t rdi_irq_mask_all; + uint32_t ppp_irq_mask_all; + uint32_t udi_irq_mask_all; + uint32_t measure_en_hbi_vbi_cnt_mask; + uint32_t measure_pixel_line_en_mask; + uint32_t fmt_measure_num_line_mask; + uint32_t fmt_measure_num_pxl_mask; + uint32_t hblank_max_mask; + uint32_t hblank_min_mask; + uint32_t crop_pix_start_mask; + uint32_t crop_pix_end_mask; + uint32_t crop_line_start_mask; + uint32_t crop_line_end_mask; +}; + +/* + * struct cam_ife_csid_ver1_path_reg_info: Structure to hold PXL reg info + * holds register address offsets + * shift values + * masks + */ +struct cam_ife_csid_ver1_path_reg_info { + /* Pxl path register offsets*/ + uint32_t irq_status_addr; + uint32_t irq_mask_addr; + uint32_t irq_clear_addr; + uint32_t irq_set_addr; + + uint32_t cfg0_addr; + uint32_t cfg1_addr; + uint32_t ctrl_addr; + uint32_t frm_drop_pattern_addr; + uint32_t frm_drop_period_addr; + uint32_t irq_subsample_pattern_addr; + uint32_t irq_subsample_period_addr; + uint32_t hcrop_addr; + uint32_t vcrop_addr; + uint32_t pix_drop_pattern_addr; + uint32_t pix_drop_period_addr; + uint32_t line_drop_pattern_addr; + uint32_t line_drop_period_addr; + uint32_t rst_strobes_addr; + uint32_t status_addr; + uint32_t misr_val_addr; + uint32_t misr_val0_addr; + uint32_t misr_val1_addr; + uint32_t misr_val2_addr; + uint32_t misr_val3_addr; + uint32_t format_measure_cfg0_addr; + uint32_t format_measure_cfg1_addr; + uint32_t format_measure0_addr; + uint32_t format_measure1_addr; + uint32_t format_measure2_addr; + uint32_t yuv_chroma_conversion_addr; + uint32_t timestamp_curr0_sof_addr; + uint32_t timestamp_curr1_sof_addr; + uint32_t timestamp_prev0_sof_addr; + uint32_t timestamp_prev1_sof_addr; + uint32_t timestamp_curr0_eof_addr; + uint32_t timestamp_curr1_eof_addr; + uint32_t timestamp_prev0_eof_addr; + uint32_t timestamp_prev1_eof_addr; + uint32_t err_recovery_cfg0_addr; + uint32_t err_recovery_cfg1_addr; + uint32_t err_recovery_cfg2_addr; + uint32_t multi_vcdt_cfg0_addr; + uint32_t byte_cntr_ping_addr; + uint32_t byte_cntr_pong_addr; + /* shift bit configuration */ + uint32_t timestamp_en_shift_val; + uint32_t crop_v_en_shift_val; + uint32_t crop_h_en_shift_val; + uint32_t drop_v_en_shift_val; + uint32_t drop_h_en_shift_val; + uint32_t bin_h_en_shift_val; + uint32_t bin_v_en_shift_val; + uint32_t bin_en_shift_val; + uint32_t bin_qcfa_en_shift_val; + uint32_t halt_mode_master; + uint32_t halt_mode_internal; + uint32_t halt_mode_global; + uint32_t halt_mode_slave; + uint32_t halt_mode_shift; + uint32_t halt_master_sel_master_val; + uint32_t halt_master_sel_shift; + uint32_t halt_frame_boundary; + uint32_t resume_frame_boundary; + uint32_t halt_immediate; + uint32_t halt_cmd_shift; + uint32_t mipi_pack_supported; + uint32_t packing_fmt_shift_val; + uint32_t format_measure_en_shift_val; + uint32_t plain_fmt_shift_val; + uint32_t packing_format; + uint32_t pix_store_en_shift_val; + uint32_t early_eof_en_shift_val; + /* config Values */ + uint32_t ccif_violation_en; + uint32_t binning_supported; + uint32_t overflow_ctrl_mode_val; + uint32_t overflow_ctrl_en; + uint32_t fatal_err_mask; + uint32_t non_fatal_err_mask; +}; + +/* + * struct struct cam_ife_csid_ver1_tpg_reg_info: Structure to hold TPG reg info + * holds register address offsets + * shift values + * masks + */ +struct cam_ife_csid_ver1_tpg_reg_info { + uint32_t ctrl_addr; + uint32_t vc_cfg0_addr; + uint32_t vc_cfg1_addr; + uint32_t lfsr_seed_addr; + uint32_t dt_n_cfg_0_addr; + uint32_t dt_n_cfg_1_addr; + uint32_t dt_n_cfg_2_addr; + uint32_t color_bars_cfg_addr; + uint32_t color_box_cfg_addr; + uint32_t common_gen_cfg_addr; + uint32_t cgen_n_cfg_addr; + uint32_t cgen_n_x0_addr; + uint32_t cgen_n_x1_addr; + uint32_t cgen_n_x2_addr; + uint32_t cgen_n_xy_addr; + uint32_t cgen_n_y1_addr; + uint32_t cgen_n_y2_addr; + + /*configurations */ + uint32_t dtn_cfg_offset; + uint32_t cgen_cfg_offset; + uint32_t cpas_ife_reg_offset; + uint32_t hbi; + uint32_t vbi; + uint32_t lfsr_seed; + uint32_t width_shift; + uint32_t height_shift; + uint32_t fmt_shift; + uint32_t color_bar; + uint32_t line_interleave_mode; + uint32_t payload_mode; + uint32_t num_frames; + uint32_t num_active_dt; + uint32_t ctrl_cfg; + uint32_t phy_sel; + uint32_t num_frame_shift; + uint32_t line_interleave_shift; + uint32_t num_active_dt_shift; + uint32_t vbi_shift; + uint32_t hbi_shift; + uint32_t color_bar_shift; + uint32_t num_active_lanes_mask; +}; + +/* + * struct cam_ife_csid_ver1_reg_info: Structure for Reg info + * + * @csi2_reg: csi2 reg info + * @ipp_reg: IPP reg + * @ppp_reg: PPP reg + * @rdi_reg: RDI reg + * @udi_reg: UDI reg + * @start_pixel: start pixel for horizontal crop + * @tpg_reg: TPG reg + * @cmn_reg: Common reg info + * @csid_cust_node_map: Customer node map + * @fused_max_width: Max width based on fuse registers + * @width_fuse_max_val: Max value of width fuse + * @used_hw_capabilities Hw capabilities + */ +struct cam_ife_csid_ver1_reg_info { + struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + struct cam_ife_csid_ver1_path_reg_info *ipp_reg; + struct cam_ife_csid_ver1_path_reg_info *ppp_reg; + struct cam_ife_csid_ver1_path_reg_info *rdi_reg + [CAM_IFE_CSID_RDI_MAX]; + struct cam_ife_csid_ver1_path_reg_info *udi_reg + [CAM_IFE_CSID_UDI_MAX]; + struct cam_ife_csid_ver1_tpg_reg_info *tpg_reg; + struct cam_ife_csid_ver1_common_reg_info *cmn_reg; + const uint32_t csid_cust_node_map[ + CAM_IFE_CSID_HW_NUM_MAX]; + const uint32_t fused_max_width[ + CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX]; + const uint32_t width_fuse_max_val; +}; + +/* + * struct cam_ife_csid_ver1_path_cfg: place holder for path parameters + * + * @cid: cid value for path + * @in_format: input format + * @out_format: output format + * @start_pixel: start pixel for horizontal crop + * @end_pixel: end pixel for horizontal crop + * @start_line: start line for vertical crop + * @end_line: end line for vertical crop + * @width: width of incoming data + * @height: height of incoming data + * @master_idx: master idx + * @horizontal_bin: horizontal binning enable/disable on path + * @vertical_bin: vertical binning enable/disable on path + * @qcfa_bin : qcfa binning enable/disable on path + * @hor_ver_bin : horizontal vertical binning enable/disable on path + * @num_bytes_out: Number of bytes out + * @sync_mode : Sync mode--> master/slave/none + * @crop_enable: flag to indicate crop enable + * @drop_enable: flag to indicate drop enable + * @fmt_measure_enable: flag to indicate format measure enabled + * + */ +struct cam_ife_csid_ver1_path_cfg { + uint32_t cid; + uint32_t in_format; + uint32_t out_format; + uint32_t start_pixel; + uint32_t end_pixel; + uint32_t width; + uint32_t start_line; + uint32_t end_line; + uint32_t height; + uint32_t master_idx; + uint32_t horizontal_bin; + uint32_t vertical_bin; + uint32_t qcfa_bin; + uint32_t hor_ver_bin; + uint32_t num_bytes_out; + uint32_t sensor_width; + uint32_t sensor_height; + enum cam_isp_hw_sync_mode sync_mode; + bool crop_enable; + bool drop_enable; + bool fmt_measure_enable; +}; + +/** + * struct cam_csid_evt_payload- payload for csid hw event + * @list : list head + * @irq_status : IRQ Status register + * @priv : Private data of payload + * @evt_type : Event type from CSID + * @hw_idx : Hw index + */ +struct cam_ife_csid_ver1_evt_payload { + struct list_head list; + uint32_t irq_status[CAM_IFE_CSID_IRQ_REG_MAX]; + void *priv; + uint32_t evt_type; + uint32_t hw_idx; +}; + +/** + * struct cam_ife_csid_tpg_cfg- csid tpg configuration data + * @width: width + * @height: height + * @test_pattern : pattern + * @encode_format: decode format + * @usage_type: whether dual isp is required + * @vc: virtual channel + * @dt: data type + * + */ +struct cam_ife_csid_ver1_tpg_cfg { + uint32_t width; + uint32_t height; + uint32_t test_pattern; + uint32_t encode_format; + uint32_t usage_type; + uint32_t vc; + uint32_t dt; +}; + +/* + * struct cam_ife_csid_ver1_hw: place holder for csid hw + * + * @hw_intf: hw intf + * @hw_info: hw info + * @core_info: csid core info + * @tasklet: tasklet to handle csid errors + * @token: private data to be sent with callback + * @counters: counters used in csid hw + * @path_res: array of path resources + * @cid_data: cid data + * @log_buf: Log Buffer to dump info + * @rx_cfg: rx configuration + * @flags: flags + * @irq_complete: complete variable for reset irq + * @debug_info: Debug info to capture debug info + * @timestamp: Timestamp to maintain evt timestamps + * @free_payload_list: List of free payload list + * @evt_payload: Event payload + * @clk_rate: clk rate for csid hw + * @res_type: cur res type for active hw + * @lock_state : spin lock + * + */ +struct cam_ife_csid_ver1_hw { + struct cam_hw_intf *hw_intf; + struct cam_hw_info *hw_info; + struct cam_ife_csid_core_info *core_info; + void *tasklet; + void *token; + struct cam_ife_csid_hw_counters counters; + struct cam_ife_csid_ver1_tpg_cfg tpg_cfg; + struct cam_isp_resource_node path_res + [CAM_IFE_PIX_PATH_RES_MAX]; + struct list_head free_payload_list; + struct cam_ife_csid_ver1_evt_payload evt_payload + [CAM_IFE_CSID_VER1_EVT_PAYLOAD_MAX]; + struct completion irq_complete + [CAM_IFE_CSID_IRQ_REG_MAX]; + struct cam_ife_csid_cid_data cid_data + [CAM_IFE_CSID_CID_MAX]; + uint8_t log_buf + [CAM_IFE_CSID_LOG_BUF_LEN]; + struct cam_ife_csid_rx_cfg rx_cfg; + struct cam_ife_csid_hw_flags flags; + struct cam_ife_csid_debug_info debug_info; + struct cam_ife_csid_timestamp timestamp; + uint64_t clk_rate; + uint32_t res_type; + spinlock_t lock_state; + cam_hw_mgr_event_cb_func event_cb; +}; + +int cam_ife_csid_hw_ver1_init(struct cam_hw_intf *csid_hw_intf, + struct cam_ife_csid_core_info *csid_core_info, + bool is_custom); + +int cam_ife_csid_hw_ver1_deinit(struct cam_hw_info *hw_priv); + +#endif diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c new file mode 100644 index 0000000000..67c7991dfa --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c @@ -0,0 +1,3996 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include + +#include +#include + +#include + +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver2.h" +#include "cam_isp_hw.h" +#include "cam_isp_hw_mgr_intf.h" +#include "cam_soc_util.h" +#include "cam_io_util.h" +#include "cam_debug_util.h" +#include "cam_cpas_api.h" +#include "cam_irq_controller.h" +#include "cam_tasklet_util.h" +#include "cam_cdm_util.h" + + +/* CSIPHY TPG VC/DT values */ +#define CAM_IFE_CPHY_TPG_VC_VAL 0x0 +#define CAM_IFE_CPHY_TPG_DT_VAL 0x2B + +/* Timeout values in usec */ +#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000 +#define CAM_IFE_CSID_TIMEOUT_ALL_US 100000 + +#define CAM_IFE_CSID_RESET_TIMEOUT_MS 100 + +/* + * Constant Factors needed to change QTimer ticks to nanoseconds + * QTimer Freq = 19.2 MHz + * Time(us) = ticks/19.2 + * Time(ns) = ticks/19.2 * 1000 + */ +#define CAM_IFE_CSID_QTIMER_MUL_FACTOR 10000 +#define CAM_IFE_CSID_QTIMER_DIV_FACTOR 192 + +/* Max number of sof irq's triggered in case of SOF freeze */ +#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12 + +/* Max CSI Rx irq error count threshold value */ +#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100 + +static const struct cam_ife_csid_irq_desc ver2_rx_irq_desc[] = { + { + .desc = "DL0_EOT", + }, + { + .desc = "DL1_EOT", + }, + { + .desc = "DL2_EOT", + }, + { + .desc = "DL3_EOT", + }, + { + .desc = "DL0_SOT", + }, + { + .desc = "DL1_SOT", + }, + { + .desc = "DL2_SOT", + }, + { + .desc = "DL3_SOT", + }, + { + .desc = "LONG_PKT", + }, + { + .desc = "SHORT_PKT", + }, + { + .desc = "CPHY_PKT_HDR", + }, + { + .desc = "ERROR_CPHY_EOT_RECEPTION", + }, + { + .desc = "ERROR_CPHY_SOT_RECEPTION", + }, + { + .desc = "ERROR_CPHY_PH_CRC", + }, + { + .desc = "WARNING_ECC", + }, + { + .desc = "ERROR_LANE0_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_LANE1_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_LANE2_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_LANE3_FIFO_OVERFLOW", + }, + { + .desc = "ERROR_CRC", + }, + { + .desc = "ERROR_ECC", + }, + { + .desc = "ERROR_MMAPPED_VC_DT", + }, + { + .desc = "ERROR_UNMAPPED_VC_DT", + }, + { + .desc = "ERROR_STREAM_UNDERFLOW", + }, + { + .desc = "ERROR_UNBOUNDED_FRAME", + }, + { + .desc = "RST_DONE", + }, +}; + +static const struct cam_ife_csid_irq_desc ver2_path_irq_desc[] = { + { + .desc = "ERROR_FIFO_OVERFLOW", + }, + { + .desc = "CAMIF_EOF", + }, + { + .desc = "CAMIF_SOF", + }, + { + .desc = "FRAME_DROP_EOF", + }, + { + .desc = "FRAME_DROP_EOL", + }, + { + .desc = "FRAME_DROP_SOL", + }, + { + .desc = "FRAME_DROP_SOF", + }, + { + .desc = "INFO_INPUT_EOF", + }, + { + .desc = "INFO_INPUT_EOL", + }, + { + .desc = "INFO_INPUT_SOL", + }, + { + .desc = "INFO_INPUT_SOF", + }, + { + .desc = "ERROR_PIX_COUNT", + }, + { + .desc = "ERROR_LINE_COUNT", + }, + { + .desc = "VCDT_GRP0_SEL", + }, + { + .desc = "VCDT_GRP1_SEL", + }, + { + .desc = "VCDT_GRP_CHANGE", + }, + { + .desc = "FRAME_DROP", + }, + { + .desc = "OVERFLOW", + }, + { + .desc = "ERROR_REC_CCIF_VIOLATION", + }, + { + .desc = "CAMIF_EPOCH0", + }, + { + .desc = "CAMIF_EPOCH1", + }, + { + .desc = "RUP_DONE", + }, + { + .desc = "ILLEGAL_BATCH_ID", + }, + { + .desc = "BATCH_END_MISSING_VIOLATION", + }, + { + .desc = "HEIGHT_VIOLATION", + }, + { + .desc = "WIDTH_VIOLATION", + }, + { + .desc = "SENSOR_SWITCH_OUT_OF_SYNC_FRAME_DROP", + }, + { + .desc = "CCIF_VIOLATION", + }, +}; + +static int cam_ife_csid_ver2_set_debug( + struct cam_ife_csid_ver2_hw *csid_hw, + uint32_t debug_val) +{ + int bit_pos = 0; + uint32_t val; + + csid_hw->debug_info.debug_val = debug_val; + + while (debug_val) { + + if (!(debug_val & 0x1)) { + debug_val >>= 1; + bit_pos++; + continue; + } + + val = BIT(bit_pos); + + switch (val) { + case CAM_IFE_CSID_DEBUG_ENABLE_SOF_IRQ: + csid_hw->debug_info.path_mask |= + IFE_CSID_VER2_PATH_INFO_INPUT_SOF; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_EOF_IRQ: + csid_hw->debug_info.path_mask |= + IFE_CSID_VER2_PATH_INFO_INPUT_EOF; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_SOT_IRQ: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER2_RX_DL0_SOT_CAPTURED | + IFE_CSID_VER2_RX_DL1_SOT_CAPTURED | + IFE_CSID_VER2_RX_DL2_SOT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_EOT_IRQ: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER2_RX_DL0_EOT_CAPTURED | + IFE_CSID_VER2_RX_DL1_EOT_CAPTURED | + IFE_CSID_VER2_RX_DL2_EOT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER2_RX_SHORT_PKT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER2_RX_LONG_PKT_CAPTURED; + break; + case CAM_IFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE: + csid_hw->debug_info.rx_mask |= + IFE_CSID_VER2_RX_CPHY_PKT_HDR_CAPTURED; + break; + default: + break; + } + + debug_val >>= 1; + bit_pos++; + } + + return 0; +} + +static int cam_ife_csid_ver2_get_evt_payload( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_ife_csid_ver2_evt_payload **evt_payload, + struct list_head *payload_list, + spinlock_t *lock) +{ + + spin_lock(lock); + + if (list_empty(payload_list)) { + *evt_payload = NULL; + spin_unlock(lock); + CAM_ERR_RATE_LIMIT(CAM_ISP, "No free payload core %d", + csid_hw->hw_intf->hw_idx); + return -ENOMEM; + } + + *evt_payload = list_first_entry(payload_list, + struct cam_ife_csid_ver2_evt_payload, list); + list_del_init(&(*evt_payload)->list); + spin_unlock(lock); + + return 0; +} + +static int cam_ife_csid_ver2_put_evt_payload( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_ife_csid_ver2_evt_payload **evt_payload, + struct list_head *payload_list, + spinlock_t *lock) +{ + unsigned long flags; + + if (*evt_payload == NULL) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid payload core %d", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + spin_lock_irqsave(lock, flags); + list_add_tail(&(*evt_payload)->list, + payload_list); + *evt_payload = NULL; + spin_unlock_irqrestore(lock, flags); + + return 0; +} + +static int cam_ife_csid_ver2_handle_buf_done_irq( + uint32_t evt_id, + struct cam_irq_th_payload *th_payload) +{ + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + int rc = 0; + + csid_hw = th_payload->handler_priv; + CAM_DBG(CAM_ISP, "Enter"); + rc = cam_irq_controller_handle_irq(evt_id, + csid_hw->buf_done_irq_controller); + return (rc == IRQ_HANDLED) ? 0 : -EINVAL; +} + +static int cam_ife_csid_ver2_path_top_half( + uint32_t evt_id, + struct cam_irq_th_payload *th_payload) +{ + int32_t rc; + int i; + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_ife_csid_ver2_evt_payload *evt_payload; + + csid_hw = th_payload->handler_priv; + + if (!csid_hw) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "No private returned"); + return -ENODEV; + } + + rc = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload, + &csid_hw->path_free_payload_list, + &csid_hw->path_payload_lock); + + for (i = 0; i < th_payload->num_registers; i++) + CAM_DBG(CAM_ISP, "CSID:%d status_%d: 0x%X", + csid_hw->hw_intf->hw_idx, + th_payload->evt_status_arr[i]); + if (rc) { + for (i = 0; i < th_payload->num_registers; i++) + CAM_INFO(CAM_ISP, "CSID:%d status_%d: 0x%X", + csid_hw->hw_intf->hw_idx, + th_payload->evt_status_arr[i]); + return rc; + } + + for (i = 0; i < th_payload->num_registers; i++) + evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i]; + + th_payload->evt_payload_priv = evt_payload; + + return rc; +} + +static int cam_ife_csid_ver2_rx_err_top_half( + uint32_t evt_id, + struct cam_irq_th_payload *th_payload) +{ + int32_t rc = 0; + int i; + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_ife_csid_ver2_evt_payload *evt_payload; + + csid_hw = th_payload->handler_priv; + + if (!csid_hw) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "No private returned"); + return -ENODEV; + } + + rc = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload, + &csid_hw->rx_free_payload_list, + &csid_hw->rx_payload_lock); + + if (rc) { + for (i = 0; i < th_payload->num_registers; i++) + CAM_INFO(CAM_ISP, "CSID:%d status_%d: 0x%X", + csid_hw->hw_intf->hw_idx, + th_payload->evt_status_arr[i]); + return IRQ_HANDLED; + } + + evt_payload->irq_reg_val[CAM_IFE_CSID_IRQ_REG_RX] = + th_payload->evt_status_arr[CAM_IFE_CSID_IRQ_REG_RX]; + + th_payload->evt_payload_priv = evt_payload; + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver2_handle_rx_debug_event( + struct cam_ife_csid_ver2_hw *csid_hw, + uint32_t bit_pos) +{ + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_ver2_reg_info *csid_reg; + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + uint32_t mask, val; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + soc_info = &csid_hw->hw_info->soc_info; + mask = BIT(bit_pos); + + switch (mask) { + case IFE_CSID_VER2_RX_LONG_PKT_CAPTURED: + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_long_pkt_0_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt VC: %d DT: %d WC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->vc_mask, + val & csi2_reg->dt_mask, + val & csi2_reg->wc_mask); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_long_pkt_1_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt ECC: %d", + csid_hw->hw_intf->hw_idx, val); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_long_pkt_ftr_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt cal CRC: %d expected CRC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->calc_crc_mask, + val & csi2_reg->expected_crc_mask); + break; + + case IFE_CSID_VER2_RX_SHORT_PKT_CAPTURED: + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_short_pkt_0_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt VC: %d DT: %d LC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->vc_mask, + val & csi2_reg->dt_mask, + val & csi2_reg->wc_mask); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_short_pkt_1_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d Long pkt ECC: %d", + csid_hw->hw_intf->hw_idx, val); + break; + case IFE_CSID_VER2_RX_CPHY_PKT_HDR_CAPTURED: + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csi2_reg->captured_cphy_pkt_hdr_addr); + CAM_INFO_RATE_LIMIT(CAM_ISP, + "Csid :%d CPHY pkt VC: %d DT: %d LC: %d", + csid_hw->hw_intf->hw_idx, + val & csi2_reg->vc_mask, + val & csi2_reg->dt_mask, + val & csi2_reg->wc_mask); + break; + default: + CAM_INFO_RATE_LIMIT(CAM_ISP, + "CSID[%d] RX_IRQ: %s", + csid_hw->hw_intf->hw_idx, + ver2_rx_irq_desc[bit_pos].desc); + break; + } + + return 0; +} +static int cam_ife_csid_ver2_rx_top_half( + uint32_t evt_id, + struct cam_irq_th_payload *th_payload) +{ + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t irq_status; + uint32_t bit_pos = 0; + + csid_hw = th_payload->handler_priv; + + if (!csid_hw) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "No private returned"); + return -ENODEV; + } + + irq_status = th_payload->evt_status_arr[CAM_IFE_CSID_IRQ_REG_RX]; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + + while (irq_status) { + + if ((BIT(bit_pos)) & + csid_hw->debug_info.rx_mask) + cam_ife_csid_ver2_handle_rx_debug_event(csid_hw, + bit_pos); + bit_pos++; + irq_status >>= 1; + } + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver2_disable_csi2( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + int rc = 0; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + CAM_DBG(CAM_ISP, "CSID:%d Disable csi2 rx", + csid_hw->hw_intf->hw_idx); + + if (!csid_hw->flags.rx_enabled) { + CAM_DBG(CAM_ISP, "CSID:%d Rx already disabled", + csid_hw->hw_intf->hw_idx); + return 0; + } + + /* Reset the Rx CFG registers */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->cfg0_addr); + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->cfg1_addr); + + if (csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX]) { + rc = cam_irq_controller_unsubscribe_irq( + csid_hw->csid_irq_controller, + csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX]); + csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX] = 0; + } + + if (csid_hw->err_irq_handle[CAM_IFE_CSID_IRQ_REG_RX]) { + rc = cam_irq_controller_unsubscribe_irq( + csid_hw->csid_irq_controller, + csid_hw->err_irq_handle[CAM_IFE_CSID_IRQ_REG_RX]); + csid_hw->err_irq_handle[CAM_IFE_CSID_IRQ_REG_RX] = 0; + } + csid_hw->flags.rx_enabled = false; + + return 0; +} + +static int cam_ife_csid_ver2_rx_err_bottom_half( + void *handler_priv, + void *evt_payload_priv) +{ + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + struct cam_ife_csid_ver2_evt_payload *payload; + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint8_t *log_buf = NULL; + uint32_t irq_status; + uint32_t len = 0; + + if (!handler_priv || !evt_payload_priv) { + CAM_ERR(CAM_ISP, "Invalid params"); + return -EINVAL; + } + + payload = evt_payload_priv; + csid_hw = handler_priv; + + log_buf = csid_hw->log_buf; + memset(log_buf, 0, sizeof(csid_hw->log_buf)); + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + + irq_status = payload->irq_reg_val[CAM_IFE_CSID_IRQ_REG_RX] & + csi2_reg->fatal_err_mask; + + if (irq_status) { + + cam_ife_csid_ver2_disable_csi2(csid_hw); + len += scnprintf(log_buf, CAM_IFE_CSID_LOG_BUF_LEN - len, + "Overflow:\n "); + + if (irq_status & IFE_CSID_VER2_RX_LANE0_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_0\n"); + + if (irq_status & IFE_CSID_VER2_RX_LANE1_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_1\n"); + + if (irq_status & IFE_CSID_VER2_RX_LANE2_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_2\n"); + + if (irq_status & IFE_CSID_VER2_RX_LANE3_FIFO_OVERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, "LANE_3\n"); + } + + irq_status = payload->irq_reg_val[CAM_IFE_CSID_IRQ_REG_RX] & + csi2_reg->part_fatal_err_mask; + + if (irq_status) { + + len += scnprintf(log_buf, CAM_IFE_CSID_LOG_BUF_LEN - len, + "Part-fatal-errors:\n"); + + if (irq_status & IFE_CSID_VER2_RX_CPHY_EOT_RECEPTION) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "CPHY_EOT_RECEPTION\n"); + + if (irq_status & IFE_CSID_VER2_RX_CPHY_SOT_RECEPTION) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "CPHY_SOT_RECEPTION\n"); + + if (irq_status & IFE_CSID_VER2_RX_STREAM_UNDERFLOW) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "STREAM_UNDERFLOW\n"); + + if (irq_status & IFE_CSID_VER2_RX_UNBOUNDED_FRAME) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "UNBOUNDED_FRAME\n"); + } + + irq_status = payload->irq_reg_val[CAM_IFE_CSID_IRQ_REG_RX] & + csi2_reg->non_fatal_err_mask; + + if (irq_status) { + len += scnprintf(log_buf, CAM_IFE_CSID_LOG_BUF_LEN - len, + "Non-fatal-errors:\n"); + + if (irq_status & IFE_CSID_VER2_RX_MMAPPED_VC_DT) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "MMAPPED_VC_DT\n"); + + if (irq_status & IFE_CSID_VER2_RX_UNMAPPED_VC_DT) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "UNMAPPED_VC_DT\n"); + + if (irq_status & IFE_CSID_VER2_RX_ERROR_CRC) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "ERROR_CRC\n"); + + if (irq_status & IFE_CSID_VER2_RX_ERROR_ECC) + len += scnprintf(log_buf + len, + CAM_IFE_CSID_LOG_BUF_LEN - len, + "ERROR_ECC\n"); + } + + if (len) + CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%u] %s", + csid_hw->hw_intf->hw_idx, log_buf); + + cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload, + &csid_hw->rx_free_payload_list, + &csid_hw->rx_payload_lock); + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver2_parse_path_irq_status( + uint32_t index, + uint32_t irq_status, + uint32_t debug_mask, + uint32_t err_mask, + uint32_t hw_idx) +{ + uint32_t bit_pos = 0; + uint32_t temp_status; + const uint8_t **irq_reg_tag; + + irq_reg_tag = cam_ife_csid_get_irq_reg_tag_ptr(); + temp_status = irq_status & err_mask; + + while (temp_status) { + + if (temp_status & 0x1) + CAM_ERR_RATE_LIMIT(CAM_ISP, + "CSID[%d] IRQ %s %s ", + hw_idx, irq_reg_tag[index], + ver2_path_irq_desc[bit_pos].desc); + + bit_pos++; + temp_status >>= 1; + } + + temp_status = irq_status & debug_mask; + bit_pos = 0; + while (temp_status) { + + if (temp_status & 0x1) + CAM_INFO_RATE_LIMIT(CAM_ISP, + "CSID[%d] IRQ %s %s ", + hw_idx, irq_reg_tag[index], + ver2_path_irq_desc[bit_pos].desc); + + bit_pos++; + temp_status >>= 1; + } + + return 0; +} + +static int cam_ife_csid_ver2_ipp_bottom_half( + void *handler_priv, + void *evt_payload_priv) +{ + struct cam_ife_csid_ver2_evt_payload *payload; + struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_isp_hw_event_info evt_info; + uint32_t irq_status_ipp; + uint32_t err_mask; + char tag[15]; + + if (!handler_priv || !evt_payload_priv) { + CAM_ERR(CAM_ISP, "Invalid params"); + return -EINVAL; + } + + payload = evt_payload_priv; + csid_hw = handler_priv; + + irq_status_ipp = payload->irq_reg_val[CAM_IFE_CSID_IRQ_REG_IPP]; + + snprintf(tag, sizeof(tag), "CSID:%d IPP", csid_hw->hw_intf->hw_idx); + + CAM_DBG(CAM_ISP, "%s status:0x%x", tag, irq_status_ipp); + + evt_info.hw_idx = csid_hw->hw_intf->hw_idx; + evt_info.res_id = CAM_IFE_PIX_PATH_RES_IPP; + evt_info.res_type = CAM_ISP_RESOURCE_PIX_PATH; + evt_info.reg_val = irq_status_ipp; + + if (irq_status_ipp & IFE_CSID_VER2_PATH_CAMIF_EOF) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_EOF, (void *)&evt_info); + } + + if (irq_status_ipp & IFE_CSID_VER2_PATH_CAMIF_SOF) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_SOF, (void *)&evt_info); + } + + if (irq_status_ipp & IFE_CSID_VER2_PATH_RUP_DONE) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_REG_UPDATE, (void *)&evt_info); + } + + if (irq_status_ipp & IFE_CSID_VER2_PATH_CAMIF_EPOCH0) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_EPOCH, (void *)&evt_info); + } + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + err_mask = csid_reg->ipp_reg->fatal_err_mask | + csid_reg->ipp_reg->non_fatal_err_mask; + + cam_ife_csid_ver2_parse_path_irq_status( + CAM_IFE_CSID_IRQ_REG_IPP, + irq_status_ipp, + csid_hw->debug_info.path_mask, + err_mask, + csid_hw->hw_intf->hw_idx); + + cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload, + &csid_hw->path_free_payload_list, + &csid_hw->path_payload_lock); + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver2_ppp_bottom_half( + void *handler_priv, + void *evt_payload_priv) +{ + struct cam_ife_csid_ver2_evt_payload *payload; + struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + uint32_t irq_status_ppp; + uint32_t err_mask; + + if (!handler_priv || !evt_payload_priv) { + CAM_ERR(CAM_ISP, "Invalid params"); + return -EINVAL; + } + + payload = evt_payload_priv; + csid_hw = handler_priv; + + irq_status_ppp = payload->irq_reg_val[CAM_IFE_CSID_IRQ_REG_PPP]; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + err_mask = csid_reg->ppp_reg->fatal_err_mask | + csid_reg->ppp_reg->non_fatal_err_mask; + + cam_ife_csid_ver2_parse_path_irq_status( + CAM_IFE_CSID_IRQ_REG_PPP, + irq_status_ppp, + csid_hw->debug_info.path_mask, + err_mask, + csid_hw->hw_intf->hw_idx); + + cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload, + &csid_hw->path_free_payload_list, + &csid_hw->path_payload_lock); + + return IRQ_HANDLED; +} + +static int cam_ife_csid_ver2_rdi_bottom_half( + void *handler_priv, + void *evt_payload_priv) +{ + struct cam_ife_csid_ver2_evt_payload *payload; + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + const struct cam_ife_csid_ver2_rdi_reg_info *rdi_reg; + struct cam_isp_resource_node *res; + uint32_t irq_status_rdi, i; + uint32_t err_mask, rdi_idx; + struct cam_isp_hw_event_info evt_info; + + if (!handler_priv || !evt_payload_priv) { + CAM_ERR(CAM_ISP, "Invalid params"); + return -EINVAL; + } + + payload = evt_payload_priv; + csid_hw = handler_priv; + + evt_info.hw_idx = csid_hw->hw_intf->hw_idx; + evt_info.res_type = CAM_ISP_RESOURCE_PIX_PATH; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + for (i = CAM_IFE_CSID_IRQ_REG_RDI_0; + i <= CAM_IFE_CSID_IRQ_REG_RDI_4; i++) { + + irq_status_rdi = payload->irq_reg_val[i]; + rdi_idx = i - CAM_IFE_CSID_IRQ_REG_RDI_0; + + if (!irq_status_rdi) + continue; + + CAM_DBG(CAM_ISP, "CSID[%u] RDI:%d status:0x%x", + csid_hw->hw_intf->hw_idx, + rdi_idx, irq_status_rdi); + + res = &csid_hw->path_res[rdi_idx]; + + if (!res) + continue; + rdi_reg = csid_reg->rdi_reg[rdi_idx]; + + if (!rdi_reg) + continue; + + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + + if (!path_cfg->handle_camif_irq) { + err_mask = rdi_reg->non_fatal_err_mask | + rdi_reg->fatal_err_mask; + cam_ife_csid_ver2_parse_path_irq_status(i, + irq_status_rdi, + csid_hw->debug_info.path_mask, + err_mask, + csid_hw->hw_intf->hw_idx); + continue; + } + + evt_info.res_id = rdi_idx; + evt_info.reg_val = irq_status_rdi; + + if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_EOF) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_EOF, + (void *)&evt_info); + } + + if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_SOF) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_SOF, + (void *)&evt_info); + } + + if (irq_status_rdi & IFE_CSID_VER2_PATH_RUP_DONE) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_REG_UPDATE, + (void *)&evt_info); + } + + if (irq_status_rdi & IFE_CSID_VER2_PATH_CAMIF_EPOCH0) { + if (csid_hw->event_cb) + csid_hw->event_cb(csid_hw->token, + CAM_ISP_HW_EVENT_EPOCH, + (void *)&evt_info); + } + + } + + cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload, + &csid_hw->path_free_payload_list, + &csid_hw->path_payload_lock); + + return IRQ_HANDLED; +} + +int cam_ife_csid_ver2_get_hw_caps(void *hw_priv, + void *get_hw_cap_args, uint32_t arg_size) +{ + int rc = 0; + struct cam_ife_csid_hw_caps *hw_caps; + struct cam_ife_csid_ver2_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_ife_csid_ver2_reg_info *csid_reg; + + + if (!hw_priv || !get_hw_cap_args) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + hw_caps->num_rdis = csid_reg->cmn_reg->num_rdis; + hw_caps->num_pix = csid_reg->cmn_reg->num_pix; + hw_caps->num_ppp = csid_reg->cmn_reg->num_ppp; + hw_caps->major_version = csid_reg->cmn_reg->major_version; + hw_caps->minor_version = csid_reg->cmn_reg->minor_version; + hw_caps->version_incr = csid_reg->cmn_reg->version_incr; + hw_caps->global_reset_en = csid_reg->cmn_reg->global_reset; + hw_caps->rup_en = csid_reg->cmn_reg->rup_supported; + + CAM_DBG(CAM_ISP, + "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d", + csid_hw->hw_intf->hw_idx, hw_caps->num_rdis, + hw_caps->num_pix, hw_caps->major_version, + hw_caps->minor_version, hw_caps->version_incr); + + return rc; +} + +static int cam_ife_csid_ver2_wait_for_reset( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + unsigned long rem_jiffies = 0; + int rc = 0; + + rem_jiffies = wait_for_completion_timeout( + &csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP], + msecs_to_jiffies(CAM_IFE_CSID_RESET_TIMEOUT_MS)); + + if (rem_jiffies == 0) { + rc = -ETIMEDOUT; + CAM_ERR(CAM_ISP, + "CSID[%d], mode[%d] reset time out", + csid_hw->hw_intf->hw_idx, + csid_hw->sync_mode); + } else { + CAM_DBG(CAM_ISP, + "CSID[%d], mode[%d] reset success", + csid_hw->hw_intf->hw_idx, + csid_hw->sync_mode); + } + + return rc; +} + +static int cam_ife_csid_ver2_reset_irq_top_half(uint32_t evt_id, + struct cam_irq_th_payload *th_payload) +{ + struct cam_ife_csid_ver2_hw *csid_hw; + + csid_hw = th_payload->handler_priv; + + CAM_DBG(CAM_ISP, "TOP_IRQ_STATUS_0 = 0x%x", + th_payload->evt_status_arr[0]); + complete(&csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]); + + return 0; +} + +static int cam_ife_csid_ver2_internal_reset( + struct cam_ife_csid_ver2_hw *csid_hw, + uint32_t rst_cmd, uint32_t rst_location, uint32_t rst_mode) +{ + uint32_t val = 0; + struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + void __iomem *mem_base; + int rc = 0; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + soc_info = &csid_hw->hw_info->soc_info; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + + if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { + CAM_ERR(CAM_ISP, "CSID[%d] powered down state", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_SLAVE) + goto wait_only; + + /*Program the reset location */ + if (rst_location == CAM_IFE_CSID_RESET_LOC_PATH_ONLY) + val |= (csid_reg->cmn_reg->rst_loc_path_only_val << + csid_reg->cmn_reg->rst_location_shift_val); + else if (rst_location == CAM_IFE_CSID_RESET_LOC_COMPLETE) + val |= (csid_reg->cmn_reg->rst_loc_complete_csid_val << + csid_reg->cmn_reg->rst_location_shift_val); + + /*Program the mode */ + if (rst_mode == CAM_CSID_HALT_AT_FRAME_BOUNDARY) + val |= (csid_reg->cmn_reg->rst_mode_frame_boundary_val << + csid_reg->cmn_reg->rst_mode_shift_val); + else if (rst_mode == CAM_CSID_HALT_IMMEDIATELY) + val |= (csid_reg->cmn_reg->rst_mode_immediate_val << + csid_reg->cmn_reg->rst_mode_shift_val); + + cam_io_w_mb(val, mem_base + csid_reg->cmn_reg->reset_cfg_addr); + + val = 0; + /*Program the cmd */ + if (rst_cmd == CAM_IFE_CSID_RESET_CMD_IRQ_CTRL) + val = csid_reg->cmn_reg->rst_cmd_irq_ctrl_only_val; + else if (rst_cmd == CAM_IFE_CSID_RESET_CMD_HW_RST) + val = csid_reg->cmn_reg->rst_cmd_hw_reset_complete_val; + else if (rst_cmd == CAM_IFE_CSID_RESET_CMD_SW_RST) + val = csid_reg->cmn_reg->rst_cmd_sw_reset_complete_val; + + cam_io_w_mb( + val, mem_base + csid_reg->cmn_reg->reset_cmd_addr); + +wait_only: + /* Mask all top irq except reset */ + cam_io_w_mb( + BIT(csid_reg->cmn_reg->top_reset_irq_shift_val), + mem_base + csid_reg->cmn_reg->top_irq_mask_addr); + + rc = cam_ife_csid_ver2_wait_for_reset(csid_hw); + cam_io_r_mb(mem_base + csid_reg->cmn_reg->top_irq_status_addr); + if (rc) + CAM_ERR(CAM_ISP, + "CSID[%d] Reset failed mode %d cmd %d loc %d", + csid_hw->hw_intf->hw_idx, + rst_mode, rst_location, rst_cmd); + return rc; +} + +int cam_ife_csid_ver2_reset(void *hw_priv, + void *reset_args, uint32_t arg_size) +{ + struct cam_hw_info *hw_info; + struct cam_ife_csid_ver2_hw *csid_hw; + struct cam_csid_reset_cfg_args *reset; + uint32_t irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; + int rc = 0; + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + reset = (struct cam_csid_reset_cfg_args *)reset_args; + + mutex_lock(&csid_hw->hw_info->hw_mutex); + + irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = IFE_CSID_VER2_TOP_IRQ_STATUS_RST; + + csid_hw->reset_irq_handle = cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_0, + irq_mask, + csid_hw, + cam_ife_csid_ver2_reset_irq_top_half, + NULL, + NULL, + NULL); + + if (csid_hw->reset_irq_handle < 1) { + CAM_ERR(CAM_ISP, "csid[%d] reset irq subscribe fail", + csid_hw->hw_intf->hw_idx); + goto end; + } + + switch (reset->reset_type) { + case CAM_IFE_CSID_RESET_GLOBAL: + rc = cam_ife_csid_ver2_internal_reset(csid_hw, + CAM_IFE_CSID_RESET_CMD_SW_RST, + CAM_IFE_CSID_RESET_LOC_COMPLETE, + CAM_CSID_HALT_IMMEDIATELY); + break; + case CAM_IFE_CSID_RESET_PATH: + rc = cam_ife_csid_ver2_internal_reset(csid_hw, + CAM_IFE_CSID_RESET_CMD_HW_RST, + CAM_IFE_CSID_RESET_LOC_PATH_ONLY, + CAM_CSID_HALT_AT_FRAME_BOUNDARY); + break; + default: + CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d", + reset->reset_type); + rc = -EINVAL; + break; + } + + if (rc) + CAM_ERR(CAM_ISP, "CSID[%d] reset type :%d fail", + csid_hw->hw_intf->hw_idx, + reset->reset_type); + + CAM_DBG(CAM_ISP, "CSID[%d] reset type :%d", + csid_hw->hw_intf->hw_idx, + reset->reset_type); + + if (csid_hw->reset_irq_handle) { + rc = cam_irq_controller_unsubscribe_irq( + csid_hw->csid_irq_controller, + csid_hw->reset_irq_handle); + csid_hw->reset_irq_handle = 0; + } +end: + mutex_unlock(&csid_hw->hw_info->hw_mutex); + return rc; +} + +static int cam_ife_csid_ver2_disable_path( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + uint32_t reg_id = 0, irq_idx = 0; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + + if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + reg_id = cam_ife_csid_convert_res_to_irq_reg(res->res_id); + irq_idx = cam_ife_csid_get_rt_irq_idx( + reg_id, + csid_reg->cmn_reg->num_pix, + csid_reg->cmn_reg->num_ppp, + csid_reg->cmn_reg->num_rdis); + + if (csid_hw->irq_handle[irq_idx]) { + rc = cam_irq_controller_unsubscribe_irq( + csid_hw->csid_irq_controller, + csid_hw->irq_handle[irq_idx]); + csid_hw->irq_handle[irq_idx] = 0; + } + + return rc; +} + +static int cam_ife_csid_hw_ver2_config_path_data( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_ife_csid_ver2_path_cfg *path_cfg, + struct cam_csid_hw_reserve_resource_args *reserve, + uint32_t cid) +{ + + path_cfg->cid = cid; + path_cfg->in_format = reserve->in_port->format; + path_cfg->out_format = reserve->out_port->format; + path_cfg->sync_mode = reserve->sync_mode; + path_cfg->height = reserve->in_port->height; + path_cfg->start_line = reserve->in_port->line_start; + path_cfg->end_line = reserve->in_port->line_stop; + path_cfg->crop_enable = reserve->crop_enable; + path_cfg->drop_enable = reserve->drop_enable; + path_cfg->horizontal_bin = reserve->in_port->horizontal_bin; + path_cfg->qcfa_bin = reserve->in_port->qcfa_bin; + path_cfg->num_bytes_out = reserve->in_port->num_bytes_out; + path_cfg->pix_pattern = reserve->in_port->test_pattern; + if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) { + path_cfg->start_pixel = reserve->in_port->left_start; + path_cfg->end_pixel = reserve->in_port->left_stop; + path_cfg->width = reserve->in_port->left_width; + + if (reserve->res_id >= CAM_IFE_PIX_PATH_RES_RDI_0 && + reserve->res_id <= (CAM_IFE_PIX_PATH_RES_RDI_0 + + CAM_IFE_CSID_RDI_MAX - 1)) { + path_cfg->end_pixel = reserve->in_port->right_stop; + path_cfg->width = path_cfg->end_pixel - + path_cfg->start_pixel + 1; + } + CAM_DBG(CAM_ISP, + "CSID:%d res:%d master:startpixel 0x%x endpixel:0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_pixel, path_cfg->end_pixel); + CAM_DBG(CAM_ISP, + "CSID:%d res:%d master:line start:0x%x line end:0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_line, path_cfg->end_line); + } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) { + path_cfg->start_pixel = reserve->in_port->right_start; + path_cfg->end_pixel = reserve->in_port->right_stop; + path_cfg->width = reserve->in_port->right_width; + CAM_DBG(CAM_ISP, + "CSID:%d res:%d slave:start:0x%x end:0x%x width 0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_pixel, path_cfg->end_pixel, + path_cfg->width); + CAM_DBG(CAM_ISP, + "CSID:%d res:%d slave:line start:0x%x line end:0x%x", + csid_hw->hw_intf->hw_idx, reserve->res_id, + path_cfg->start_line, path_cfg->end_line); + } else { + path_cfg->width = reserve->in_port->left_width; + path_cfg->start_pixel = reserve->in_port->left_start; + path_cfg->end_pixel = reserve->in_port->left_stop; + CAM_DBG(CAM_ISP, + "CSID:%d res:%d left width %d start: %d stop:%d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + reserve->in_port->left_width, + reserve->in_port->left_start, + reserve->in_port->left_stop); + } + return 0; +} + +static int cam_ife_csid_hw_ver2_config_rx( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_csid_hw_reserve_resource_args *reserve) +{ + + /*Before calling this function we already validated the + * sancitity of in port args. If this function is called + * from somewhere else as well, please make sure to validate the + * in_port args before coming here. + */ + if (csid_hw->counters.csi2_reserve_cnt) { + CAM_DBG(CAM_ISP, "CSID %d Rx already reserved cnt %d", + csid_hw->hw_intf->hw_idx, + csid_hw->counters.csi2_reserve_cnt); + csid_hw->counters.csi2_reserve_cnt++; + return 0; + } + + csid_hw->rx_cfg.lane_cfg = + reserve->in_port->lane_cfg; + csid_hw->rx_cfg.lane_type = + reserve->in_port->lane_type; + csid_hw->rx_cfg.lane_num = + reserve->in_port->lane_num; + csid_hw->res_type = reserve->in_port->res_type; + + switch (reserve->in_port->res_type) { + case CAM_ISP_IFE_IN_RES_TPG: + csid_hw->rx_cfg.phy_sel = 0; + csid_hw->rx_cfg.tpg_mux_sel = 0; + case CAM_ISP_IFE_IN_RES_CPHY_TPG_0: + csid_hw->rx_cfg.tpg_mux_sel = 1; + csid_hw->rx_cfg.tpg_num_sel = 1; + break; + case CAM_ISP_IFE_IN_RES_CPHY_TPG_1: + csid_hw->rx_cfg.tpg_mux_sel = 1; + csid_hw->rx_cfg.tpg_num_sel = 2; + break; + default: + csid_hw->rx_cfg.tpg_mux_sel = 0; + csid_hw->rx_cfg.phy_sel = + (reserve->in_port->res_type & 0xFF); + break; + } + + csid_hw->counters.csi2_reserve_cnt++; + CAM_DBG(CAM_ISP, + "CSID:%d Rx lane param: cfg:%u type:%u num:%u res:%u", + csid_hw->hw_intf->hw_idx, + reserve->in_port->lane_cfg, reserve->in_port->lane_type, + reserve->in_port->lane_num, reserve->in_port->res_type); + + return 0; + +} + +static int cam_ife_csid_ver_config_camif( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_csid_hw_reserve_resource_args *reserve, + struct cam_ife_csid_ver2_path_cfg *path_cfg) +{ + int rc = 0; + uint32_t epoch0 = 0; + struct cam_ife_csid_ver2_reg_info *csid_reg; + const struct cam_ife_csid_ver2_rdi_reg_info *rdi_reg = NULL; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + switch (reserve->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + epoch0 = (path_cfg->end_line - path_cfg->start_line)/ + csid_reg->cmn_reg->epoch_div_factor; + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rdi_reg = csid_reg->rdi_reg[reserve->res_id]; + if (!rdi_reg) { + rc = -EINVAL; + CAM_ERR(CAM_ISP, "CSID[%d] invalid res %d", + csid_hw->hw_intf->hw_idx, reserve->res_id); + goto end; + } + epoch0 = rdi_reg->epoch0_cfg_val; + break; + } + + path_cfg->camif_data.epoch0 = epoch0; + + path_cfg->camif_data.pix_pattern = reserve->in_port->test_pattern; + +end: + CAM_DBG(CAM_ISP, "CSID[%d] pix_pattern: %d epoch0: 0x%x", + csid_hw->hw_intf->hw_idx, + path_cfg->camif_data.pix_pattern, epoch0); + return rc; +} + +int cam_ife_csid_hw_ver2_hw_cfg( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_ife_csid_ver2_path_cfg *path_cfg, + struct cam_csid_hw_reserve_resource_args *reserve, + uint32_t cid) +{ + int rc = 0; + + rc = cam_ife_csid_hw_ver2_config_rx(csid_hw, reserve); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] rx config failed", + csid_hw->hw_intf->hw_idx); + return rc; + } + + cam_ife_csid_hw_ver2_config_path_data(csid_hw, path_cfg, + reserve, cid); + rc = cam_ife_csid_ver_config_camif(csid_hw, reserve, path_cfg); + + if (rc) + CAM_ERR(CAM_ISP, "CSID[%d] camif config failed", + csid_hw->hw_intf->hw_idx); + + return rc; +} + +static int cam_ife_csid_ver2_in_port_validate( + struct cam_csid_hw_reserve_resource_args *reserve, + struct cam_ife_csid_ver2_hw *csid_hw) +{ + int rc = 0; + struct cam_ife_csid_ver2_reg_info *csid_reg; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + /* check in port args */ + rc = cam_ife_csid_check_in_port_args(reserve, + csid_hw->hw_intf->hw_idx); + if (rc) + goto err; + + if (csid_hw->counters.csi2_reserve_cnt) { + + if (csid_hw->token != reserve->cb_priv) { + CAM_ERR(CAM_ISP, + "CSID[%d] different Context for res %d", + csid_hw->hw_intf->hw_idx, + reserve->res_id); + rc = -EINVAL; + goto err; + } + + if (csid_hw->res_type != reserve->in_port->res_type) { + CAM_ERR(CAM_ISP, + "CSID[%d] Invalid res[%d] in_res_type[%d]", + csid_hw->hw_intf->hw_idx, + csid_hw->res_type, + reserve->in_port->res_type); + rc = -EINVAL; + goto err; + } + + if (csid_hw->rx_cfg.lane_cfg != + reserve->in_port->lane_cfg || + csid_hw->rx_cfg.lane_type != + reserve->in_port->lane_type || + csid_hw->rx_cfg.lane_num != + reserve->in_port->lane_num) { + CAM_ERR(CAM_ISP, + "lane: num[%d %d] type[%d %d] cfg[%d %d]", + csid_hw->hw_intf->hw_idx, + csid_hw->rx_cfg.lane_num, + reserve->in_port->lane_num, + csid_hw->rx_cfg.lane_type, + reserve->in_port->lane_type, + csid_hw->rx_cfg.lane_cfg, + reserve->in_port->lane_cfg); + rc = -EINVAL; + goto err; + } + } + + return rc; +err: + CAM_ERR(CAM_ISP, "Invalid args csid[%d] rc %d", + csid_hw->hw_intf->hw_idx, rc); + return rc; +} + +int cam_ife_csid_ver2_reserve(void *hw_priv, + void *reserve_args, uint32_t arg_size) +{ + + struct cam_ife_csid_ver2_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_isp_resource_node *res = NULL; + struct cam_csid_hw_reserve_resource_args *reserve; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t cid; + int rc = 0; + + reserve = (struct cam_csid_hw_reserve_resource_args *)reserve_args; + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + res = &csid_hw->path_res[reserve->res_id]; + if (res->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) { + CAM_ERR(CAM_ISP, "CSID %d Res_id %d state %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state); + return -EINVAL; + } + + rc = cam_ife_csid_ver2_in_port_validate(reserve, csid_hw); + if (rc) { + CAM_ERR(CAM_ISP, "CSID %d Res_id %d port validation failed", + csid_hw->hw_intf->hw_idx, reserve->res_id); + return rc; + } + + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + if (!path_cfg) { + CAM_ERR(CAM_ISP, + "CSID %d Unallocated Res_id %d state %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state); + return -EINVAL; + } + + rc = cam_ife_csid_cid_reserve(csid_hw->cid_data, &cid, + csid_hw->hw_intf->hw_idx, reserve); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID %d Res_id %d state %d invalid cid %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state, cid); + return rc; + } + + rc = cam_ife_csid_hw_ver2_hw_cfg(csid_hw, path_cfg, + reserve, cid); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] res %d hw_cfg fail", + csid_hw->hw_intf->hw_idx, reserve->res_id); + goto release; + } + reserve->node_res = res; + + res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + csid_hw->event_cb = reserve->event_cb; + csid_hw->tasklet = reserve->tasklet; + csid_hw->token = reserve->cb_priv; + reserve->buf_done_controller = csid_hw->buf_done_irq_controller; + res->cdm_ops = reserve->cdm_ops; + csid_hw->flags.sfe_inline_shdr = reserve->sfe_inline_shdr; + + reserve->need_top_cfg = csid_reg->need_top_cfg; + + CAM_DBG(CAM_ISP, "CSID %d Res_id %d state %d cid %d", + csid_hw->hw_intf->hw_idx, reserve->res_id, + res->res_state, cid); + + return rc; + +release: + cam_ife_csid_cid_release(&csid_hw->cid_data[cid], + csid_hw->hw_intf->hw_idx, + path_cfg->cid); + return rc; +} + +int cam_ife_csid_ver2_release(void *hw_priv, + void *release_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver2_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_isp_resource_node *res = NULL; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + int rc = 0; + + if (!hw_priv || !release_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + res = (struct cam_isp_resource_node *)release_args; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + return -EINVAL; + } + + mutex_lock(&csid_hw->hw_info->hw_mutex); + + if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH && + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + rc = -EINVAL; + goto end; + } + + if ((res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) || + (res->res_state >= CAM_ISP_RESOURCE_STATE_STREAMING)) { + CAM_WARN(CAM_ISP, + "CSID:%d res type:%d Res %d in state %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, + res->res_state); + goto end; + } + + CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); + + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + + cam_ife_csid_cid_release(&csid_hw->cid_data[path_cfg->cid], + csid_hw->hw_intf->hw_idx, + path_cfg->cid); + + memset(path_cfg, 0, sizeof(*path_cfg)); + + if (csid_hw->counters.csi2_reserve_cnt) + csid_hw->counters.csi2_reserve_cnt--; + + if (!csid_hw->counters.csi2_reserve_cnt) { + memset(&csid_hw->rx_cfg, 0, + sizeof(struct cam_ife_csid_rx_cfg)); + memset(&csid_hw->top_cfg, 0, + sizeof(struct cam_ife_csid_ver2_top_cfg)); + csid_hw->token = NULL; + } + + res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; +end: + mutex_unlock(&csid_hw->hw_info->hw_mutex); + return rc; +} + +static int cam_ife_csid_ver2_shdr_cfg( + struct cam_ife_csid_ver2_hw *csid_hw, + uint32_t res_id) +{ + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t val; + void __iomem *mem_base; + struct cam_hw_soc_info *soc_info; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + val = cam_io_r_mb(mem_base + + csid_reg->cmn_reg->shdr_master_slave_cfg_addr); + + switch (res_id) { + + case CAM_IFE_PIX_PATH_RES_RDI_0: + val |= BIT(csid_reg->cmn_reg->shdr_master_rdi0_shift); + break; + case CAM_IFE_PIX_PATH_RES_RDI_1: + val |= BIT(csid_reg->cmn_reg->shdr_slave_rdi1_shift); + break; + case CAM_IFE_PIX_PATH_RES_RDI_2: + val |= BIT(csid_reg->cmn_reg->shdr_slave_rdi2_shift); + break; + default: + break; + } + + val |= BIT(csid_reg->cmn_reg->shdr_master_slave_en_shift); + + cam_io_w_mb(val, mem_base + + csid_reg->cmn_reg->shdr_master_slave_cfg_addr); + + CAM_DBG(CAM_ISP, "CSID %d shdr cfg %x", csid_hw->hw_intf->hw_idx, + val); + + return 0; +} + +static int cam_ife_csid_ver2_init_config_rdi_path( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_rdi_reg_info *path_reg = NULL; + const struct cam_ife_csid_ver2_common_reg_info *cmn_reg = NULL; + uint32_t val; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + struct cam_ife_csid_cid_data *cid_data; + struct cam_ife_csid_path_format path_format = {0}; + bool is_rpp = false; + void __iomem *mem_base; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + if (!csid_reg->rdi_reg[res->res_id]) { + CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + cmn_reg = csid_reg->cmn_reg; + path_reg = csid_reg->rdi_reg[res->res_id]; + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + cid_data = &csid_hw->cid_data[path_cfg->cid]; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + is_rpp = path_cfg->crop_enable || path_cfg->drop_enable; + rc = cam_ife_csid_get_format_rdi(path_cfg->in_format, + path_cfg->out_format, &path_format, is_rpp); + if (rc) + return rc; + + /*Configure cfg0: + * VC + * DT + * DT_ID cobination + * Decode Format + * Frame_id_dec_en + * VFR en + * offline mode + */ + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc << + cmn_reg->vc_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt << + cmn_reg->dt_shift_val) | + (path_cfg->cid << cmn_reg->dt_id_shift_val) | + (path_format.decode_fmt << cmn_reg->decode_format_shift_val) | + (path_cfg->offline_mode << + path_reg->offline_mode_en_shift_val); + + if (csid_reg->cmn_reg->vfr_supported) + val |= path_cfg->vfr_en << cmn_reg->vfr_en_shift_val; + + if (csid_reg->cmn_reg->frame_id_dec_supported) + val |= path_cfg->frame_id_dec_en << + cmn_reg->frame_id_decode_en_shift_val; + + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + /*Configure Multi VC DT combo */ + if (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].valid) { + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].vc << + cmn_reg->multi_vcdt_vc1_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].dt << + cmn_reg->multi_vcdt_dt1_shift_val) | + (1 << cmn_reg->multi_vcdt_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->multi_vcdt_cfg0_addr); + } + + /*configure cfg1 addr + * Crop/Drop parameters + * Timestamp enable and strobe selection + * Plain format + * Packing format + */ + val = (path_cfg->crop_enable << path_reg->crop_h_en_shift_val) | + (path_cfg->crop_enable << + path_reg->crop_v_en_shift_val); + + if (cmn_reg->drop_supported) + val |= (path_cfg->drop_enable << + path_reg->drop_v_en_shift_val) | + (path_cfg->drop_enable << + path_reg->drop_h_en_shift_val); + + val |= (1 << path_reg->timestamp_en_shift_val) | + (cmn_reg->timestamp_strobe_val << + cmn_reg->timestamp_stb_sel_shift_val); + + if (path_reg->mipi_pack_supported) + val |= path_format.packing_fmt << + path_reg->packing_fmt_shift_val; + + val |= path_format.plain_fmt << path_reg->plain_fmt_shift_val; + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) + val |= 1 << path_reg->format_measure_en_shift_val; + + cam_io_w_mb(val, mem_base + path_reg->cfg1_addr); + + if (path_cfg->crop_enable) { + val = (((path_cfg->end_pixel & cmn_reg->crop_pix_start_mask) << + cmn_reg->crop_shift_val) | + (path_cfg->start_pixel & cmn_reg->crop_pix_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->hcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + + val = (((path_cfg->end_line & cmn_reg->crop_line_start_mask) << + csid_reg->cmn_reg->crop_shift_val) | + (path_cfg->start_line & cmn_reg->crop_line_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->vcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + } + + /* set frame drop pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->frm_drop_period_addr); + cam_io_w_mb(0, mem_base + path_reg->frm_drop_pattern_addr); + /* set irq sub sample pattern to 1 and period to 0 */ + cam_io_w_mb(0, mem_base + path_reg->irq_subsample_period_addr); + cam_io_w_mb(1, mem_base + path_reg->irq_subsample_pattern_addr); + + /*TODO Need to check for any hw errata like 480 and 580*/ + /* set pxl drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->pix_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->pix_drop_period_addr); + + /* set line drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->line_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->line_drop_period_addr); + + /* Enable the RDI path */ + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + val |= (1 << cmn_reg->path_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + if (path_reg->overflow_ctrl_en) { + val = path_reg->overflow_ctrl_en | + path_reg->overflow_ctrl_mode_val; + cam_io_w_mb(val, mem_base + + path_reg->err_recovery_cfg0_addr); + } + + if (csid_hw->flags.sfe_inline_shdr) + cam_ife_csid_ver2_shdr_cfg(csid_hw, res->res_id); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, mem_base + + path_reg->format_measure_cfg0_addr); + } + + cam_io_w_mb(val, mem_base + + csid_reg->csi2_reg->capture_ctrl_addr); + CAM_DBG(CAM_ISP, "rx capture control value 0x%x", val); + + return rc; +} + +static int cam_ife_csid_ver2_init_config_pxl_path( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_pxl_reg_info *path_reg = NULL; + const struct cam_ife_csid_ver2_common_reg_info *cmn_reg = NULL; + uint32_t val = 0; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + struct cam_ife_csid_cid_data *cid_data; + struct cam_ife_csid_path_format path_format = {0}; + void __iomem *mem_base; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + path_reg = csid_reg->ipp_reg; + else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + path_reg = csid_reg->ppp_reg; + + cmn_reg = csid_reg->cmn_reg; + + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + cid_data = &csid_hw->cid_data[path_cfg->cid]; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + + rc = cam_ife_csid_get_format_ipp_ppp(path_cfg->in_format, + &path_format); + + /*Configure: + * VC + * DT + * DT_ID cobination + * Decode Format + * Frame_id_dec_en + * VFR en + */ + val |= (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc << + cmn_reg->vc_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt << + cmn_reg->dt_shift_val) | + (path_cfg->cid << cmn_reg->dt_id_shift_val) | + (path_format.decode_fmt << cmn_reg->decode_format_shift_val); + + if (csid_reg->cmn_reg->vfr_supported) + val |= path_cfg->vfr_en << cmn_reg->vfr_en_shift_val; + + if (csid_reg->cmn_reg->frame_id_dec_supported) + val |= path_cfg->frame_id_dec_en << + cmn_reg->frame_id_decode_en_shift_val; + + CAM_DBG(CAM_ISP, "CSID[%d] res:%d cfg0_addr 0x%x", + csid_hw->hw_intf->hw_idx, res->res_id, + val); + + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + /*Configure Multi VC DT combo */ + if (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].valid) { + val = (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].vc << + cmn_reg->multi_vcdt_vc1_shift_val) | + (cid_data->vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_1].dt << + cmn_reg->multi_vcdt_dt1_shift_val) | + (1 << cmn_reg->multi_vcdt_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->multi_vcdt_cfg0_addr); + } + + val = 0; + /*configure cfg1 addr + * Binning + * Crop/Drop parameters + * Early Eof + * Timestamp enable and strobe selection + * Pix store enable + */ + + if (csid_hw->flags.binning_enabled) { + + if (path_reg->binning_supported & CAM_IFE_CSID_BIN_HORIZONTAL) + val |= path_cfg->horizontal_bin << + path_reg->bin_h_en_shift_val; + + if (path_reg->binning_supported & CAM_IFE_CSID_BIN_VERTICAL) + val |= path_cfg->vertical_bin << + path_reg->bin_v_en_shift_val; + + if (path_reg->binning_supported & CAM_IFE_CSID_BIN_QCFA) + val |= path_cfg->qcfa_bin << + path_reg->bin_qcfa_en_shift_val; + + if (path_cfg->qcfa_bin || path_cfg->vertical_bin || + path_cfg->horizontal_bin) + val |= 1 << path_reg->bin_en_shift_val; + } + + val |= (path_cfg->crop_enable << path_reg->crop_h_en_shift_val) | + (path_cfg->crop_enable << + path_reg->crop_v_en_shift_val); + + if (cmn_reg->drop_supported) + val |= (path_cfg->drop_enable << + path_reg->drop_v_en_shift_val) | + (path_cfg->drop_enable << + path_reg->drop_h_en_shift_val); + + val |= 1 << path_reg->pix_store_en_shift_val; + val |= 1 << path_reg->timestamp_en_shift_val; + val |= cmn_reg->timestamp_strobe_val << + cmn_reg->timestamp_stb_sel_shift_val; + + /*enable early eof based on crop enable */ + if (!(csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_DISABLE_EARLY_EOF) && + cmn_reg->early_eof_supported && + path_cfg->crop_enable) + val |= (1 << path_reg->early_eof_en_shift_val); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) + val |= 1 << path_reg->format_measure_en_shift_val; + + CAM_DBG(CAM_ISP, "CSID[%d] res:%d cfg1_addr 0x%x", + csid_hw->hw_intf->hw_idx, res->res_id, + val); + + cam_io_w_mb(val, mem_base + path_reg->cfg1_addr); + + if (path_cfg->crop_enable) { + val = (((path_cfg->end_pixel & cmn_reg->crop_pix_start_mask) << + cmn_reg->crop_shift_val) | + (path_cfg->start_pixel & cmn_reg->crop_pix_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->hcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + + val = (((path_cfg->end_line & cmn_reg->crop_line_start_mask) << + csid_reg->cmn_reg->crop_shift_val) | + (path_cfg->start_line & cmn_reg->crop_line_end_mask)); + cam_io_w_mb(val, mem_base + path_reg->vcrop_addr); + CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", + csid_hw->hw_intf->hw_idx, val); + } + + /* set frame drop pattern to 0 and period to 1 */ + cam_io_w_mb(1, mem_base + path_reg->frm_drop_period_addr); + cam_io_w_mb(0, mem_base + path_reg->frm_drop_pattern_addr); + /* set irq sub sample pattern to 1 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->irq_subsample_period_addr); + cam_io_w_mb(1, mem_base + path_reg->irq_subsample_pattern_addr); + /* set pxl drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->pix_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->pix_drop_period_addr); + /* set line drop pattern to 0 and period to 1 */ + cam_io_w_mb(0, mem_base + path_reg->line_drop_pattern_addr); + cam_io_w_mb(1, mem_base + path_reg->line_drop_period_addr); + + /* Enable the Pxl path */ + val = cam_io_r_mb(mem_base + path_reg->cfg0_addr); + val |= (1 << cmn_reg->path_en_shift_val); + cam_io_w_mb(val, mem_base + path_reg->cfg0_addr); + + if (path_reg->overflow_ctrl_en) { + val = path_reg->overflow_ctrl_en | + path_reg->overflow_ctrl_mode_val; + cam_io_w_mb(val, mem_base + path_reg->err_recovery_cfg0_addr); + } + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { + val = cam_io_r_mb(mem_base + + path_reg->format_measure_cfg0_addr); + val |= csid_reg->cmn_reg->measure_en_hbi_vbi_cnt_mask; + cam_io_w_mb(val, + mem_base + path_reg->format_measure_cfg0_addr); + } + + cam_io_w_mb(val, mem_base + + csid_reg->csi2_reg->capture_ctrl_addr); + CAM_DBG(CAM_ISP, "rx capture control value 0x%x", val); + + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; + + return rc; +} + +static int cam_ife_csid_ver2_start_rdi_path( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_rdi_reg_info *path_reg; + void __iomem *mem_base; + uint32_t val = 0; + uint32_t irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; + uint32_t top_irq_mask = 0, irq_idx = 0, rt_irq_idx; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + + rc = cam_ife_csid_ver2_init_config_rdi_path( + csid_hw, res); + + if (rc) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return rc; + } + + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || + res->res_id > CAM_IFE_PIX_PATH_RES_RDI_4) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + path_reg = csid_reg->rdi_reg[res->res_id]; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + /* Resume at frame boundary */ + cam_io_w_mb(path_reg->resume_frame_boundary, + mem_base + path_reg->ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID:%d Rdi res: %d", + csid_hw->hw_intf->hw_idx, res->res_id); + + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + /*Program the camif part */ + val = (path_cfg->camif_data.pix_pattern << + path_reg->pix_pattern_shift_val) | + (path_cfg->camif_data.stripe_loc << + path_reg->stripe_loc_shift_val); + + cam_io_w_mb(val, mem_base + path_reg->camif_frame_cfg_addr); + cam_io_w_mb(path_cfg->camif_data.epoch0, + mem_base + path_reg->epoch_irq_cfg_addr); + + val = path_reg->fatal_err_mask | path_reg->non_fatal_err_mask | + csid_hw->debug_info.path_mask; + + if (res->rdi_only_ctx) { + path_cfg->handle_camif_irq = true; + val |= path_reg->camif_irq_mask; + } + + res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; + + irq_idx = cam_ife_csid_convert_res_to_irq_reg(res->res_id); + rt_irq_idx = cam_ife_csid_get_rt_irq_idx( + irq_idx, + csid_reg->cmn_reg->num_pix, + csid_reg->cmn_reg->num_ppp, + csid_reg->cmn_reg->num_rdis); + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_RDI_0: + top_irq_mask = IFE_CSID_VER2_TOP_IRQ_STATUS_RDI0; + break; + case CAM_IFE_PIX_PATH_RES_RDI_1: + top_irq_mask = IFE_CSID_VER2_TOP_IRQ_STATUS_RDI1; + break; + case CAM_IFE_PIX_PATH_RES_RDI_2: + top_irq_mask = IFE_CSID_VER2_TOP_IRQ_STATUS_RDI2; + break; + case CAM_IFE_PIX_PATH_RES_RDI_3: + top_irq_mask = IFE_CSID_VER2_TOP_IRQ_STATUS_RDI3; + break; + case CAM_IFE_PIX_PATH_RES_RDI_4: + top_irq_mask = IFE_CSID_VER2_TOP_IRQ_STATUS_RDI4; + break; + } + + irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = top_irq_mask; + irq_mask[irq_idx] = val; + csid_hw->irq_handle[irq_idx] = cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_1, + irq_mask, + csid_hw, + cam_ife_csid_ver2_path_top_half, + cam_ife_csid_ver2_rdi_bottom_half, + csid_hw->tasklet, + &tasklet_bh_api); + + if (csid_hw->irq_handle[irq_idx] < 1) { + CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Irq fail %d", + csid_hw->hw_intf->hw_idx, res->res_id); + rc = -EINVAL; + } + + val = cam_io_r_mb(mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr); + val |= path_reg->rup_aup_mask; + cam_io_w_mb(val, mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr); + CAM_DBG(CAM_ISP, "CSID[%d] rup_cmd_addr %x val %x", + csid_reg->cmn_reg->rup_aup_cmd_addr, val); + + return rc; +} + + +static int cam_ife_csid_ver2_start_ipp_path( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_pxl_reg_info *path_reg = NULL; + uint32_t val = 0; + void __iomem *mem_base; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + uint32_t irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; + uint32_t top_irq_mask = 0, irq_idx = 0; + CAM_IRQ_HANDLER_BOTTOM_HALF bh_func; + + rc = cam_ife_csid_ver2_init_config_pxl_path( + csid_hw, res); + + if (rc) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return rc; + } + + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || + res->res_id != CAM_IFE_PIX_PATH_RES_IPP) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + path_reg = csid_reg->ipp_reg; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d IPP is not supported on HW", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + + val = (path_cfg->camif_data.pix_pattern << + path_reg->pix_pattern_shift_val) | + (path_cfg->camif_data.stripe_loc << + path_reg->stripe_loc_shift_val); + + cam_io_w_mb(val, mem_base + path_reg->camif_frame_cfg_addr); + cam_io_w_mb(path_cfg->camif_data.epoch0, + mem_base + path_reg->epoch_irq_cfg_addr); + + CAM_DBG(CAM_ISP, "csid[%d] frame_cfg 0x%x epoch_cfg 0x%x", + csid_hw->hw_intf->hw_idx, + val, path_cfg->camif_data.epoch0); + + top_irq_mask = IFE_CSID_VER2_TOP_IRQ_STATUS_IPP0; + irq_idx = cam_ife_csid_get_rt_irq_idx( + CAM_IFE_CSID_IRQ_REG_IPP, + csid_reg->cmn_reg->num_pix, + csid_reg->cmn_reg->num_ppp, + csid_reg->cmn_reg->num_rdis); + + bh_func = cam_ife_csid_ver2_ipp_bottom_half; + val = path_reg->fatal_err_mask | path_reg->non_fatal_err_mask | + csid_hw->debug_info.path_mask | path_reg->camif_irq_mask; + + irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = top_irq_mask; + irq_mask[irq_idx] = val; + csid_hw->irq_handle[irq_idx] = + cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_1, + irq_mask, + csid_hw, + cam_ife_csid_ver2_path_top_half, + bh_func, + csid_hw->tasklet, + &tasklet_bh_api); + + if (csid_hw->irq_handle[irq_idx] < 1) { + CAM_ERR(CAM_ISP, "CSID[%d] Subscribe IPP Irq fail", + csid_hw->hw_intf->hw_idx); + rc = -EINVAL; + goto end; + } + + val = path_reg->start_master_sel_val << + path_reg->start_master_sel_shift; + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER) { + /* Set start mode as master */ + val |= path_reg->start_mode_master << + path_reg->start_mode_shift; + } else if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_SLAVE) { + /* Set start mode as slave */ + val |= path_reg->start_mode_slave << + path_reg->start_mode_shift; + } else { + /* Default is internal halt mode */ + val = 0; + } + + /* + * Resume at frame boundary if Master or No Sync. + * Slave will get resume command from Master. + */ + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER || + path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) + val |= path_reg->resume_frame_boundary; + + cam_io_w_mb(val, mem_base + path_reg->ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID:%d Pix res: %d ctrl val: 0x%x", + csid_hw->hw_intf->hw_idx, + res->res_id, val); + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER || + path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) { + val = cam_io_r_mb(mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr); + val |= path_reg->rup_aup_mask; + cam_io_w_mb(val, mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr); + } + + res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; +end: + return rc; +} + +static int cam_ife_csid_ver2_start_ppp_path( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + int rc = 0; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_pxl_reg_info *path_reg = NULL; + uint32_t val = 0; + struct cam_ife_csid_ver2_path_cfg *path_cfg; + uint32_t irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; + uint32_t top_irq_mask = 0, irq_idx = 0; + void __iomem *mem_base; + + rc = cam_ife_csid_ver2_init_config_pxl_path( + csid_hw, res); + + if (rc) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return rc; + } + + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW || + res->res_id != CAM_IFE_PIX_PATH_RES_PPP) { + CAM_ERR(CAM_ISP, + "CSID:%d %s path res type:%d res_id:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id, res->res_state); + return -EINVAL; + } + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + path_reg = csid_reg->ppp_reg; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + + if (!path_reg) { + CAM_ERR(CAM_ISP, "CSID:%d PPP is not supported on HW", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv; + + val = (path_cfg->camif_data.pix_pattern << + path_reg->pix_pattern_shift_val) | + (path_cfg->camif_data.stripe_loc << + path_reg->stripe_loc_shift_val); + + cam_io_w_mb(val, mem_base + path_reg->camif_frame_cfg_addr); + cam_io_w_mb(path_cfg->camif_data.epoch0, mem_base + + path_reg->epoch_irq_cfg_addr); + + top_irq_mask = IFE_CSID_VER2_TOP_IRQ_STATUS_PPP0; + irq_idx = cam_ife_csid_get_rt_irq_idx( + CAM_IFE_CSID_IRQ_REG_PPP, + csid_reg->cmn_reg->num_pix, + csid_reg->cmn_reg->num_ppp, + csid_reg->cmn_reg->num_rdis); + + /* for dual case + * set ppp as slave + * if current csid is set as master set + * start_master_sel_val as 3 + */ + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) { + val = 0; + } else { + val = path_reg->start_mode_slave << + path_reg->start_mode_shift; + /* Set halt mode as internal master */ + if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_MASTER) + val |= path_reg->start_master_sel_val << + path_reg->start_master_sel_shift; + } + + /* + * Resume at frame boundary if Master or No Sync. + * Slave will get resume command from Master. + */ + if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_MASTER || + csid_hw->sync_mode == CAM_ISP_HW_SYNC_NONE) + val |= path_reg->resume_frame_boundary; + + cam_io_w_mb(val, mem_base + path_reg->ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID:%d Pix res: %d ctrl val: 0x%x", + csid_hw->hw_intf->hw_idx, res->res_id, val); + + if (path_cfg->sync_mode == CAM_ISP_HW_SYNC_MASTER || + path_cfg->sync_mode == CAM_ISP_HW_SYNC_NONE) { + val = cam_io_r_mb(mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr); + val |= path_reg->rup_aup_mask; + cam_io_w_mb(val, mem_base + csid_reg->cmn_reg->rup_aup_cmd_addr); + } + + val = path_reg->fatal_err_mask | path_reg->non_fatal_err_mask | + csid_hw->debug_info.path_mask | path_reg->camif_irq_mask; + + res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; + + irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = top_irq_mask; + irq_mask[irq_idx] = val; + csid_hw->irq_handle[irq_idx] = + cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_1, + irq_mask, + csid_hw, + cam_ife_csid_ver2_path_top_half, + cam_ife_csid_ver2_ppp_bottom_half, + csid_hw->tasklet, + &tasklet_bh_api); + + if (csid_hw->irq_handle[irq_idx] < 1) { + CAM_ERR(CAM_ISP, "CSID[%d] Subscribe PPP Irq fail", + csid_hw->hw_intf->hw_idx); + rc = -EINVAL; + } + + return rc; +} + +static int cam_ife_csid_ver2_rx_capture_config( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + uint32_t vc, dt, i; + uint32_t val = 0; + + for (i = 0; i < CAM_IFE_CSID_CID_MAX; i++) + if (csid_hw->cid_data[i].cid_cnt) + break; + + if (i == CAM_IFE_CSID_CID_MAX) { + CAM_WARN(CAM_ISP, "CSID[%d] no valid cid", + csid_hw->hw_intf->hw_idx); + return 0; + } + + vc = csid_hw->cid_data[i].vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].vc; + dt = csid_hw->cid_data[i].vc_dt[CAM_IFE_CSID_MULTI_VC_DT_GRP_0].dt; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) + val = ((1 << + csid_reg->csi2_reg->capture_short_pkt_en_shift) | + (vc << + csid_reg->csi2_reg->capture_short_pkt_vc_shift)); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) + val |= ((1 << + csid_reg->csi2_reg->capture_long_pkt_en_shift) | + (dt << + csid_reg->csi2_reg->capture_long_pkt_dt_shift) | + (vc << + csid_reg->csi2_reg->capture_long_pkt_vc_shift)); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) + val |= ((1 << + csid_reg->csi2_reg->capture_cphy_pkt_en_shift) | + (dt << + csid_reg->csi2_reg->capture_cphy_pkt_dt_shift) | + (vc << + csid_reg->csi2_reg->capture_cphy_pkt_vc_shift)); + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->csi2_reg->capture_ctrl_addr); + + CAM_DBG(CAM_ISP, "CSID[%d] rx capture_ctrl: 0x%x", + csid_hw->hw_intf->hw_idx, val); + + return 0; +} + +static int cam_ife_csid_ver2_enable_csi2(struct cam_ife_csid_ver2_hw *csid_hw) +{ + int rc = 0; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + uint32_t val = 0; + void __iomem *mem_base; + struct cam_ife_csid_rx_cfg *rx_cfg; + int vc_full_width; + uint32_t irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; + + if (csid_hw->flags.rx_enabled) + return 0; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + csi2_reg = csid_reg->csi2_reg; + soc_info = &csid_hw->hw_info->soc_info; + rx_cfg = &csid_hw->rx_cfg; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + + /*Configure Rx cfg0 */ + val |= ((rx_cfg->lane_cfg << csi2_reg->lane_cfg_shift) | + ((rx_cfg->lane_num - 1) << csi2_reg->lane_num_shift) | + (rx_cfg->lane_type << csi2_reg->phy_type_shift)); + + if (rx_cfg->tpg_mux_sel) { + val |= ((rx_cfg->tpg_num_sel << csi2_reg->tpg_num_sel_shift) | + (rx_cfg->tpg_mux_sel << csi2_reg->tpg_mux_en_shift)); + } else { + val |= rx_cfg->phy_sel << csi2_reg->phy_num_shift; + } + + cam_io_w_mb(val, mem_base + csi2_reg->cfg0_addr); + + CAM_DBG(CAM_ISP, "CSID[%d] rx_cfg0: 0x%x", val); + + val = 0; + /*Configure Rx cfg1*/ + val = 1 << csi2_reg->misr_enable_shift_val; + val |= 1 << csi2_reg->ecc_correction_shift_en; + + vc_full_width = cam_ife_csid_is_vc_full_width(csid_hw->cid_data); + + if (vc_full_width == 1) { + val |= 1 << csi2_reg->vc_mode_shift_val; + } else if (vc_full_width < 0) { + CAM_ERR(CAM_ISP, "Error VC DT"); + return -EINVAL; + } + + cam_io_w_mb(val, mem_base + csi2_reg->cfg1_addr); + CAM_DBG(CAM_ISP, "CSID[%d] rx_cfg1: 0x%x", val); + + val = 0; + + irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = IFE_CSID_VER2_TOP_IRQ_STATUS_RX0; + + if (csid_hw->debug_info.rx_mask) { + irq_mask[CAM_IFE_CSID_IRQ_REG_RX] = val | csid_hw->debug_info.rx_mask; + csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX] = + cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_4, + irq_mask, + csid_hw, + cam_ife_csid_ver2_rx_top_half, + NULL, + NULL, + NULL); + } + + if (csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX] < 1) { + CAM_ERR(CAM_ISP, "CSID[%d] RX debug irq register fail", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + val = csi2_reg->fatal_err_mask | csi2_reg->part_fatal_err_mask | + csi2_reg->non_fatal_err_mask; + + /*EPD supported sensors do not send EOT, error will be generated + * if this irq is enabled + */ + if (csid_hw->flags.epd_supported) + val = val & ~IFE_CSID_VER2_RX_CPHY_EOT_RECEPTION; + + irq_mask[CAM_IFE_CSID_IRQ_REG_RX] = val; + + csid_hw->err_irq_handle[CAM_IFE_CSID_IRQ_REG_RX] = + cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_0, + irq_mask, + csid_hw, + cam_ife_csid_ver2_rx_err_top_half, + cam_ife_csid_ver2_rx_err_bottom_half, + csid_hw->tasklet, + &tasklet_bh_api); + + if (csid_hw->err_irq_handle[CAM_IFE_CSID_IRQ_REG_RX] < 1) { + CAM_ERR(CAM_ISP, "CSID[%d] RX err irq register fail", + csid_hw->hw_intf->hw_idx); + rc = -EINVAL; + goto err; + } + + csid_hw->flags.rx_enabled = true; + + cam_ife_csid_ver2_rx_capture_config(csid_hw); + + return rc; +err: + if (csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX]) { + rc = cam_irq_controller_unsubscribe_irq( + csid_hw->csid_irq_controller, + csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX]); + csid_hw->irq_handle[CAM_IFE_CSID_IRQ_REG_RX] = 0; + } + return rc; +} + + +static int cam_ife_csid_ver2_program_top( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + const struct cam_ife_csid_ver2_top_reg_info *top_reg; + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t val; + struct cam_hw_soc_info *soc_info; + int input_core_sel; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + if (!csid_reg->need_top_cfg) { + CAM_DBG(CAM_ISP, "CSID %d top not supported", + csid_hw->hw_intf->hw_idx); + return 0; + } + + top_reg = csid_reg->top_reg; + soc_info = &csid_hw->hw_info->soc_info; + + /* Porgram top parameters */ + input_core_sel = csid_reg->input_core_sel[csid_hw->hw_intf->hw_idx] + [csid_hw->top_cfg.input_core_type]; + + CAM_DBG(CAM_ISP, "CSID[%d] input_core_sel %d", + csid_hw->hw_intf->hw_idx, input_core_sel); + + if (input_core_sel == -1) { + CAM_ERR(CAM_ISP, "csid[%d] invalid top input_core_type %u", + csid_hw->hw_intf->hw_idx, + csid_hw->top_cfg.input_core_type); + return -EINVAL; + } + + val = (uint32_t)input_core_sel << top_reg->input_core_type_shift_val; + val |= csid_hw->top_cfg.offline_sfe_en << + top_reg->sfe_offline_en_shift_val; + val |= csid_hw->top_cfg.out_ife_en << + top_reg->out_ife_en_shift_val; + + cam_io_w_mb(val, + soc_info->reg_map[CAM_IFE_CSID_TOP_MEM_BASE_ID].mem_base + + top_reg->io_path_cfg0_addr[csid_hw->hw_intf->hw_idx]); + + /*Program dual csid regs */ + + if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_NONE) + return 0; + + val = csid_hw->top_cfg.dual_sync_core_sel << + top_reg->dual_sync_sel_shift_val; + val |= csid_hw->top_cfg.dual_en << + top_reg->dual_en_shift_val; + val |= csid_hw->top_cfg.master_slave_sel << + top_reg->master_slave_sel_shift_val; + + cam_io_w_mb(val, + soc_info->reg_map[CAM_IFE_CSID_TOP_MEM_BASE_ID].mem_base + + top_reg->dual_csid_cfg0_addr[csid_hw->hw_intf->hw_idx]); + + return 0; +} + +static int cam_ife_csid_ver2_enable_core(struct cam_ife_csid_ver2_hw *csid_hw) +{ + int rc = 0; + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t clk_lvl; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + /* overflow check before increment */ + if (csid_hw->hw_info->open_count == UINT_MAX) { + CAM_ERR(CAM_ISP, "CSID:%d Open count reached max", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + /* Increment ref Count */ + csid_hw->hw_info->open_count++; + + if (csid_hw->hw_info->open_count > 1) { + CAM_DBG(CAM_ISP, "CSID[%d] hw has already been enabled", + csid_hw->hw_intf->hw_idx); + return rc; + } + + rc = cam_soc_util_get_clk_level(soc_info, csid_hw->clk_rate, + soc_info->src_clk_idx, &clk_lvl); + if (rc) { + CAM_ERR(CAM_ISP, + "CSID[%d] get clk level fail rate %u", + csid_hw->clk_rate); + } + + CAM_DBG(CAM_ISP, "CSID[%d] clock lvl %u rate %u", + csid_hw->hw_intf->hw_idx, + clk_lvl, csid_hw->clk_rate); + + rc = cam_ife_csid_enable_soc_resources(soc_info, clk_lvl); + + if (rc) { + CAM_ERR(CAM_ISP, + "CSID[%d] Enable soc failed", + csid_hw->hw_intf->hw_idx); + goto err; + } + + cam_ife_csid_ver2_program_top(csid_hw); + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP; + + return rc; + +err: + CAM_ERR(CAM_ISP, "CSID[%d] init hw fail rc %d", + csid_hw->hw_intf->hw_idx, rc); + csid_hw->hw_info->open_count--; + return rc; +} + +static int cam_ife_csid_ver2_enable_hw( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_ver2_reg_info *csid_reg = NULL; + uint32_t val; + int i; + void __iomem *mem_base; + uint32_t buf_done_irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0}; + + if (csid_hw->flags.device_enabled) { + CAM_DBG(CAM_ISP, "CSID[%d] hw has already been enabled", + csid_hw->hw_intf->hw_idx); + return 0; + } + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + cam_ife_csid_ver2_enable_csi2(csid_hw); + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + + /* Clear IRQs */ + cam_io_w_mb(1, mem_base + csid_reg->cmn_reg->top_irq_clear_addr); + + cam_io_w_mb(csid_reg->csi2_reg->irq_mask_all, + mem_base + csid_reg->csi2_reg->irq_clear_addr); + + if (csid_reg->cmn_reg->num_pix) + cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all, + mem_base + csid_reg->ipp_reg->irq_clear_addr); + + if (csid_reg->cmn_reg->num_ppp) + cam_io_w_mb(csid_reg->cmn_reg->ppp_irq_mask_all, + mem_base + csid_reg->ppp_reg->irq_clear_addr); + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) + cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, + mem_base + csid_reg->rdi_reg[i]->irq_clear_addr); + + cam_io_w_mb(1, mem_base + csid_reg->cmn_reg->irq_cmd_addr); + + /* Read hw version */ + val = cam_io_r_mb(mem_base + csid_reg->cmn_reg->hw_version_addr); + + buf_done_irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = + IFE_CSID_VER2_TOP_IRQ_STATUS_BUF_DONE; + csid_hw->buf_done_irq_handle = cam_irq_controller_subscribe_irq( + csid_hw->csid_irq_controller, + CAM_IRQ_PRIORITY_4, + buf_done_irq_mask, + csid_hw, + cam_ife_csid_ver2_handle_buf_done_irq, + NULL, + NULL, + NULL); + + if (csid_hw->buf_done_irq_handle < 1) { + CAM_ERR(CAM_ISP, "csid[%d] buf done irq subscribe fail", + csid_hw->hw_intf->hw_idx); + return -EINVAL; + } + + csid_hw->flags.device_enabled = true; + CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x", + csid_hw->hw_intf->hw_idx, val); + return 0; +} + +int cam_ife_csid_ver2_init_hw(void *hw_priv, + void *init_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_hw_info *hw_info; + int rc = 0; + struct cam_isp_resource_node *res; + + if (!hw_priv || !init_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + + mutex_lock(&csid_hw->hw_info->hw_mutex); + + rc = cam_ife_csid_ver2_enable_core(csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] init hw fail", + csid_hw->hw_intf->hw_idx); + goto end; + } + res = (struct cam_isp_resource_node *)init_args; + + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; + + CAM_DBG(CAM_ISP, "CSID[%d] init hw", + csid_hw->hw_intf->hw_idx); +end: + mutex_unlock(&csid_hw->hw_info->hw_mutex); + return rc; +} + + +static int cam_ife_csid_ver2_disable_core( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + const struct cam_ife_csid_ver2_reg_info *csid_reg; + struct cam_hw_soc_info *soc_info; + int rc = 0; + unsigned long flags; + + /* Check for refcount */ + if (!csid_hw->hw_info->open_count) { + CAM_WARN(CAM_ISP, "Unbalanced disable_hw"); + return rc; + } + + /* Decrement ref Count */ + csid_hw->hw_info->open_count--; + + if (csid_hw->hw_info->open_count) + return rc; + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + cam_ife_csid_ver2_disable_csi2(csid_hw); + + /* Disable the top IRQ interrupt */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + csid_reg->cmn_reg->top_irq_mask_addr); + + rc = cam_ife_csid_disable_soc_resources(soc_info); + if (rc) + CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed", + csid_hw->hw_intf->hw_idx); + + spin_lock_irqsave(&csid_hw->lock_state, flags); + csid_hw->flags.device_enabled = false; + spin_unlock_irqrestore(&csid_hw->lock_state, flags); + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; + csid_hw->counters.error_irq_count = 0; + + return rc; +} + +int cam_ife_csid_ver2_deinit_hw(void *hw_priv, + void *deinit_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_isp_resource_node *res; + struct cam_hw_info *hw_info; + int rc = 0; + + if (!hw_priv || !deinit_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "CSID:Invalid arguments"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + res = (struct cam_isp_resource_node *)deinit_args; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d", + csid_hw->hw_intf->hw_idx, + res->res_type); + return -EINVAL; + } + + if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { + CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state", + csid_hw->hw_intf->hw_idx, + res->res_id); + return -EINVAL; + } + + mutex_lock(&csid_hw->hw_info->hw_mutex); + if (csid_hw->buf_done_irq_handle) { + rc = cam_irq_controller_unsubscribe_irq( + csid_hw->csid_irq_controller, + csid_hw->buf_done_irq_handle); + csid_hw->buf_done_irq_handle = 0; + } + + if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW) + goto disable_hw; + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + case CAM_IFE_PIX_PATH_RES_PPP: + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver2_disable_path(csid_hw, res); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + break; + } + +disable_hw: + res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + cam_ife_csid_ver2_disable_core(csid_hw); + mutex_unlock(&csid_hw->hw_info->hw_mutex); + CAM_DBG(CAM_ISP, "De-Init CSID %d Path: %d", + csid_hw->hw_intf->hw_idx, res->res_id); + + return rc; +} + +int cam_ife_csid_ver2_start(void *hw_priv, void *start_args, + uint32_t arg_size) +{ + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_isp_resource_node *res; + struct cam_hw_info *hw_info; + int rc = 0; + + if (!hw_priv || !start_args) { + CAM_ERR(CAM_ISP, "CSID Invalid params"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + res = (struct cam_isp_resource_node *)start_args; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + rc = -EINVAL; + goto end; + } + + if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH && + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + rc = -EINVAL; + goto end; + } + + csid_hw->flags.sof_irq_triggered = false; + csid_hw->counters.irq_debug_cnt = 0; + + CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d", + csid_hw->hw_intf->hw_idx, res->res_type, res->res_id); + + mutex_lock(&csid_hw->hw_info->hw_mutex); + rc = cam_ife_csid_ver2_enable_hw(csid_hw); + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + rc = cam_ife_csid_ver2_start_ipp_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_PPP: + rc = cam_ife_csid_ver2_start_ppp_path(csid_hw, res); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rc = cam_ife_csid_ver2_start_rdi_path(csid_hw, res); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, res->res_type); + break; + } + + mutex_unlock(&csid_hw->hw_info->hw_mutex); + +end: + return rc; +} + +int cam_ife_csid_ver2_stop(void *hw_priv, + void *stop_args, uint32_t arg_size) +{ + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + struct cam_isp_resource_node *res; + struct cam_hw_info *hw_info; + int rc = 0; + uint32_t i; + struct cam_csid_hw_stop_args *csid_stop; + + if (!hw_priv || !stop_args || + (arg_size != sizeof(struct cam_csid_hw_stop_args))) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + csid_stop = (struct cam_csid_hw_stop_args *) stop_args; + + if (!csid_stop->num_res) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + + CAM_DBG(CAM_ISP, "CSID:%d num_res %d", + csid_hw->hw_intf->hw_idx, + csid_stop->num_res); + + mutex_lock(&csid_hw->hw_info->hw_mutex); + for (i = 0; i < csid_stop->num_res; i++) { + + res = csid_stop->node_res[i]; + rc = cam_ife_csid_ver2_disable_path(csid_hw, res); + res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW; + CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id); + } + mutex_unlock(&csid_hw->hw_info->hw_mutex); + + return rc; +} + +int cam_ife_csid_ver2_read(void *hw_priv, + void *read_args, uint32_t arg_size) +{ + CAM_ERR(CAM_ISP, "CSID: un supported"); + + return -EINVAL; +} + +int cam_ife_csid_ver2_write(void *hw_priv, + void *write_args, uint32_t arg_size) +{ + CAM_ERR(CAM_ISP, "CSID: un supported"); + return -EINVAL; +} + +static int cam_ife_csid_ver2_top_cfg( + struct cam_ife_csid_ver2_hw *csid_hw, void *cmd_args) +{ + struct cam_ife_csid_top_config_args *top_args; + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t hw_idx; + int rc = 0; + + if ((!csid_hw) || (!cmd_args)) + return -EINVAL; + + top_args = (struct cam_ife_csid_top_config_args *)cmd_args; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + hw_idx = csid_hw->hw_intf->hw_idx; + csid_hw->top_cfg.out_ife_en = true; + + /* config out_core parameter*/ + + switch (top_args->input_core_type) { + case CAM_IFE_CSID_INPUT_CORE_NONE: + csid_hw->top_cfg.input_core_type = + CAM_IFE_CSID_INPUT_CORE_SEL_NONE; + csid_hw->top_cfg.out_ife_en = false; + break; + + case CAM_IFE_CSID_INPUT_CORE_IFE: + csid_hw->top_cfg.input_core_type = + CAM_IFE_CSID_INPUT_CORE_SEL_INTERNAL; + break; + + case CAM_IFE_CSID_INPUT_CORE_SFE: + csid_hw->top_cfg.out_ife_en = false; + case CAM_IFE_CSID_INPUT_CORE_SFE_IFE: + + if (top_args->core_idx == 0) { + csid_hw->top_cfg.input_core_type = + CAM_IFE_CSID_INPUT_CORE_SEL_SFE_0; + } else if (top_args->core_idx == 1) { + csid_hw->top_cfg.input_core_type = + CAM_IFE_CSID_INPUT_CORE_SEL_SFE_1; + } else { + rc = -EINVAL; + CAM_ERR(CAM_ISP, + "CSID: %d Invalid SFE node %d", + hw_idx, top_args->core_idx); + } + + break; + + case CAM_IFE_CSID_INPUT_CORE_CUST_IFE: + + if (!(csid_reg->csid_cust_node_map[hw_idx] & + BIT(top_args->core_idx))) { + CAM_ERR(CAM_ISP, + "CSID: %d not supported for cust node %d", + hw_idx, top_args->core_idx); + rc = -EINVAL; + break; + } + + if (top_args->core_idx == 0) { + csid_hw->top_cfg.input_core_type = + CAM_IFE_CSID_INPUT_CORE_SEL_CUST_NODE_0; + } else if (top_args->core_idx == 1) { + csid_hw->top_cfg.input_core_type = + CAM_IFE_CSID_INPUT_CORE_SEL_CUST_NODE_1; + } else { + rc = -EINVAL; + CAM_ERR(CAM_ISP, + "CSID: %d Invalid Cust node %d", + hw_idx, top_args->core_idx); + } + break; + default: + break; + } + + csid_hw->top_cfg.offline_sfe_en = top_args->is_sfe_offline; + CAM_DBG(CAM_ISP, + "CSID[%d] input_core_type:%d ife_out:%d sfe_offline:%d", + hw_idx, csid_hw->top_cfg.input_core_type, + csid_hw->top_cfg.out_ife_en, + csid_hw->top_cfg.offline_sfe_en); + CAM_DBG(CAM_ISP, + "CSID[%d] Top config received: input_core_type%d core_idx:%d", + hw_idx, top_args->input_core_type, top_args->core_idx); + + /*config dual sync params */ + + if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_NONE) + return rc; + else if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_MASTER) + csid_hw->top_cfg.master_slave_sel = + csid_reg->top_reg->master_sel_val; + else + csid_hw->top_cfg.master_slave_sel = + csid_reg->top_reg->slave_sel_val; + + csid_hw->top_cfg.dual_en = true; + csid_hw->top_cfg.dual_sync_core_sel = csid_hw->dual_core_idx + 1; + + return rc; +} + +static int cam_ife_csid_ver2_reg_update( + struct cam_ife_csid_ver2_hw *csid_hw, + void *cmd_args, uint32_t arg_size) +{ + const struct cam_ife_csid_ver2_rdi_reg_info *rdi_reg; + struct cam_ife_csid_reg_update_args *rup_args = cmd_args; + struct cam_cdm_utils_ops *cdm_util_ops; + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t size, i; + uint32_t reg_val_pair[2]; + uint32_t rup_aup_mask = 0; + int rc = 0; + + if (arg_size != sizeof(struct cam_ife_csid_reg_update_args)) { + CAM_ERR(CAM_ISP, "Invalid arg size: %d expected:%ld", + arg_size, sizeof(struct cam_ife_csid_reg_update_args)); + return -EINVAL; + } + + if (!rup_args) { + CAM_ERR(CAM_ISP, "Invalid args"); + return -EINVAL; + } + + if (!rup_args->num_res || + rup_args->num_res > CAM_IFE_PIX_PATH_RES_MAX) { + CAM_ERR(CAM_ISP, "Invalid num_res %u", + rup_args->num_res); + return -EINVAL; + } + + cdm_util_ops = (struct cam_cdm_utils_ops *)rup_args->res[0]->cdm_ops; + + if (!cdm_util_ops) { + CAM_ERR(CAM_ISP, "Invalid CDM ops"); + return -EINVAL; + } + + size = cdm_util_ops->cdm_required_size_reg_random(1); + /* since cdm returns dwords, we need to convert it into bytes */ + if ((size * 4) > rup_args->cmd.size) { + CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d", + rup_args->cmd.size, (size*4)); + return -EINVAL; + } + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + for (i = 0; i < rup_args->num_res; i++) { + switch (rup_args->res[i]->res_id) { + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + rdi_reg = csid_reg->rdi_reg[rup_args->res[i]->res_id]; + if (!rdi_reg) { + rc = -EINVAL; + goto err; + } + rup_aup_mask |= rdi_reg->rup_aup_mask; + break; + case CAM_IFE_PIX_PATH_RES_IPP: + if (!csid_reg->ipp_reg) { + rc = -EINVAL; + goto err; + } + rup_aup_mask |= csid_reg->ipp_reg->rup_aup_mask; + break; + case CAM_IFE_PIX_PATH_RES_PPP: + if (!csid_reg->ppp_reg) { + rc = -EINVAL; + goto err; + } + rup_aup_mask |= csid_reg->ppp_reg->rup_aup_mask; + break; + + default: + rc = -EINVAL; + goto err; + } + } + + reg_val_pair[0] = csid_reg->cmn_reg->rup_aup_cmd_addr; + reg_val_pair[1] = rup_aup_mask; + + if (rup_args->is_mup_update) + reg_val_pair[1] |= 1 << csid_reg->cmn_reg->mup_shift_val; + + CAM_DBG(CAM_ISP, "CSID:%d reg_update_cmd 0x%X offset 0x%X", + csid_hw->hw_intf->hw_idx, + reg_val_pair[1], reg_val_pair[0]); + + cdm_util_ops->cdm_write_regrandom(rup_args->cmd.cmd_buf_addr, + 1, reg_val_pair); + + rup_args->cmd.used_bytes = size * 4; + + return rc; +err: + CAM_ERR(CAM_ISP, "CSID[%d] wrong res_id %d", + csid_hw->hw_intf->hw_idx, + rup_args->res[i]->res_id); + return rc; +} + +static int cam_ife_csid_ver2_get_time_stamp( + struct cam_ife_csid_ver2_hw *csid_hw, void *cmd_args) +{ + struct cam_isp_resource_node *res = NULL; + uint64_t time_lo, time_hi; + struct cam_hw_soc_info *soc_info; + struct cam_csid_get_time_stamp_args *timestamp_args; + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint64_t time_delta; + struct timespec64 ts; + uint32_t curr_0_sof_addr, curr_1_sof_addr; + + timestamp_args = (struct cam_csid_get_time_stamp_args *)cmd_args; + res = timestamp_args->node_res; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH || + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + return -EINVAL; + } + + if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d", + csid_hw->hw_intf->hw_idx, + csid_hw->hw_info->hw_state); + return -EINVAL; + } + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + curr_0_sof_addr = csid_reg->ipp_reg->timestamp_curr0_sof_addr; + curr_1_sof_addr = csid_reg->ipp_reg->timestamp_curr1_sof_addr; + break; + case CAM_IFE_PIX_PATH_RES_PPP: + curr_0_sof_addr = csid_reg->ppp_reg->timestamp_curr0_sof_addr; + curr_1_sof_addr = csid_reg->ppp_reg->timestamp_curr1_sof_addr; + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + curr_0_sof_addr = + csid_reg->rdi_reg + [res->res_id]->timestamp_curr0_sof_addr; + curr_1_sof_addr = + csid_reg->rdi_reg + [res->res_id]->timestamp_curr1_sof_addr; + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d invalid res %d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + time_hi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + curr_1_sof_addr); + time_lo = cam_io_r_mb(soc_info->reg_map[0].mem_base + + curr_0_sof_addr); + timestamp_args->time_stamp_val = (time_hi << 32) | time_lo; + + timestamp_args->time_stamp_val = mul_u64_u32_div( + timestamp_args->time_stamp_val, + CAM_IFE_CSID_QTIMER_MUL_FACTOR, + CAM_IFE_CSID_QTIMER_DIV_FACTOR); + + time_delta = timestamp_args->time_stamp_val - + csid_hw->timestamp.prev_sof_ts; + + if (!csid_hw->timestamp.prev_boot_ts) { + ktime_get_boottime_ts64(&ts); + timestamp_args->boot_timestamp = + (uint64_t)((ts.tv_sec * 1000000000) + + ts.tv_nsec); + } else { + timestamp_args->boot_timestamp = + csid_hw->timestamp.prev_boot_ts + time_delta; + } + + CAM_DBG(CAM_ISP, "timestamp:%lld", + timestamp_args->boot_timestamp); + csid_hw->timestamp.prev_sof_ts = timestamp_args->time_stamp_val; + csid_hw->timestamp.prev_boot_ts = timestamp_args->boot_timestamp; + + return 0; +} + +static int cam_ife_csid_ver2_print_hbi_vbi( + struct cam_ife_csid_ver2_hw *csid_hw, + struct cam_isp_resource_node *res) +{ + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t hbi, vbi; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH || + res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d", + csid_hw->hw_intf->hw_idx, res->res_type, + res->res_id); + return -EINVAL; + } + + if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d", + csid_hw->hw_intf->hw_idx, + csid_hw->hw_info->hw_state); + return -EINVAL; + } + + switch (res->res_id) { + case CAM_IFE_PIX_PATH_RES_IPP: + hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->format_measure1_addr); + vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->format_measure2_addr); + break; + case CAM_IFE_PIX_PATH_RES_PPP: + hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->format_measure1_addr); + vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->format_measure2_addr); + break; + case CAM_IFE_PIX_PATH_RES_RDI_0: + case CAM_IFE_PIX_PATH_RES_RDI_1: + case CAM_IFE_PIX_PATH_RES_RDI_2: + case CAM_IFE_PIX_PATH_RES_RDI_3: + case CAM_IFE_PIX_PATH_RES_RDI_4: + hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[res->res_id]->format_measure1_addr); + vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[res->res_id]->format_measure2_addr); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d invalid res %d", + csid_hw->hw_intf->hw_idx, res->res_id); + return -EINVAL; + } + + CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID: %d res: %d hbi %u vbi %u", + res->res_id, hbi, vbi); + + return 0; +} + +static int cam_ife_csid_ver2_set_csid_clock( + struct cam_ife_csid_ver2_hw *csid_hw, + void *cmd_args) +{ + struct cam_ife_csid_clock_update_args *clk_update = NULL; + + if (!csid_hw) + return -EINVAL; + + clk_update = + (struct cam_ife_csid_clock_update_args *)cmd_args; + + csid_hw->clk_rate = clk_update->clk_rate; + CAM_INFO(CAM_ISP, "CSID clock rate %llu", csid_hw->clk_rate); + + return 0; +} + +static int cam_ife_csid_ver2_sof_irq_debug( + struct cam_ife_csid_ver2_hw *csid_hw, + void *cmd_args) +{ + int i = 0; + uint32_t val = 0; + bool sof_irq_enable = false; + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_ver2_reg_info *csid_reg; + + if (*((uint32_t *)cmd_args) == 1) + sof_irq_enable = true; + + if (csid_hw->hw_info->hw_state == + CAM_HW_STATE_POWER_DOWN) { + CAM_WARN(CAM_ISP, + "CSID powered down unable to %s sof irq", + (sof_irq_enable) ? "enable" : "disable"); + return 0; + } + + soc_info = &csid_hw->hw_info->soc_info; + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + for (i = 0; i < csid_reg->cmn_reg->num_pix; i++) { + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_mask_addr); + + if (!val) + continue; + + if (sof_irq_enable) + val |= IFE_CSID_VER2_PATH_INFO_INPUT_SOF; + else + val &= ~IFE_CSID_VER2_PATH_INFO_INPUT_SOF; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->irq_mask_addr); + } + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->irq_mask_addr); + if (!val) + continue; + + if (sof_irq_enable) + val |= IFE_CSID_VER2_PATH_INFO_INPUT_SOF; + else + val &= ~IFE_CSID_VER2_PATH_INFO_INPUT_SOF; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->irq_mask_addr); + } + + if (sof_irq_enable) { + csid_hw->debug_info.path_mask |= + IFE_CSID_VER2_PATH_INFO_INPUT_SOF; + csid_hw->debug_info.debug_val |= + CAM_IFE_CSID_DEBUG_ENABLE_SOF_IRQ; + csid_hw->flags.sof_irq_triggered = true; + } else { + csid_hw->debug_info.path_mask &= + ~IFE_CSID_VER2_PATH_INFO_INPUT_SOF; + csid_hw->debug_info.debug_val &= + ~CAM_IFE_CSID_DEBUG_ENABLE_SOF_IRQ; + csid_hw->flags.sof_irq_triggered = false; + } + + CAM_INFO(CAM_ISP, "SOF freeze: CSID SOF irq %s", + (sof_irq_enable) ? "enabled" : "disabled"); + + return 0; +} +static int cam_ife_csid_ver2_dual_sync_cfg( + struct cam_ife_csid_ver2_hw *csid_hw, + void *cmd_args) +{ + struct cam_ife_csid_dual_sync_args *dual_sync_args; + + if (!csid_hw || !cmd_args) { + CAM_ERR(CAM_ISP, "Invalid args %pK %pK", + csid_hw, cmd_args); + return -EINVAL; + } + + dual_sync_args = (struct cam_ife_csid_dual_sync_args *)cmd_args; + csid_hw->sync_mode = dual_sync_args->sync_mode; + csid_hw->dual_core_idx = dual_sync_args->dual_core_id; + + return 0; +} + +static int cam_ife_csid_ver2_program_offline_go_cmd( + struct cam_ife_csid_ver2_hw *csid_hw, + void *args) +{ + struct cam_ife_csid_ver2_reg_info *csid_reg; + uint32_t *val; + void __iomem *mem_base; + struct cam_hw_soc_info *soc_info; + + if (!csid_hw || !args) { + CAM_ERR(CAM_ISP, "CSID go cmd invalid args %pK %pK", + csid_hw, args); + return -EINVAL; + } + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + val = (uint32_t *)(args); + + cam_io_w_mb(*val, mem_base + csid_reg->cmn_reg->offline_cmd_addr); + + CAM_DBG(CAM_ISP, "CSID %d go cmd %u", csid_hw->hw_intf->hw_idx, + *val); + + return 0; +} + + +static int cam_ife_csid_ver2_process_cmd(void *hw_priv, + uint32_t cmd_type, void *cmd_args, uint32_t arg_size) +{ + int rc = 0; + struct cam_ife_csid_ver2_hw *csid_hw; + struct cam_hw_info *hw_info; + struct cam_isp_resource_node *res = NULL; + + if (!hw_priv || !cmd_args) { + CAM_ERR(CAM_ISP, "CSID: Invalid arguments"); + return -EINVAL; + } + + hw_info = (struct cam_hw_info *)hw_priv; + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info; + + switch (cmd_type) { + case CAM_IFE_CSID_CMD_GET_TIME_STAMP: + rc = cam_ife_csid_ver2_get_time_stamp(csid_hw, cmd_args); + + if (csid_hw->debug_info.debug_val & + CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO) { + res = ((struct cam_csid_get_time_stamp_args *) + cmd_args)->node_res; + cam_ife_csid_ver2_print_hbi_vbi(csid_hw, res); + } + break; + case CAM_IFE_CSID_SET_CSID_DEBUG: + rc = cam_ife_csid_ver2_set_debug(csid_hw, + *((uint32_t *)cmd_args)); + break; + case CAM_IFE_CSID_SOF_IRQ_DEBUG: + rc = cam_ife_csid_ver2_sof_irq_debug(csid_hw, cmd_args); + break; + case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE: + rc = cam_ife_csid_ver2_set_csid_clock(csid_hw, cmd_args); + break; + case CAM_ISP_HW_CMD_DUMP_HW: + //rc = cam_ife_csid_ver2_dump_hw(csid_hw, cmd_args); + break; + case CAM_IFE_CSID_SET_CONFIG: + rc = cam_ife_csid_set_epd_config(&csid_hw->flags, cmd_args, + csid_hw->hw_intf->hw_idx); + break; + case CAM_IFE_CSID_TOP_CONFIG: + rc = cam_ife_csid_ver2_top_cfg(csid_hw, cmd_args); + break; + case CAM_ISP_HW_CMD_GET_CHANGE_BASE: + rc = cam_ife_csid_get_base(&hw_info->soc_info, + CAM_IFE_CSID_CLC_MEM_BASE_ID, + cmd_args, arg_size); + break; + case CAM_ISP_HW_CMD_GET_REG_UPDATE: + rc = cam_ife_csid_ver2_reg_update(csid_hw, + cmd_args, arg_size); + break; + case CAM_IFE_CSID_SET_DUAL_SYNC_CONFIG: + rc = cam_ife_csid_ver2_dual_sync_cfg(csid_hw, + cmd_args); + break; + case CAM_IFE_CSID_PROGRAM_OFFLINE_CMD: + rc = cam_ife_csid_ver2_program_offline_go_cmd( + csid_hw, cmd_args); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", + csid_hw->hw_intf->hw_idx, cmd_type); + rc = -EINVAL; + break; + } + return rc; + +} + +static irqreturn_t cam_ife_csid_irq(int irq_num, void *data) +{ + struct cam_ife_csid_ver2_hw *csid_hw = data; + + if (!csid_hw) + return IRQ_NONE; + + return cam_irq_controller_handle_irq(irq_num, + csid_hw->csid_irq_controller); +} + +static void cam_ife_csid_ver2_free_res(struct cam_ife_csid_ver2_hw *csid_hw) +{ + + struct cam_isp_resource_node *res; + uint32_t num_paths; + int i; + struct cam_ife_csid_ver2_reg_info *csid_reg; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + num_paths = csid_reg->cmn_reg->num_udis; + + for (i = 0; i < num_paths; i++) { + res = &csid_hw->path_res[CAM_IFE_PIX_PATH_RES_UDI_0 + i]; + kfree(res->res_priv); + res->res_priv = NULL; + } + + num_paths = csid_reg->cmn_reg->num_rdis; + + for (i = 0; i < num_paths; i++) { + res = &csid_hw->path_res[CAM_IFE_PIX_PATH_RES_RDI_0 + i]; + kfree(res->res_priv); + res->res_priv = NULL; + } + + kfree(csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP].res_priv); + csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP].res_priv = NULL; + kfree(csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP].res_priv); + csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP].res_priv = NULL; +} + +static int cam_ife_ver2_hw_alloc_res( + struct cam_isp_resource_node *res, + uint32_t res_type, + struct cam_hw_intf *hw_intf, + uint32_t res_id) + +{ + struct cam_ife_csid_ver2_path_cfg *path_cfg = NULL; + + path_cfg = kzalloc(sizeof(*path_cfg), GFP_KERNEL); + + if (!path_cfg) + return -ENOMEM; + + res->res_id = res_id; + res->res_type = res_type; + res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; + res->hw_intf = hw_intf; + res->res_priv = path_cfg; + + return 0; +} + +static int cam_ife_csid_ver2_hw_init_path_res( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + int rc = 0; + int i; + struct cam_ife_csid_ver2_reg_info *csid_reg; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + /* Initialize the IPP resources */ + if (csid_reg->cmn_reg->num_pix) { + rc = cam_ife_ver2_hw_alloc_res( + &csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP], + CAM_ISP_RESOURCE_PIX_PATH, + csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_IPP); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d IPP res init fail", + csid_hw->hw_intf->hw_idx); + goto free_res; + } + } + + /* Initialize PPP resource */ + if (csid_reg->cmn_reg->num_ppp) { + rc = cam_ife_ver2_hw_alloc_res( + &csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP], + CAM_ISP_RESOURCE_PIX_PATH, + csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_PPP); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d PPP res init fail", + csid_hw->hw_intf->hw_idx); + goto free_res; + } + } + + /* Initialize the RDI resource */ + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + /* res type is from RDI 0 to RDI3 */ + rc = cam_ife_ver2_hw_alloc_res( + &csid_hw->path_res[CAM_IFE_PIX_PATH_RES_RDI_0 + i], + CAM_ISP_RESOURCE_PIX_PATH, + csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_RDI_0 + i); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d RDI[%d] res init fail", + csid_hw->hw_intf->hw_idx, i); + goto free_res; + } + } + + /* Initialize the UDI resource */ + for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) { + /* res type is from UDI0 to UDI3 */ + rc = cam_ife_ver2_hw_alloc_res( + &csid_hw->path_res[CAM_IFE_PIX_PATH_RES_UDI_0 + i], + CAM_ISP_RESOURCE_PIX_PATH, + csid_hw->hw_intf, + CAM_IFE_PIX_PATH_RES_UDI_0 + i); + if (rc) { + CAM_ERR(CAM_ISP, "CSID: %d UDI[%d] res init fail", + csid_hw->hw_intf->hw_idx, i); + goto free_res; + } + } + + return rc; + +free_res: + cam_ife_csid_ver2_free_res(csid_hw); + return rc; +} + +static int cam_ife_csid_hw_init_irq( + struct cam_ife_csid_ver2_hw *csid_hw) +{ + int rc = 0; + int i; + struct cam_hw_soc_info *soc_info; + void __iomem *mem_base; + struct cam_ife_csid_ver2_reg_info *csid_reg; + + csid_reg = (struct cam_ife_csid_ver2_reg_info *) + csid_hw->core_info->csid_reg; + + soc_info = &csid_hw->hw_info->soc_info; + mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base; + + rc = cam_irq_controller_init("csid", + mem_base, csid_reg->irq_reg_info, + &csid_hw->csid_irq_controller, + true); + + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to init CSID irq controller rc = %d", rc); + return rc; + } + + rc = cam_irq_controller_init("csid_buf_done", + mem_base, + csid_reg->buf_done_irq_reg_info, + &csid_hw->buf_done_irq_controller, + true); + + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to init CSID buf_done irq controller rc = %d", + rc); + return rc; + } + + spin_lock_init(&csid_hw->path_payload_lock); + INIT_LIST_HEAD(&csid_hw->path_free_payload_list); + for (i = 0; i < CAM_IFE_CSID_VER2_PAYLOAD_MAX; i++) { + INIT_LIST_HEAD(&csid_hw->path_evt_payload[i].list); + list_add_tail(&csid_hw->path_evt_payload[i].list, + &csid_hw->path_free_payload_list); + } + spin_lock_init(&csid_hw->rx_payload_lock); + INIT_LIST_HEAD(&csid_hw->rx_free_payload_list); + for (i = 0; i < CAM_IFE_CSID_VER2_PAYLOAD_MAX; i++) { + INIT_LIST_HEAD(&csid_hw->rx_evt_payload[i].list); + list_add_tail(&csid_hw->rx_evt_payload[i].list, + &csid_hw->rx_free_payload_list); + } + + return rc; +} + +int cam_ife_csid_hw_ver2_init(struct cam_hw_intf *hw_intf, + struct cam_ife_csid_core_info *core_info, + bool is_custom) +{ + int rc = -EINVAL; + uint32_t i; + struct cam_hw_info *hw_info; + struct cam_ife_csid_ver2_hw *csid_hw = NULL; + + if (!hw_intf || !core_info) { + CAM_ERR(CAM_ISP, "Invalid parameters intf: %pK hw_info: %pK", + hw_intf, core_info); + return rc; + } + + hw_info = (struct cam_hw_info *)hw_intf->hw_priv; + + csid_hw = kzalloc(sizeof(struct cam_ife_csid_ver2_hw), GFP_KERNEL); + + if (!csid_hw) { + CAM_ERR(CAM_ISP, "Csid core %d hw allocation fails", + hw_intf->hw_idx); + return -ENOMEM; + } + + hw_info->core_info = csid_hw; + csid_hw->hw_intf = hw_intf; + csid_hw->hw_info = hw_info; + csid_hw->core_info = core_info; + CAM_DBG(CAM_ISP, "type %d index %d", + hw_intf->hw_type, + hw_intf->hw_idx); + + csid_hw->flags.device_enabled = false; + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; + mutex_init(&csid_hw->hw_info->hw_mutex); + spin_lock_init(&csid_hw->hw_info->hw_lock); + spin_lock_init(&csid_hw->lock_state); + init_completion(&csid_hw->hw_info->hw_complete); + + for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++) + init_completion(&csid_hw->irq_complete[i]); + + rc = cam_ife_csid_init_soc_resources(&csid_hw->hw_info->soc_info, + cam_ife_csid_irq, csid_hw, is_custom); + if (rc < 0) { + CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", + hw_intf->hw_idx); + return rc; + } + + if (cam_cpas_is_feature_supported(CAM_CPAS_QCFA_BINNING_ENABLE, + CAM_CPAS_HW_IDX_ANY, NULL)) + csid_hw->flags.binning_enabled = true; + + csid_hw->hw_intf->hw_ops.get_hw_caps = + cam_ife_csid_ver2_get_hw_caps; + csid_hw->hw_intf->hw_ops.init = cam_ife_csid_ver2_init_hw; + csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_ver2_deinit_hw; + csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_ver2_reset; + csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_ver2_reserve; + csid_hw->hw_intf->hw_ops.release = cam_ife_csid_ver2_release; + csid_hw->hw_intf->hw_ops.start = cam_ife_csid_ver2_start; + csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_ver2_stop; + csid_hw->hw_intf->hw_ops.read = cam_ife_csid_ver2_read; + csid_hw->hw_intf->hw_ops.write = cam_ife_csid_ver2_write; + csid_hw->hw_intf->hw_ops.process_cmd = + cam_ife_csid_ver2_process_cmd; + + rc = cam_ife_csid_hw_init_irq(csid_hw); + + rc = cam_ife_csid_ver2_hw_init_path_res(csid_hw); + + if (rc) { + CAM_ERR(CAM_ISP, "CSID[%d] Probe Init failed", + hw_intf->hw_idx); + return rc; + } + csid_hw->debug_info.debug_val = 0; + csid_hw->counters.error_irq_count = 0; + + return 0; + +} +EXPORT_SYMBOL(cam_ife_csid_hw_ver2_init); + +int cam_ife_csid_hw_ver2_deinit(struct cam_hw_info *hw_priv) +{ + struct cam_ife_csid_ver2_hw *csid_hw; + unsigned long flags; + int rc = -EINVAL; + int i; + + csid_hw = (struct cam_ife_csid_ver2_hw *)hw_priv->core_info; + + if (!csid_hw) { + CAM_ERR(CAM_ISP, "Invalid param"); + return rc; + } + + spin_lock_irqsave(&csid_hw->path_payload_lock, flags); + INIT_LIST_HEAD(&csid_hw->path_free_payload_list); + for (i = 0; i < CAM_IFE_CSID_VER2_PAYLOAD_MAX; i++) + INIT_LIST_HEAD(&csid_hw->path_evt_payload[i].list); + spin_unlock_irqrestore(&csid_hw->path_payload_lock, flags); + + spin_lock_irqsave(&csid_hw->rx_payload_lock, flags); + INIT_LIST_HEAD(&csid_hw->rx_free_payload_list); + for (i = 0; i < CAM_IFE_CSID_VER2_PAYLOAD_MAX; i++) + INIT_LIST_HEAD(&csid_hw->rx_evt_payload[i].list); + spin_unlock_irqrestore(&csid_hw->rx_payload_lock, flags); + + rc = cam_irq_controller_deinit(&csid_hw->csid_irq_controller); + rc = cam_irq_controller_deinit(&csid_hw->buf_done_irq_controller); + + /* release the privdate data memory from resources */ + cam_ife_csid_ver2_free_res(csid_hw); + + cam_ife_csid_deinit_soc_resources(&csid_hw->hw_info->soc_info); + + return 0; +} +EXPORT_SYMBOL(cam_ife_csid_hw_ver2_deinit); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h new file mode 100644 index 0000000000..b06a017504 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h @@ -0,0 +1,651 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_IFE_CSID_HW_VER2_H_ +#define _CAM_IFE_CSID_HW_VER2_H_ + +#include "cam_hw.h" +#include "cam_ife_csid_hw_intf.h" +#include "cam_ife_csid_soc.h" +#include "cam_ife_csid_common.h" + +#define IFE_CSID_VER2_RX_DL0_EOT_CAPTURED BIT(0) +#define IFE_CSID_VER2_RX_DL1_EOT_CAPTURED BIT(1) +#define IFE_CSID_VER2_RX_DL2_EOT_CAPTURED BIT(2) +#define IFE_CSID_VER2_RX_DL3_EOT_CAPTURED BIT(3) +#define IFE_CSID_VER2_RX_DL0_SOT_CAPTURED BIT(4) +#define IFE_CSID_VER2_RX_DL1_SOT_CAPTURED BIT(5) +#define IFE_CSID_VER2_RX_DL2_SOT_CAPTURED BIT(6) +#define IFE_CSID_VER2_RX_DL3_SOT_CAPTURED BIT(7) +#define IFE_CSID_VER2_RX_LONG_PKT_CAPTURED BIT(8) +#define IFE_CSID_VER2_RX_SHORT_PKT_CAPTURED BIT(9) +#define IFE_CSID_VER2_RX_CPHY_PKT_HDR_CAPTURED BIT(10) +#define IFE_CSID_VER2_RX_CPHY_EOT_RECEPTION BIT(11) +#define IFE_CSID_VER2_RX_CPHY_SOT_RECEPTION BIT(12) +#define IFE_CSID_VER2_RX_ERROR_CPHY_PH_CRC BIT(13) +#define IFE_CSID_VER2_RX_WARNING_ECC BIT(14) +#define IFE_CSID_VER2_RX_LANE0_FIFO_OVERFLOW BIT(15) +#define IFE_CSID_VER2_RX_LANE1_FIFO_OVERFLOW BIT(16) +#define IFE_CSID_VER2_RX_LANE2_FIFO_OVERFLOW BIT(17) +#define IFE_CSID_VER2_RX_LANE3_FIFO_OVERFLOW BIT(18) +#define IFE_CSID_VER2_RX_ERROR_CRC BIT(19) +#define IFE_CSID_VER2_RX_ERROR_ECC BIT(20) +#define IFE_CSID_VER2_RX_MMAPPED_VC_DT BIT(21) +#define IFE_CSID_VER2_RX_UNMAPPED_VC_DT BIT(22) +#define IFE_CSID_VER2_RX_STREAM_UNDERFLOW BIT(23) +#define IFE_CSID_VER2_RX_UNBOUNDED_FRAME BIT(24) +#define IFE_CSID_VER2_RX_RST_DONE BIT(27) + +#define CAM_IFE_CSID_VER2_PAYLOAD_MAX 256 + +#define IFE_CSID_VER2_TOP_IRQ_DONE BIT(0) +#define IFE_CSID_VER2_PATH_INFO_RST_DONE BIT(1) +#define IFE_CSID_VER2_PATH_ERROR_FIFO_OVERFLOW BIT(2) +#define IFE_CSID_VER2_PATH_CAMIF_EOF BIT(3) +#define IFE_CSID_VER2_PATH_CAMIF_SOF BIT(4) +#define IFE_CSID_VER2_PATH_INFO_FRAME_DROP_EOF BIT(5) +#define IFE_CSID_VER2_PATH_INFO_FRAME_DROP_EOL BIT(6) +#define IFE_CSID_VER2_PATH_INFO_FRAME_DROP_SOL BIT(7) +#define IFE_CSID_VER2_PATH_INFO_FRAME_DROP_SOF BIT(8) +#define IFE_CSID_VER2_PATH_INFO_INPUT_EOF BIT(9) +#define IFE_CSID_VER2_PATH_INFO_INPUT_EOL BIT(10) +#define IFE_CSID_VER2_PATH_INFO_INPUT_SOL BIT(11) +#define IFE_CSID_VER2_PATH_INFO_INPUT_SOF BIT(12) +#define IFE_CSID_VER2_PATH_ERROR_PIX_COUNT BIT(13) +#define IFE_CSID_VER2_PATH_ERROR_LINE_COUNT BIT(14) +#define IFE_CSID_VER2_PATH_VCDT_GRP0_SEL BIT(15) +#define IFE_CSID_VER2_PATH_VCDT_GRP1_SEL BIT(16) +#define IFE_CSID_VER2_PATH_VCDT_GRP_CHANGE BIT(17) +#define IFE_CSID_VER2_PATH_FRAME_DROP BIT(18) +#define IFE_CSID_VER2_PATH_OVERFLOW BIT(19) +#define IFE_CSID_VER2_PATH_ERROR_REC_CCIF_VIOLATION BIT(20) +#define IFE_CSID_VER2_PATH_CAMIF_EPOCH0 BIT(21) +#define IFE_CSID_VER2_PATH_CAMIF_EPOCH1 BIT(22) +#define IFE_CSID_VER2_PATH_RUP_DONE BIT(23) +#define IFE_CSID_VER2_PATH_ILLEGAL_BATCH_ID BIT(24) +#define IFE_CSID_VER2_PATH_BATCH_END_MISSING_VIOLATION BIT(25) +#define IFE_CSID_VER2_PATH_HEIGHT_VIOLATION BIT(26) +#define IFE_CSID_VER2_PATH_WIDTH_VIOLATION BIT(27) +#define IFE_CSID_VER2_PATH_SENSOR_SWITCH_OUT_OF_SYNC_FRAME_DROP BIT(28) +#define IFE_CSID_VER2_PATH_CCIF_VIOLATION BIT(29) + +/*Each Bit represents the index of cust node hw*/ +#define IFE_CSID_VER2_CUST_NODE_IDX_0 0x1 +#define IFE_CSID_VER2_CUST_NODE_IDX_1 0x2 +#define IFE_CSID_VER2_CUST_NODE_IDX_2 0x4 + +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RST BIT(0) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RX0 BIT(2) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RX1 BIT(3) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_IPP0 BIT(4) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_IPP1 BIT(5) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_PPP0 BIT(6) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_PPP1 BIT(7) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RDI0 BIT(8) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RDI1 BIT(9) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RDI2 BIT(10) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RDI3 BIT(11) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_RDI4 BIT(12) +#define IFE_CSID_VER2_TOP_IRQ_STATUS_BUF_DONE BIT(13) + +enum cam_ife_csid_ver2_input_core_sel { + CAM_IFE_CSID_INPUT_CORE_SEL_NONE, + CAM_IFE_CSID_INPUT_CORE_SEL_INTERNAL, + CAM_IFE_CSID_INPUT_CORE_SEL_SFE_0, + CAM_IFE_CSID_INPUT_CORE_SEL_SFE_1, + CAM_IFE_CSID_INPUT_CORE_SEL_CUST_NODE_0, + CAM_IFE_CSID_INPUT_CORE_SEL_CUST_NODE_1, + CAM_IFE_CSID_INPUT_CORE_SEL_CUST_NODE_2, + CAM_IFE_CSID_INPUT_CORE_SEL_MAX, +}; + +enum cam_ife_csid_ver2_csid_reset_loc { + CAM_IFE_CSID_RESET_LOC_PATH_ONLY, + CAM_IFE_CSID_RESET_LOC_COMPLETE, + CAM_IFE_CSID_RESET_LOC_MAX, +}; + +enum cam_ife_csid_ver2_csid_reset_cmd { + CAM_IFE_CSID_RESET_CMD_IRQ_CTRL, + CAM_IFE_CSID_RESET_CMD_SW_RST, + CAM_IFE_CSID_RESET_CMD_HW_RST, + CAM_IFE_CSID_RESET_CMD_HW_MAX, +}; + +struct cam_ife_csid_ver2_top_cfg { + uint32_t input_core_type; + uint32_t dual_sync_core_sel; + uint32_t master_slave_sel; + bool dual_en; + bool offline_sfe_en; + bool out_ife_en; +}; + +struct cam_ife_csid_ver2_evt_payload { + struct list_head list; + uint32_t irq_reg_val[CAM_IFE_CSID_IRQ_REG_MAX]; +}; + +/* + * struct cam_ife_csid_ver2_path_cfg: place holder for path parameters + * + * @pix_pattern: Pix pattern for incoming data + * @stripe_loc: Stripe location + * @epoch0_cfg: Epoch 0 configuration value + * @epoch1_cfg: Epoch 1 configuration value + */ +struct cam_ife_csid_ver2_camif_data { + uint32_t pix_pattern; + uint32_t stripe_loc; + uint32_t epoch0; + uint32_t epoch1; +}; + +/* + * struct cam_ife_csid_ver2_path_cfg: place holder for path parameters + * + * @camif_data: CAMIF data + * @cid: cid value for path + * @in_format: input format + * @out_format: output format + * @start_pixel: start pixel for horizontal crop + * @end_pixel: end pixel for horizontal crop + * @start_line: start line for vertical crop + * @end_line: end line for vertical crop + * @width: width of incoming data + * @height: height of incoming data + * @master_idx: master idx + * @horizontal_bin: horizontal binning enable/disable on path + * @vertical_bin: vertical binning enable/disable on path + * @qcfa_bin : qcfa binning enable/disable on path + * @hor_ver_bin : horizontal vertical binning enable/disable on path + * @num_bytes_out: Number of bytes out + * @pix_pattern: Pixel Pattern + * @sync_mode : Sync mode--> master/slave/none + * @vfr_en : flag to indicate if variable frame rate is enabled + * @frame_id_dec_en: flag to indicate if frame id decoding is enabled + * @crop_enable: flag to indicate crop enable + * @drop_enable: flag to indicate drop enable + * @offline_mode: flag to indicate if path working in offline mode + * + */ +struct cam_ife_csid_ver2_path_cfg { + struct cam_ife_csid_ver2_camif_data camif_data; + uint32_t cid; + uint32_t in_format; + uint32_t out_format; + uint32_t start_pixel; + uint32_t end_pixel; + uint32_t width; + uint32_t start_line; + uint32_t end_line; + uint32_t height; + uint32_t master_idx; + uint64_t clk_rate; + uint32_t horizontal_bin; + uint32_t vertical_bin; + uint32_t qcfa_bin; + uint32_t hor_ver_bin; + uint32_t num_bytes_out; + uint32_t pix_pattern; + enum cam_isp_hw_sync_mode sync_mode; + bool vfr_en; + bool frame_id_dec_en; + bool crop_enable; + bool drop_enable; + bool offline_mode; + bool handle_camif_irq; +}; + +struct cam_ife_csid_ver2_top_reg_info { + uint32_t io_path_cfg0_addr[CAM_IFE_CSID_HW_NUM_MAX]; + uint32_t dual_csid_cfg0_addr[CAM_IFE_CSID_HW_NUM_MAX]; + uint32_t input_core_type_shift_val; + uint32_t sfe_offline_en_shift_val; + uint32_t out_ife_en_shift_val; + uint32_t dual_sync_sel_shift_val; + uint32_t dual_en_shift_val; + uint32_t master_slave_sel_shift_val; + uint32_t master_sel_val; + uint32_t slave_sel_val; +}; + +struct cam_ife_csid_ver2_rdi_reg_info { + uint32_t irq_status_addr; + uint32_t irq_mask_addr; + uint32_t irq_clear_addr; + uint32_t irq_set_addr; + uint32_t cfg0_addr; + uint32_t ctrl_addr; + uint32_t debug_clr_cmd_addr; + uint32_t multi_vcdt_cfg0_addr; + uint32_t cfg1_addr; + uint32_t err_recovery_cfg0_addr; + uint32_t err_recovery_cfg1_addr; + uint32_t err_recovery_cfg2_addr; + uint32_t debug_byte_cntr_ping_addr; + uint32_t debug_byte_cntr_pong_addr; + uint32_t camif_frame_cfg_addr; + uint32_t epoch_irq_cfg_addr; + uint32_t epoch0_subsample_ptrn_addr; + uint32_t epoch1_subsample_ptrn_addr; + uint32_t debug_camif_1_addr; + uint32_t debug_camif_0_addr; + uint32_t frm_drop_pattern_addr; + uint32_t frm_drop_period_addr; + uint32_t irq_subsample_pattern_addr; + uint32_t irq_subsample_period_addr; + uint32_t hcrop_addr; + uint32_t vcrop_addr; + uint32_t pix_drop_pattern_addr; + uint32_t pix_drop_period_addr; + uint32_t line_drop_pattern_addr; + uint32_t line_drop_period_addr; + uint32_t debug_halt_status_addr; + uint32_t debug_misr_val0_addr; + uint32_t debug_misr_val1_addr; + uint32_t debug_misr_val2_addr; + uint32_t debug_misr_val3_addr; + uint32_t format_measure_cfg0_addr; + uint32_t format_measure_cfg1_addr; + uint32_t format_measure0_addr; + uint32_t format_measure1_addr; + uint32_t format_measure2_addr; + uint32_t timestamp_curr0_sof_addr; + uint32_t timestamp_curr1_sof_addr; + uint32_t timestamp_perv0_sof_addr; + uint32_t timestamp_perv1_sof_addr; + uint32_t timestamp_curr0_eof_addr; + uint32_t timestamp_curr1_eof_addr; + uint32_t timestamp_perv0_eof_addr; + uint32_t timestamp_perv1_eof_addr; + uint32_t batch_id_cfg0_addr; + uint32_t batch_id_cfg1_addr; + uint32_t batch_period_cfg_addr; + uint32_t batch_stream_id_cfg_addr; + uint32_t epoch0_cfg_batch_id0_addr; + uint32_t epoch1_cfg_batch_id0_addr; + uint32_t epoch0_cfg_batch_id1_addr; + uint32_t epoch1_cfg_batch_id1_addr; + uint32_t epoch0_cfg_batch_id2_addr; + uint32_t epoch1_cfg_batch_id2_addr; + uint32_t epoch0_cfg_batch_id3_addr; + uint32_t epoch1_cfg_batch_id3_addr; + uint32_t epoch0_cfg_batch_id4_addr; + uint32_t epoch1_cfg_batch_id4_addr; + uint32_t epoch0_cfg_batch_id5_addr; + uint32_t epoch1_cfg_batch_id5_addr; + + /*Shift Bit Configurations*/ + uint32_t resume_frame_boundary; + uint32_t offline_mode_supported; + uint32_t mipi_pack_supported; + uint32_t packing_fmt_shift_val; + uint32_t plain_fmt_shift_val; + uint32_t plain_alignment_shift_val; + uint32_t crop_v_en_shift_val; + uint32_t crop_h_en_shift_val; + uint32_t drop_v_en_shift_val; + uint32_t drop_h_en_shift_val; + uint32_t early_eof_en_shift_val; + uint32_t format_measure_en_shift_val; + uint32_t timestamp_en_shift_val; + uint32_t byte_cntr_en_shift_val; + uint32_t offline_mode_en_shift_val; + uint32_t debug_byte_cntr_rst_shift_val; + uint32_t stripe_loc_shift_val; + uint32_t pix_pattern_shift_val; + uint32_t ccif_violation_en; + uint32_t overflow_ctrl_mode_val; + uint32_t overflow_ctrl_en; + uint32_t fatal_err_mask; + uint32_t non_fatal_err_mask; + uint32_t pix_pattern_shift; + uint32_t camif_irq_mask; + uint32_t rup_aup_mask; + uint32_t epoch0_cfg_val; + uint32_t epoch1_cfg_val; +}; + +struct cam_ife_csid_ver2_pxl_reg_info { + uint32_t irq_status_addr; + uint32_t irq_mask_addr; + uint32_t irq_clear_addr; + uint32_t irq_set_addr; + uint32_t cfg0_addr; + uint32_t ctrl_addr; + uint32_t debug_clr_cmd_addr; + uint32_t multi_vcdt_cfg0_addr; + uint32_t cfg1_addr; + uint32_t sparse_pd_extractor_cfg_addr; + uint32_t err_recovery_cfg0_addr; + uint32_t err_recovery_cfg1_addr; + uint32_t err_recovery_cfg2_addr; + uint32_t bin_pd_detect_cfg0_addr; + uint32_t bin_pd_detect_cfg1_addr; + uint32_t bin_pd_detect_cfg2_addr; + uint32_t camif_frame_cfg_addr; + uint32_t epoch_irq_cfg_addr; + uint32_t epoch0_subsample_ptrn_addr; + uint32_t epoch1_subsample_ptrn_addr; + uint32_t debug_camif_1_addr; + uint32_t debug_camif_0_addr; + uint32_t debug_halt_status_addr; + uint32_t debug_misr_val0_addr; + uint32_t debug_misr_val1_addr; + uint32_t debug_misr_val2_addr; + uint32_t debug_misr_val3_addr; + uint32_t hcrop_addr; + uint32_t vcrop_addr; + uint32_t pix_drop_pattern_addr; + uint32_t pix_drop_period_addr; + uint32_t line_drop_pattern_addr; + uint32_t line_drop_period_addr; + uint32_t frm_drop_pattern_addr; + uint32_t frm_drop_period_addr; + uint32_t irq_subsample_pattern_addr; + uint32_t irq_subsample_period_addr; + uint32_t format_measure_cfg0_addr; + uint32_t format_measure_cfg1_addr; + uint32_t format_measure0_addr; + uint32_t format_measure1_addr; + uint32_t format_measure2_addr; + uint32_t timestamp_curr0_sof_addr; + uint32_t timestamp_curr1_sof_addr; + uint32_t timestamp_perv0_sof_addr; + uint32_t timestamp_perv1_sof_addr; + uint32_t timestamp_curr0_eof_addr; + uint32_t timestamp_curr1_eof_addr; + uint32_t timestamp_perv0_eof_addr; + uint32_t timestamp_perv1_eof_addr; + uint32_t lut_bank_cfg_addr; + uint32_t batch_id_cfg0_addr; + uint32_t batch_id_cfg1_addr; + uint32_t batch_period_cfg_addr; + uint32_t batch_stream_id_cfg_addr; + uint32_t epoch0_cfg_batch_id0_addr; + uint32_t epoch1_cfg_batch_id0_addr; + uint32_t epoch0_cfg_batch_id1_addr; + uint32_t epoch1_cfg_batch_id1_addr; + uint32_t epoch0_cfg_batch_id2_addr; + uint32_t epoch1_cfg_batch_id2_addr; + uint32_t epoch0_cfg_batch_id3_addr; + uint32_t epoch1_cfg_batch_id3_addr; + uint32_t epoch0_cfg_batch_id4_addr; + uint32_t epoch1_cfg_batch_id4_addr; + uint32_t epoch0_cfg_batch_id5_addr; + uint32_t epoch1_cfg_batch_id5_addr; + + /*Shift Bit Configurations*/ + uint32_t start_mode_master; + uint32_t start_mode_internal; + uint32_t start_mode_global; + uint32_t start_mode_slave; + uint32_t start_mode_shift; + uint32_t start_master_sel_val; + uint32_t start_master_sel_shift; + uint32_t crop_v_en_shift_val; + uint32_t crop_h_en_shift_val; + uint32_t drop_v_en_shift_val; + uint32_t drop_h_en_shift_val; + uint32_t pix_store_en_shift_val; + uint32_t early_eof_en_shift_val; + uint32_t bin_h_en_shift_val; + uint32_t bin_v_en_shift_val; + uint32_t bin_en_shift_val; + uint32_t bin_qcfa_en_shift_val; + uint32_t format_measure_en_shift_val; + uint32_t timestamp_en_shift_val; + uint32_t min_hbi_shift_val; + uint32_t start_master_sel_shift_val; + uint32_t bin_pd_en_shift_val; + uint32_t bin_pd_blk_w_shift_val; + uint32_t bin_pd_blk_h_shift_val; + uint32_t bin_pd_detect_x_offset_shift_val; + uint32_t bin_pd_detect_x_end_shift_val; + uint32_t bin_pd_detect_y_offset_shift_val; + uint32_t bin_pd_detect_y_end_shift_val; + uint32_t stripe_loc_shift_val; + uint32_t pix_pattern_shift_val; + uint32_t epoch0_cfg_val; + uint32_t epoch1_cfg_val; + /* config Values */ + uint32_t resume_frame_boundary; + uint32_t overflow_ctrl_mode_val; + uint32_t overflow_ctrl_en; + uint32_t lut_bank_0_sel_val; + uint32_t lut_bank_1_sel_val; + uint32_t ccif_violation_en; + uint32_t binning_supported; + uint32_t fatal_err_mask; + uint32_t non_fatal_err_mask; + uint32_t camif_irq_mask; + uint32_t rup_aup_mask; +}; + +struct cam_ife_csid_ver2_common_reg_info { + uint32_t hw_version_addr; + uint32_t cfg0_addr; + uint32_t global_cmd_addr; + uint32_t reset_cfg_addr; + uint32_t reset_cmd_addr; + uint32_t rup_aup_cmd_addr; + uint32_t offline_cmd_addr; + uint32_t shdr_master_slave_cfg_addr; + uint32_t top_irq_status_addr; + uint32_t top_irq_mask_addr; + uint32_t top_irq_clear_addr; + uint32_t top_irq_set_addr; + uint32_t irq_cmd_addr; + uint32_t buf_done_irq_status_addr; + uint32_t buf_done_irq_mask_addr; + uint32_t buf_done_irq_clear_addr; + uint32_t buf_done_irq_set_addr; + + /*Shift Bit Configurations*/ + uint32_t rst_done_shift_val; + uint32_t rst_location_shift_val; + uint32_t rst_mode_shift_val; + uint32_t timestamp_stb_sel_shift_val; + uint32_t frame_id_decode_en_shift_val; + uint32_t vfr_en_shift_val; + uint32_t decode_format_shift_val; + uint32_t start_mode_shift_val; + uint32_t start_cmd_shift_val; + uint32_t path_en_shift_val; + uint32_t dt_id_shift_val; + uint32_t vc_shift_val; + uint32_t dt_shift_val; + uint32_t crop_shift_val; + uint32_t debug_frm_drop_rst_shift_val; + uint32_t debug_timestamp_rst_shift_val; + uint32_t debug_format_measure_rst_shift_val; + uint32_t debug_misr_rst_shift_val; + uint32_t num_padding_pixels_shift_val; + uint32_t num_padding_rows_shift_val; + uint32_t num_vbi_lines_shift_val; + uint32_t num_hbi_cycles_shift_val; + uint32_t camif_stripe_loc_shift_val; + uint32_t camif_pix_pattern_shift_val; + uint32_t epoch0_line_shift_val; + uint32_t epoch1_line_shift_val; + uint32_t camif_width_shift_val; + uint32_t camif_height_shift_val; + uint32_t batch_id0_shift_val; + uint32_t batch_id1_shift_val; + uint32_t batch_id2_shift_val; + uint32_t batch_id3_shift_val; + uint32_t batch_id4_shift_val; + uint32_t batch_id5_shift_val; + uint32_t batch_id0_period_shift_val; + uint32_t batch_id1_period_shift_val; + uint32_t batch_id2_period_shift_val; + uint32_t batch_id3_period_shift_val; + uint32_t batch_id4_period_shift_val; + uint32_t batch_id5_period_shift_val; + uint32_t stream_id_len_shift_val; + uint32_t stream_id_x_offset_shift_val; + uint32_t stream_id_y_offset_shift_val; + uint32_t multi_vcdt_vc1_shift_val; + uint32_t multi_vcdt_dt1_shift_val; + uint32_t multi_vcdt_ts_combo_en_shift_val; + uint32_t multi_vcdt_en_shift_val; + uint32_t mup_shift_val; + uint32_t shdr_slave_rdi2_shift; + uint32_t shdr_slave_rdi1_shift; + uint32_t shdr_master_rdi0_shift; + uint32_t shdr_master_slave_en_shift; + /* config Values */ + uint32_t major_version; + uint32_t minor_version; + uint32_t version_incr; + uint32_t num_udis; + uint32_t num_rdis; + uint32_t num_pix; + uint32_t num_ppp; + uint32_t rst_loc_path_only_val; + uint32_t rst_loc_complete_csid_val; + uint32_t rst_mode_frame_boundary_val; + uint32_t rst_mode_immediate_val; + uint32_t rst_cmd_irq_ctrl_only_val; + uint32_t rst_cmd_sw_reset_complete_val; + uint32_t rst_cmd_hw_reset_complete_val; + uint32_t vfr_supported; + uint32_t frame_id_dec_supported; + uint32_t drop_supported; + uint32_t multi_vcdt_supported; + uint32_t timestamp_strobe_val; + uint32_t overflow_ctrl_mode_val; + uint32_t overflow_ctrl_en; + uint32_t early_eof_supported; + uint32_t global_reset; + uint32_t rup_supported; + /* Masks */ + uint32_t pxl_cnt_mask; + uint32_t line_cnt_mask; + uint32_t hblank_max_mask; + uint32_t hblank_min_mask; + uint32_t epoch0_line_mask; + uint32_t epoch1_line_mask; + uint32_t camif_width_mask; + uint32_t camif_height_mask; + uint32_t crop_pix_start_mask; + uint32_t crop_pix_end_mask; + uint32_t crop_line_start_mask; + uint32_t crop_line_end_mask; + uint32_t measure_en_hbi_vbi_cnt_mask; + uint32_t measure_pixel_line_en_mask; + uint32_t ipp_irq_mask_all; + uint32_t rdi_irq_mask_all; + uint32_t ppp_irq_mask_all; + uint32_t udi_irq_mask_all; + uint32_t top_reset_irq_shift_val; + uint32_t epoch_div_factor; +}; + +struct cam_ife_csid_ver2_reg_info { + struct cam_irq_controller_reg_info *irq_reg_info; + struct cam_irq_controller_reg_info *buf_done_irq_reg_info; + const struct cam_ife_csid_ver2_common_reg_info *cmn_reg; + const struct cam_ife_csid_csi2_rx_reg_info *csi2_reg; + const struct cam_ife_csid_ver2_pxl_reg_info *ipp_reg; + const struct cam_ife_csid_ver2_pxl_reg_info *ppp_reg; + const struct cam_ife_csid_ver2_rdi_reg_info *rdi_reg + [CAM_IFE_CSID_RDI_MAX]; + const struct cam_ife_csid_ver2_top_reg_info *top_reg; + const uint32_t need_top_cfg; + const uint32_t csid_cust_node_map[ + CAM_IFE_CSID_HW_NUM_MAX]; + const int input_core_sel[ + CAM_IFE_CSID_HW_NUM_MAX][CAM_IFE_CSID_INPUT_CORE_SEL_MAX]; +}; + +/* + * struct cam_ife_csid_ver2_hw: place holder for csid hw + * + * @path_res: array of path resources + * @cid_data: cid data + * @rx_cfg: rx configuration + * @flags: flags + * @irq_complete: complete variable for reset irq + * @debug_info: Debug info to capture debug info + * @timestamp: Timestamp info + * @timestamp: Timestamp info + * @rx_evt_payload Payload for rx events + * @path_evt_payload Payload for path events + * @rx_free_payload_list: Free Payload list for rx events + * @free_payload_list: Free Payload list for rx events + * @lock_state : spin lock + * @payload_lock: spin lock for path payload + * @rx_payload_lock: spin lock for rx payload + * @csid_irq_controller: common csid irq controller + * @buf_done_irq_controller: buf done irq controller + * @hw_info: hw info + * @core_info: csid core info + * @token: Context private of ife hw manager + * @event_cb: Event cb to ife hw manager + * @irq_handle: Array of irq handle for events + * @err_irq_handle: Array of irq handle for error events + * @counters: counters used in csid hw + * @log_buf: Log Buffer to dump info + * @clk_rate: clk rate for csid hw + * @res_type: cur res type for active hw + * @dual_core_idx: core idx in case of dual csid + * @tasklet: Tasklet for irq events + * @reset_irq_handle: Reset irq handle + * @buf_done_irq_handle: Buf done irq handle + * @sync_mode: Master/Slave modes + * + */ +struct cam_ife_csid_ver2_hw { + struct cam_isp_resource_node path_res + [CAM_IFE_PIX_PATH_RES_MAX]; + struct cam_ife_csid_cid_data cid_data[CAM_IFE_CSID_CID_MAX]; + struct cam_ife_csid_ver2_top_cfg top_cfg; + struct cam_ife_csid_rx_cfg rx_cfg; + struct cam_ife_csid_hw_counters counters; + struct cam_ife_csid_hw_flags flags; + struct completion irq_complete + [CAM_IFE_CSID_IRQ_REG_MAX]; + struct cam_ife_csid_debug_info debug_info; + struct cam_ife_csid_timestamp timestamp; + struct cam_ife_csid_ver2_evt_payload rx_evt_payload[ + CAM_IFE_CSID_VER2_PAYLOAD_MAX]; + struct cam_ife_csid_ver2_evt_payload path_evt_payload[ + CAM_IFE_CSID_VER2_PAYLOAD_MAX]; + struct list_head rx_free_payload_list; + struct list_head path_free_payload_list; + spinlock_t lock_state; + spinlock_t path_payload_lock; + spinlock_t rx_payload_lock; + void *csid_irq_controller; + void *buf_done_irq_controller; + struct cam_hw_intf *hw_intf; + struct cam_hw_info *hw_info; + struct cam_ife_csid_core_info *core_info; + void *token; + cam_hw_mgr_event_cb_func event_cb; + int irq_handle[ + CAM_IFE_CSID_IRQ_REG_MAX]; + int err_irq_handle[ + CAM_IFE_CSID_IRQ_REG_MAX]; + uint8_t log_buf + [CAM_IFE_CSID_LOG_BUF_LEN]; + uint64_t clk_rate; + uint32_t res_type; + uint32_t dual_core_idx; + void *tasklet; + int reset_irq_handle; + int buf_done_irq_handle; + enum cam_isp_hw_sync_mode sync_mode; +}; + +int cam_ife_csid_hw_ver2_init(struct cam_hw_intf *csid_hw_intf, + struct cam_ife_csid_core_info *csid_core_info, + bool is_custom); + +int cam_ife_csid_hw_ver2_deinit(struct cam_hw_info *hw_priv); + +#endif diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.h index 4d8783ce0c..e5d97e3084 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.h @@ -1,316 +1,398 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_LITE17X_H_ #define _CAM_IFE_CSID_LITE17X_H_ -#include "cam_ife_csid_core.h" -static const struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_17x_rdi_0_reg_offset = { +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" - .csid_rdi_irq_status_addr = 0x30, - .csid_rdi_irq_mask_addr = 0x34, - .csid_rdi_irq_clear_addr = 0x38, - .csid_rdi_irq_set_addr = 0x3c, - .csid_rdi_cfg0_addr = 0x200, - .csid_rdi_cfg1_addr = 0x204, - .csid_rdi_ctrl_addr = 0x208, - .csid_rdi_frm_drop_pattern_addr = 0x20c, - .csid_rdi_frm_drop_period_addr = 0x210, - .csid_rdi_irq_subsample_pattern_addr = 0x214, - .csid_rdi_irq_subsample_period_addr = 0x218, - .csid_rdi_rpp_hcrop_addr = 0x21c, - .csid_rdi_rpp_vcrop_addr = 0x220, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x224, - .csid_rdi_rpp_pix_drop_period_addr = 0x228, - .csid_rdi_rpp_line_drop_pattern_addr = 0x22c, - .csid_rdi_rpp_line_drop_period_addr = 0x230, - .csid_rdi_rst_strobes_addr = 0x240, - .csid_rdi_status_addr = 0x250, - .csid_rdi_misr_val0_addr = 0x254, - .csid_rdi_misr_val1_addr = 0x258, - .csid_rdi_misr_val2_addr = 0x25c, - .csid_rdi_misr_val3_addr = 0x260, - .csid_rdi_format_measure_cfg0_addr = 0x270, - .csid_rdi_format_measure_cfg1_addr = 0x274, - .csid_rdi_format_measure0_addr = 0x278, - .csid_rdi_format_measure1_addr = 0x27c, - .csid_rdi_format_measure2_addr = 0x280, - .csid_rdi_timestamp_curr0_sof_addr = 0x290, - .csid_rdi_timestamp_curr1_sof_addr = 0x294, - .csid_rdi_timestamp_prev0_sof_addr = 0x298, - .csid_rdi_timestamp_prev1_sof_addr = 0x29c, - .csid_rdi_timestamp_curr0_eof_addr = 0x2a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x2a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x2a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x2ac, - .csid_rdi_byte_cntr_ping_addr = 0x2e0, - .csid_rdi_byte_cntr_pong_addr = 0x2e4, +#define CAM_CSID_LITE_DRV_NAME "csid_lite" + +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_17x_rdi_0_reg_info = { + + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x250, + .misr_val0_addr = 0x254, + .misr_val1_addr = 0x258, + .misr_val2_addr = 0x25c, + .misr_val3_addr = 0x260, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, + .byte_cntr_ping_addr = 0x2e0, + .byte_cntr_pong_addr = 0x2e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .packing_fmt_shift_val = 30, + .plain_fmt_shift_val = 10, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x8000, }; -static const struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_17x_rdi_1_reg_offset = { +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_17x_rdi_1_reg_info = { - .csid_rdi_irq_status_addr = 0x40, - .csid_rdi_irq_mask_addr = 0x44, - .csid_rdi_irq_clear_addr = 0x48, - .csid_rdi_irq_set_addr = 0x4c, - .csid_rdi_cfg0_addr = 0x300, - .csid_rdi_cfg1_addr = 0x304, - .csid_rdi_ctrl_addr = 0x308, - .csid_rdi_frm_drop_pattern_addr = 0x30c, - .csid_rdi_frm_drop_period_addr = 0x310, - .csid_rdi_irq_subsample_pattern_addr = 0x314, - .csid_rdi_irq_subsample_period_addr = 0x318, - .csid_rdi_rpp_hcrop_addr = 0x31c, - .csid_rdi_rpp_vcrop_addr = 0x320, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x324, - .csid_rdi_rpp_pix_drop_period_addr = 0x328, - .csid_rdi_rpp_line_drop_pattern_addr = 0x32c, - .csid_rdi_rpp_line_drop_period_addr = 0x330, - .csid_rdi_rst_strobes_addr = 0x340, - .csid_rdi_status_addr = 0x350, - .csid_rdi_misr_val0_addr = 0x354, - .csid_rdi_misr_val1_addr = 0x358, - .csid_rdi_misr_val2_addr = 0x35c, - .csid_rdi_misr_val3_addr = 0x360, - .csid_rdi_format_measure_cfg0_addr = 0x370, - .csid_rdi_format_measure_cfg1_addr = 0x374, - .csid_rdi_format_measure0_addr = 0x378, - .csid_rdi_format_measure1_addr = 0x37c, - .csid_rdi_format_measure2_addr = 0x380, - .csid_rdi_timestamp_curr0_sof_addr = 0x390, - .csid_rdi_timestamp_curr1_sof_addr = 0x394, - .csid_rdi_timestamp_prev0_sof_addr = 0x398, - .csid_rdi_timestamp_prev1_sof_addr = 0x39c, - .csid_rdi_timestamp_curr0_eof_addr = 0x3a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x3a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x3a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x3ac, - .csid_rdi_byte_cntr_ping_addr = 0x3e0, - .csid_rdi_byte_cntr_pong_addr = 0x3e4, + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, }; -static const struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_17x_rdi_2_reg_offset = { +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_17x_rdi_2_reg_info = { - .csid_rdi_irq_status_addr = 0x50, - .csid_rdi_irq_mask_addr = 0x54, - .csid_rdi_irq_clear_addr = 0x58, - .csid_rdi_irq_set_addr = 0x5c, - .csid_rdi_cfg0_addr = 0x400, - .csid_rdi_cfg1_addr = 0x404, - .csid_rdi_ctrl_addr = 0x408, - .csid_rdi_frm_drop_pattern_addr = 0x40c, - .csid_rdi_frm_drop_period_addr = 0x410, - .csid_rdi_irq_subsample_pattern_addr = 0x414, - .csid_rdi_irq_subsample_period_addr = 0x418, - .csid_rdi_rpp_hcrop_addr = 0x41c, - .csid_rdi_rpp_vcrop_addr = 0x420, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x424, - .csid_rdi_rpp_pix_drop_period_addr = 0x428, - .csid_rdi_rpp_line_drop_pattern_addr = 0x42c, - .csid_rdi_rpp_line_drop_period_addr = 0x430, - .csid_rdi_yuv_chroma_conversion_addr = 0x434, - .csid_rdi_rst_strobes_addr = 0x440, - .csid_rdi_status_addr = 0x450, - .csid_rdi_misr_val0_addr = 0x454, - .csid_rdi_misr_val1_addr = 0x458, - .csid_rdi_misr_val2_addr = 0x45c, - .csid_rdi_misr_val3_addr = 0x460, - .csid_rdi_format_measure_cfg0_addr = 0x470, - .csid_rdi_format_measure_cfg1_addr = 0x474, - .csid_rdi_format_measure0_addr = 0x478, - .csid_rdi_format_measure1_addr = 0x47c, - .csid_rdi_format_measure2_addr = 0x480, - .csid_rdi_timestamp_curr0_sof_addr = 0x490, - .csid_rdi_timestamp_curr1_sof_addr = 0x494, - .csid_rdi_timestamp_prev0_sof_addr = 0x498, - .csid_rdi_timestamp_prev1_sof_addr = 0x49c, - .csid_rdi_timestamp_curr0_eof_addr = 0x4a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x4a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x4a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x4ac, - .csid_rdi_byte_cntr_ping_addr = 0x4e0, - .csid_rdi_byte_cntr_pong_addr = 0x4e4, + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .yuv_chroma_conversion_addr = 0x434, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, }; -static const struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_17x_rdi_3_reg_offset = { +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_17x_rdi_3_reg_info = { - .csid_rdi_irq_status_addr = 0x60, - .csid_rdi_irq_mask_addr = 0x64, - .csid_rdi_irq_clear_addr = 0x68, - .csid_rdi_irq_set_addr = 0x6c, - .csid_rdi_cfg0_addr = 0x500, - .csid_rdi_cfg1_addr = 0x504, - .csid_rdi_ctrl_addr = 0x508, - .csid_rdi_frm_drop_pattern_addr = 0x50c, - .csid_rdi_frm_drop_period_addr = 0x510, - .csid_rdi_irq_subsample_pattern_addr = 0x514, - .csid_rdi_irq_subsample_period_addr = 0x518, - .csid_rdi_rpp_hcrop_addr = 0x51c, - .csid_rdi_rpp_vcrop_addr = 0x520, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x524, - .csid_rdi_rpp_pix_drop_period_addr = 0x528, - .csid_rdi_rpp_line_drop_pattern_addr = 0x52c, - .csid_rdi_rpp_line_drop_period_addr = 0x530, - .csid_rdi_yuv_chroma_conversion_addr = 0x534, - .csid_rdi_rst_strobes_addr = 0x540, - .csid_rdi_status_addr = 0x550, - .csid_rdi_misr_val0_addr = 0x554, - .csid_rdi_misr_val1_addr = 0x558, - .csid_rdi_misr_val2_addr = 0x55c, - .csid_rdi_misr_val3_addr = 0x560, - .csid_rdi_format_measure_cfg0_addr = 0x570, - .csid_rdi_format_measure_cfg1_addr = 0x574, - .csid_rdi_format_measure0_addr = 0x578, - .csid_rdi_format_measure1_addr = 0x57c, - .csid_rdi_format_measure2_addr = 0x580, - .csid_rdi_timestamp_curr0_sof_addr = 0x590, - .csid_rdi_timestamp_curr1_sof_addr = 0x594, - .csid_rdi_timestamp_prev0_sof_addr = 0x598, - .csid_rdi_timestamp_prev1_sof_addr = 0x59c, - .csid_rdi_timestamp_curr0_eof_addr = 0x5a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x5a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x5a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x5ac, - .csid_rdi_byte_cntr_ping_addr = 0x5e0, - .csid_rdi_byte_cntr_pong_addr = 0x5e4, + .irq_status_addr = 0x60, + .irq_mask_addr = 0x64, + .irq_clear_addr = 0x68, + .irq_set_addr = 0x6c, + .cfg0_addr = 0x500, + .cfg1_addr = 0x504, + .ctrl_addr = 0x508, + .frm_drop_pattern_addr = 0x50c, + .frm_drop_period_addr = 0x510, + .irq_subsample_pattern_addr = 0x514, + .irq_subsample_period_addr = 0x518, + .hcrop_addr = 0x51c, + .vcrop_addr = 0x520, + .pix_drop_pattern_addr = 0x524, + .pix_drop_period_addr = 0x528, + .line_drop_pattern_addr = 0x52c, + .line_drop_period_addr = 0x530, + .yuv_chroma_conversion_addr = 0x534, + .rst_strobes_addr = 0x540, + .status_addr = 0x550, + .misr_val0_addr = 0x554, + .misr_val1_addr = 0x558, + .misr_val2_addr = 0x55c, + .misr_val3_addr = 0x560, + .format_measure_cfg0_addr = 0x570, + .format_measure_cfg1_addr = 0x574, + .format_measure0_addr = 0x578, + .format_measure1_addr = 0x57c, + .format_measure2_addr = 0x580, + .timestamp_curr0_sof_addr = 0x590, + .timestamp_curr1_sof_addr = 0x594, + .timestamp_prev0_sof_addr = 0x598, + .timestamp_prev1_sof_addr = 0x59c, + .timestamp_curr0_eof_addr = 0x5a0, + .timestamp_curr1_eof_addr = 0x5a4, + .timestamp_prev0_eof_addr = 0x5a8, + .timestamp_prev1_eof_addr = 0x5ac, + .byte_cntr_ping_addr = 0x5e0, + .byte_cntr_pong_addr = 0x5e4, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, }; -static const struct cam_ife_csid_csi2_rx_reg_offset - cam_ife_csid_lite_17x_csi2_reg_offset = { +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_lite_17x_csi2_reg_info = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_de_scramble_cfg0_addr = 0x114, - .csid_csi2_rx_de_scramble_cfg1_addr = 0x118, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .de_scramble_cfg0_addr = 0x114, + .de_scramble_cfg1_addr = 0x118, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x3, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x3, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, }; -static const struct cam_ife_csid_csi2_tpg_reg_offset - cam_ife_csid_lite_17x_tpg_reg_offset = { - +static struct cam_ife_csid_ver1_tpg_reg_info + cam_ife_csid_lite_17x_tpg_reg_info = { /*CSID TPG control */ - .csid_tpg_ctrl_addr = 0x600, - .csid_tpg_vc_cfg0_addr = 0x604, - .csid_tpg_vc_cfg1_addr = 0x608, - .csid_tpg_lfsr_seed_addr = 0x60c, - .csid_tpg_dt_n_cfg_0_addr = 0x610, - .csid_tpg_dt_n_cfg_1_addr = 0x614, - .csid_tpg_dt_n_cfg_2_addr = 0x618, - .csid_tpg_color_bars_cfg_addr = 0x640, - .csid_tpg_color_box_cfg_addr = 0x644, - .csid_tpg_common_gen_cfg_addr = 0x648, - .csid_tpg_cgen_n_cfg_addr = 0x650, - .csid_tpg_cgen_n_x0_addr = 0x654, - .csid_tpg_cgen_n_x1_addr = 0x658, - .csid_tpg_cgen_n_x2_addr = 0x65c, - .csid_tpg_cgen_n_xy_addr = 0x660, - .csid_tpg_cgen_n_y1_addr = 0x664, - .csid_tpg_cgen_n_y2_addr = 0x668, + .ctrl_addr = 0x600, + .vc_cfg0_addr = 0x604, + .vc_cfg1_addr = 0x608, + .lfsr_seed_addr = 0x60c, + .dt_n_cfg_0_addr = 0x610, + .dt_n_cfg_1_addr = 0x614, + .dt_n_cfg_2_addr = 0x618, + .color_bars_cfg_addr = 0x640, + .color_box_cfg_addr = 0x644, + .common_gen_cfg_addr = 0x648, + .cgen_n_cfg_addr = 0x650, + .cgen_n_x0_addr = 0x654, + .cgen_n_x1_addr = 0x658, + .cgen_n_x2_addr = 0x65c, + .cgen_n_xy_addr = 0x660, + .cgen_n_y1_addr = 0x664, + .cgen_n_y2_addr = 0x668, - /*configurations */ - .tpg_dtn_cfg_offset = 0xc, - .tpg_cgen_cfg_offset = 0x20, - .tpg_cpas_ife_reg_offset = 0x28, + /* configurations */ + .dtn_cfg_offset = 0xc, + .cgen_cfg_offset = 0x20, + .cpas_ife_reg_offset = 0x28, + .hbi = 0x740, + .vbi = 0x3FF, + .ctrl_cfg = 0x408007, + .lfsr_seed = 0x12345678, + .color_bar = 1, + .num_frames = 0, + .line_interleave_mode = 0x1, + .payload_mode = 0x8, + .num_active_lanes_mask = 0x30, + .num_active_dt = 0, + .fmt_shift = 16, + .num_frame_shift = 16, + .width_shift = 16, + .vbi_shift = 12, + .line_interleave_shift = 10, + .num_active_dt_shift = 8, + .color_bar_shift = 5, + .height_shift = 0, + .hbi_shift = 0, }; -static const struct cam_ife_csid_common_reg_offset - cam_csid_lite_17x_cmn_reg_offset = { +static struct cam_ife_csid_ver1_common_reg_info + cam_csid_lite_17x_cmn_reg_info = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 1, - .minor_version = 7, - .version_incr = 0, - .num_rdis = 4, - .num_pix = 0, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .packing_fmt_shift_val = 30, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .crop_shift = 16, - .ipp_irq_mask_all = 0x7FFF, - .rdi_irq_mask_all = 0x7FFF, - .ppp_irq_mask_all = 0xFFFF, + .major_version = 1, + .minor_version = 7, + .version_incr = 0, + .num_rdis = 4, + .num_pix = 0, + .timestamp_strobe_val = 0x2, + .timestamp_stb_sel_shift_val = 0, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .ipp_irq_mask_all = 0x7FFF, + .rdi_irq_mask_all = 0x7FFF, + .ppp_irq_mask_all = 0xFFFF, }; -static const struct cam_ife_csid_reg_offset cam_ife_csid_lite_17x_reg_offset = { - .cmn_reg = &cam_csid_lite_17x_cmn_reg_offset, - .csi2_reg = &cam_ife_csid_lite_17x_csi2_reg_offset, +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_lite_17x_reg_info = { + .cmn_reg = &cam_csid_lite_17x_cmn_reg_info, + .csi2_reg = &cam_ife_csid_lite_17x_csi2_reg_info, .ipp_reg = NULL, .rdi_reg = { - &cam_ife_csid_lite_17x_rdi_0_reg_offset, - &cam_ife_csid_lite_17x_rdi_1_reg_offset, - &cam_ife_csid_lite_17x_rdi_2_reg_offset, - &cam_ife_csid_lite_17x_rdi_3_reg_offset, + &cam_ife_csid_lite_17x_rdi_0_reg_info, + &cam_ife_csid_lite_17x_rdi_1_reg_info, + &cam_ife_csid_lite_17x_rdi_2_reg_info, + &cam_ife_csid_lite_17x_rdi_3_reg_info, }, - .tpg_reg = &cam_ife_csid_lite_17x_tpg_reg_offset, + .tpg_reg = &cam_ife_csid_lite_17x_tpg_reg_info, }; - #endif /*_CAM_IFE_CSID_LITE17X_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite480.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite480.h index b77f2dfa35..79b5c6ba2d 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite480.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite480.h @@ -1,340 +1,434 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_IFE_CSID_LITE_480_H_ #define _CAM_IFE_CSID_LITE_480_H_ -#include "cam_ife_csid_core.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_hw_ver1.h" -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_480_rdi_0_reg_offset = { - .csid_rdi_irq_status_addr = 0x30, - .csid_rdi_irq_mask_addr = 0x34, - .csid_rdi_irq_clear_addr = 0x38, - .csid_rdi_irq_set_addr = 0x3c, - .csid_rdi_cfg0_addr = 0x200, - .csid_rdi_cfg1_addr = 0x204, - .csid_rdi_ctrl_addr = 0x208, - .csid_rdi_frm_drop_pattern_addr = 0x20c, - .csid_rdi_frm_drop_period_addr = 0x210, - .csid_rdi_irq_subsample_pattern_addr = 0x214, - .csid_rdi_irq_subsample_period_addr = 0x218, - .csid_rdi_rpp_hcrop_addr = 0x21c, - .csid_rdi_rpp_vcrop_addr = 0x220, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x224, - .csid_rdi_rpp_pix_drop_period_addr = 0x228, - .csid_rdi_rpp_line_drop_pattern_addr = 0x22c, - .csid_rdi_rpp_line_drop_period_addr = 0x230, - .csid_rdi_rst_strobes_addr = 0x240, - .csid_rdi_status_addr = 0x250, - .csid_rdi_misr_val0_addr = 0x254, - .csid_rdi_misr_val1_addr = 0x258, - .csid_rdi_misr_val2_addr = 0x25c, - .csid_rdi_misr_val3_addr = 0x260, - .csid_rdi_format_measure_cfg0_addr = 0x270, - .csid_rdi_format_measure_cfg1_addr = 0x274, - .csid_rdi_format_measure0_addr = 0x278, - .csid_rdi_format_measure1_addr = 0x27c, - .csid_rdi_format_measure2_addr = 0x280, - .csid_rdi_timestamp_curr0_sof_addr = 0x290, - .csid_rdi_timestamp_curr1_sof_addr = 0x294, - .csid_rdi_timestamp_prev0_sof_addr = 0x298, - .csid_rdi_timestamp_prev1_sof_addr = 0x29c, - .csid_rdi_timestamp_curr0_eof_addr = 0x2a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x2a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x2a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x2ac, - .csid_rdi_err_recovery_cfg0_addr = 0x2b0, - .csid_rdi_err_recovery_cfg1_addr = 0x2b4, - .csid_rdi_err_recovery_cfg2_addr = 0x2b8, - .csid_rdi_multi_vcdt_cfg0_addr = 0x2bc, - .csid_rdi_byte_cntr_ping_addr = 0x2e0, - .csid_rdi_byte_cntr_pong_addr = 0x2e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_480_rdi_0_reg_info = { + .irq_status_addr = 0x30, + .irq_mask_addr = 0x34, + .irq_clear_addr = 0x38, + .irq_set_addr = 0x3c, + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .ctrl_addr = 0x208, + .frm_drop_pattern_addr = 0x20c, + .frm_drop_period_addr = 0x210, + .irq_subsample_pattern_addr = 0x214, + .irq_subsample_period_addr = 0x218, + .hcrop_addr = 0x21c, + .vcrop_addr = 0x220, + .pix_drop_pattern_addr = 0x224, + .pix_drop_period_addr = 0x228, + .line_drop_pattern_addr = 0x22c, + .line_drop_period_addr = 0x230, + .rst_strobes_addr = 0x240, + .status_addr = 0x250, + .misr_val0_addr = 0x254, + .misr_val1_addr = 0x258, + .misr_val2_addr = 0x25c, + .misr_val3_addr = 0x260, + .format_measure_cfg0_addr = 0x270, + .format_measure_cfg1_addr = 0x274, + .format_measure0_addr = 0x278, + .format_measure1_addr = 0x27c, + .format_measure2_addr = 0x280, + .timestamp_curr0_sof_addr = 0x290, + .timestamp_curr1_sof_addr = 0x294, + .timestamp_prev0_sof_addr = 0x298, + .timestamp_prev1_sof_addr = 0x29c, + .timestamp_curr0_eof_addr = 0x2a0, + .timestamp_curr1_eof_addr = 0x2a4, + .timestamp_prev0_eof_addr = 0x2a8, + .timestamp_prev1_eof_addr = 0x2ac, + .err_recovery_cfg0_addr = 0x2b0, + .err_recovery_cfg1_addr = 0x2b4, + .err_recovery_cfg2_addr = 0x2b8, + .multi_vcdt_cfg0_addr = 0x2bc, + .byte_cntr_ping_addr = 0x2e0, + .byte_cntr_pong_addr = 0x2e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .mipi_pack_supported = 1, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .overflow_ctrl_mode_val = 0x8, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_480_rdi_1_reg_offset = { - .csid_rdi_irq_status_addr = 0x40, - .csid_rdi_irq_mask_addr = 0x44, - .csid_rdi_irq_clear_addr = 0x48, - .csid_rdi_irq_set_addr = 0x4c, - .csid_rdi_cfg0_addr = 0x300, - .csid_rdi_cfg1_addr = 0x304, - .csid_rdi_ctrl_addr = 0x308, - .csid_rdi_frm_drop_pattern_addr = 0x30c, - .csid_rdi_frm_drop_period_addr = 0x310, - .csid_rdi_irq_subsample_pattern_addr = 0x314, - .csid_rdi_irq_subsample_period_addr = 0x318, - .csid_rdi_rpp_hcrop_addr = 0x31c, - .csid_rdi_rpp_vcrop_addr = 0x320, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x324, - .csid_rdi_rpp_pix_drop_period_addr = 0x328, - .csid_rdi_rpp_line_drop_pattern_addr = 0x32c, - .csid_rdi_rpp_line_drop_period_addr = 0x330, - .csid_rdi_rst_strobes_addr = 0x340, - .csid_rdi_status_addr = 0x350, - .csid_rdi_misr_val0_addr = 0x354, - .csid_rdi_misr_val1_addr = 0x358, - .csid_rdi_misr_val2_addr = 0x35c, - .csid_rdi_misr_val3_addr = 0x360, - .csid_rdi_format_measure_cfg0_addr = 0x370, - .csid_rdi_format_measure_cfg1_addr = 0x374, - .csid_rdi_format_measure0_addr = 0x378, - .csid_rdi_format_measure1_addr = 0x37c, - .csid_rdi_format_measure2_addr = 0x380, - .csid_rdi_timestamp_curr0_sof_addr = 0x390, - .csid_rdi_timestamp_curr1_sof_addr = 0x394, - .csid_rdi_timestamp_prev0_sof_addr = 0x398, - .csid_rdi_timestamp_prev1_sof_addr = 0x39c, - .csid_rdi_timestamp_curr0_eof_addr = 0x3a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x3a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x3a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x3ac, - .csid_rdi_err_recovery_cfg0_addr = 0x3b0, - .csid_rdi_err_recovery_cfg1_addr = 0x3b4, - .csid_rdi_err_recovery_cfg2_addr = 0x3b8, - .csid_rdi_multi_vcdt_cfg0_addr = 0x3bc, - .csid_rdi_byte_cntr_ping_addr = 0x3e0, - .csid_rdi_byte_cntr_pong_addr = 0x3e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_480_rdi_1_reg_info = { + .irq_status_addr = 0x40, + .irq_mask_addr = 0x44, + .irq_clear_addr = 0x48, + .irq_set_addr = 0x4c, + .cfg0_addr = 0x300, + .cfg1_addr = 0x304, + .ctrl_addr = 0x308, + .frm_drop_pattern_addr = 0x30c, + .frm_drop_period_addr = 0x310, + .irq_subsample_pattern_addr = 0x314, + .irq_subsample_period_addr = 0x318, + .hcrop_addr = 0x31c, + .vcrop_addr = 0x320, + .pix_drop_pattern_addr = 0x324, + .pix_drop_period_addr = 0x328, + .line_drop_pattern_addr = 0x32c, + .line_drop_period_addr = 0x330, + .rst_strobes_addr = 0x340, + .status_addr = 0x350, + .misr_val0_addr = 0x354, + .misr_val1_addr = 0x358, + .misr_val2_addr = 0x35c, + .misr_val3_addr = 0x360, + .format_measure_cfg0_addr = 0x370, + .format_measure_cfg1_addr = 0x374, + .format_measure0_addr = 0x378, + .format_measure1_addr = 0x37c, + .format_measure2_addr = 0x380, + .timestamp_curr0_sof_addr = 0x390, + .timestamp_curr1_sof_addr = 0x394, + .timestamp_prev0_sof_addr = 0x398, + .timestamp_prev1_sof_addr = 0x39c, + .timestamp_curr0_eof_addr = 0x3a0, + .timestamp_curr1_eof_addr = 0x3a4, + .timestamp_prev0_eof_addr = 0x3a8, + .timestamp_prev1_eof_addr = 0x3ac, + .err_recovery_cfg0_addr = 0x3b0, + .err_recovery_cfg1_addr = 0x3b4, + .err_recovery_cfg2_addr = 0x3b8, + .multi_vcdt_cfg0_addr = 0x3bc, + .byte_cntr_ping_addr = 0x3e0, + .byte_cntr_pong_addr = 0x3e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .packing_fmt_shift_val = 30, + .plain_fmt_shift_val = 10, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .overflow_ctrl_mode_val = 0x8, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_480_rdi_2_reg_offset = { - .csid_rdi_irq_status_addr = 0x50, - .csid_rdi_irq_mask_addr = 0x54, - .csid_rdi_irq_clear_addr = 0x58, - .csid_rdi_irq_set_addr = 0x5c, - .csid_rdi_cfg0_addr = 0x400, - .csid_rdi_cfg1_addr = 0x404, - .csid_rdi_ctrl_addr = 0x408, - .csid_rdi_frm_drop_pattern_addr = 0x40c, - .csid_rdi_frm_drop_period_addr = 0x410, - .csid_rdi_irq_subsample_pattern_addr = 0x414, - .csid_rdi_irq_subsample_period_addr = 0x418, - .csid_rdi_rpp_hcrop_addr = 0x41c, - .csid_rdi_rpp_vcrop_addr = 0x420, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x424, - .csid_rdi_rpp_pix_drop_period_addr = 0x428, - .csid_rdi_rpp_line_drop_pattern_addr = 0x42c, - .csid_rdi_rpp_line_drop_period_addr = 0x430, - .csid_rdi_rst_strobes_addr = 0x440, - .csid_rdi_status_addr = 0x450, - .csid_rdi_misr_val0_addr = 0x454, - .csid_rdi_misr_val1_addr = 0x458, - .csid_rdi_misr_val2_addr = 0x45c, - .csid_rdi_misr_val3_addr = 0x460, - .csid_rdi_format_measure_cfg0_addr = 0x470, - .csid_rdi_format_measure_cfg1_addr = 0x474, - .csid_rdi_format_measure0_addr = 0x478, - .csid_rdi_format_measure1_addr = 0x47c, - .csid_rdi_format_measure2_addr = 0x480, - .csid_rdi_timestamp_curr0_sof_addr = 0x490, - .csid_rdi_timestamp_curr1_sof_addr = 0x494, - .csid_rdi_timestamp_prev0_sof_addr = 0x498, - .csid_rdi_timestamp_prev1_sof_addr = 0x49c, - .csid_rdi_timestamp_curr0_eof_addr = 0x4a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x4a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x4a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x4ac, - .csid_rdi_err_recovery_cfg0_addr = 0x4b0, - .csid_rdi_err_recovery_cfg1_addr = 0x4b4, - .csid_rdi_err_recovery_cfg2_addr = 0x4b8, - .csid_rdi_multi_vcdt_cfg0_addr = 0x4bc, - .csid_rdi_byte_cntr_ping_addr = 0x4e0, - .csid_rdi_byte_cntr_pong_addr = 0x4e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_480_rdi_2_reg_info = { + .irq_status_addr = 0x50, + .irq_mask_addr = 0x54, + .irq_clear_addr = 0x58, + .irq_set_addr = 0x5c, + .cfg0_addr = 0x400, + .cfg1_addr = 0x404, + .ctrl_addr = 0x408, + .frm_drop_pattern_addr = 0x40c, + .frm_drop_period_addr = 0x410, + .irq_subsample_pattern_addr = 0x414, + .irq_subsample_period_addr = 0x418, + .hcrop_addr = 0x41c, + .vcrop_addr = 0x420, + .pix_drop_pattern_addr = 0x424, + .pix_drop_period_addr = 0x428, + .line_drop_pattern_addr = 0x42c, + .line_drop_period_addr = 0x430, + .rst_strobes_addr = 0x440, + .status_addr = 0x450, + .misr_val0_addr = 0x454, + .misr_val1_addr = 0x458, + .misr_val2_addr = 0x45c, + .misr_val3_addr = 0x460, + .format_measure_cfg0_addr = 0x470, + .format_measure_cfg1_addr = 0x474, + .format_measure0_addr = 0x478, + .format_measure1_addr = 0x47c, + .format_measure2_addr = 0x480, + .timestamp_curr0_sof_addr = 0x490, + .timestamp_curr1_sof_addr = 0x494, + .timestamp_prev0_sof_addr = 0x498, + .timestamp_prev1_sof_addr = 0x49c, + .timestamp_curr0_eof_addr = 0x4a0, + .timestamp_curr1_eof_addr = 0x4a4, + .timestamp_prev0_eof_addr = 0x4a8, + .timestamp_prev1_eof_addr = 0x4ac, + .err_recovery_cfg0_addr = 0x4b0, + .err_recovery_cfg1_addr = 0x4b4, + .err_recovery_cfg2_addr = 0x4b8, + .multi_vcdt_cfg0_addr = 0x4bc, + .byte_cntr_ping_addr = 0x4e0, + .byte_cntr_pong_addr = 0x4e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_rdi_reg_offset - cam_ife_csid_lite_480_rdi_3_reg_offset = { - .csid_rdi_irq_status_addr = 0x60, - .csid_rdi_irq_mask_addr = 0x64, - .csid_rdi_irq_clear_addr = 0x68, - .csid_rdi_irq_set_addr = 0x6c, - .csid_rdi_cfg0_addr = 0x500, - .csid_rdi_cfg1_addr = 0x504, - .csid_rdi_ctrl_addr = 0x508, - .csid_rdi_frm_drop_pattern_addr = 0x50c, - .csid_rdi_frm_drop_period_addr = 0x510, - .csid_rdi_irq_subsample_pattern_addr = 0x514, - .csid_rdi_irq_subsample_period_addr = 0x518, - .csid_rdi_rpp_hcrop_addr = 0x51c, - .csid_rdi_rpp_vcrop_addr = 0x520, - .csid_rdi_rpp_pix_drop_pattern_addr = 0x524, - .csid_rdi_rpp_pix_drop_period_addr = 0x528, - .csid_rdi_rpp_line_drop_pattern_addr = 0x52c, - .csid_rdi_rpp_line_drop_period_addr = 0x530, - .csid_rdi_rst_strobes_addr = 0x540, - .csid_rdi_status_addr = 0x550, - .csid_rdi_misr_val0_addr = 0x554, - .csid_rdi_misr_val1_addr = 0x558, - .csid_rdi_misr_val2_addr = 0x55c, - .csid_rdi_misr_val3_addr = 0x560, - .csid_rdi_format_measure_cfg0_addr = 0x570, - .csid_rdi_format_measure_cfg1_addr = 0x574, - .csid_rdi_format_measure0_addr = 0x578, - .csid_rdi_format_measure1_addr = 0x57c, - .csid_rdi_format_measure2_addr = 0x580, - .csid_rdi_timestamp_curr0_sof_addr = 0x590, - .csid_rdi_timestamp_curr1_sof_addr = 0x594, - .csid_rdi_timestamp_prev0_sof_addr = 0x598, - .csid_rdi_timestamp_prev1_sof_addr = 0x59c, - .csid_rdi_timestamp_curr0_eof_addr = 0x5a0, - .csid_rdi_timestamp_curr1_eof_addr = 0x5a4, - .csid_rdi_timestamp_prev0_eof_addr = 0x5a8, - .csid_rdi_timestamp_prev1_eof_addr = 0x5ac, - .csid_rdi_err_recovery_cfg0_addr = 0x5b0, - .csid_rdi_err_recovery_cfg1_addr = 0x5b4, - .csid_rdi_err_recovery_cfg2_addr = 0x5b8, - .csid_rdi_multi_vcdt_cfg0_addr = 0x5bc, - .csid_rdi_byte_cntr_ping_addr = 0x5e0, - .csid_rdi_byte_cntr_pong_addr = 0x5e4, +static struct cam_ife_csid_ver1_path_reg_info + cam_ife_csid_lite_480_rdi_3_reg_info = { + .irq_status_addr = 0x60, + .irq_mask_addr = 0x64, + .irq_clear_addr = 0x68, + .irq_set_addr = 0x6c, + .cfg0_addr = 0x500, + .cfg1_addr = 0x504, + .ctrl_addr = 0x508, + .frm_drop_pattern_addr = 0x50c, + .frm_drop_period_addr = 0x510, + .irq_subsample_pattern_addr = 0x514, + .irq_subsample_period_addr = 0x518, + .hcrop_addr = 0x51c, + .vcrop_addr = 0x520, + .pix_drop_pattern_addr = 0x524, + .pix_drop_period_addr = 0x528, + .line_drop_pattern_addr = 0x52c, + .line_drop_period_addr = 0x530, + .rst_strobes_addr = 0x540, + .status_addr = 0x550, + .misr_val0_addr = 0x554, + .misr_val1_addr = 0x558, + .misr_val2_addr = 0x55c, + .misr_val3_addr = 0x560, + .format_measure_cfg0_addr = 0x570, + .format_measure_cfg1_addr = 0x574, + .format_measure0_addr = 0x578, + .format_measure1_addr = 0x57c, + .format_measure2_addr = 0x580, + .timestamp_curr0_sof_addr = 0x590, + .timestamp_curr1_sof_addr = 0x594, + .timestamp_prev0_sof_addr = 0x598, + .timestamp_prev1_sof_addr = 0x59c, + .timestamp_curr0_eof_addr = 0x5a0, + .timestamp_curr1_eof_addr = 0x5a4, + .timestamp_prev0_eof_addr = 0x5a8, + .timestamp_prev1_eof_addr = 0x5ac, + .err_recovery_cfg0_addr = 0x5b0, + .err_recovery_cfg1_addr = 0x5b4, + .err_recovery_cfg2_addr = 0x5b8, + .multi_vcdt_cfg0_addr = 0x5bc, + .byte_cntr_ping_addr = 0x5e0, + .byte_cntr_pong_addr = 0x5e4, /* configurations */ - .ccif_violation_en = 1, - .overflow_ctrl_en = 1, + .halt_mode_internal = 0, + .halt_mode_global = 1, + .halt_mode_shift = 2, + .halt_frame_boundary = 0, + .resume_frame_boundary = 1, + .halt_immediate = 2, + .halt_cmd_shift = 0, + .crop_v_en_shift_val = 6, + .crop_h_en_shift_val = 5, + .drop_v_en_shift_val = 4, + .drop_h_en_shift_val = 3, + .plain_fmt_shift_val = 10, + .packing_fmt_shift_val = 30, + .ccif_violation_en = 1, + .overflow_ctrl_en = 1, + .timestamp_en_shift_val = 2, + .format_measure_en_shift_val = 1, + .overflow_ctrl_mode_val = 0x8, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, }; -static struct cam_ife_csid_csi2_rx_reg_offset - cam_ife_csid_lite_480_csi2_reg_offset = { - .csid_csi2_rx_irq_status_addr = 0x20, - .csid_csi2_rx_irq_mask_addr = 0x24, - .csid_csi2_rx_irq_clear_addr = 0x28, - .csid_csi2_rx_irq_set_addr = 0x2c, +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_lite_480_csi2_reg_info = { + .irq_status_addr = 0x20, + .irq_mask_addr = 0x24, + .irq_clear_addr = 0x28, + .irq_set_addr = 0x2c, /*CSI2 rx control */ - .csid_csi2_rx_cfg0_addr = 0x100, - .csid_csi2_rx_cfg1_addr = 0x104, - .csid_csi2_rx_capture_ctrl_addr = 0x108, - .csid_csi2_rx_rst_strobes_addr = 0x110, - .csid_csi2_rx_de_scramble_cfg0_addr = 0x114, - .csid_csi2_rx_de_scramble_cfg1_addr = 0x118, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120, - .csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124, - .csid_csi2_rx_captured_short_pkt_0_addr = 0x128, - .csid_csi2_rx_captured_short_pkt_1_addr = 0x12c, - .csid_csi2_rx_captured_long_pkt_0_addr = 0x130, - .csid_csi2_rx_captured_long_pkt_1_addr = 0x134, - .csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138, - .csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c, - .csid_csi2_rx_lane0_misr_addr = 0x150, - .csid_csi2_rx_lane1_misr_addr = 0x154, - .csid_csi2_rx_lane2_misr_addr = 0x158, - .csid_csi2_rx_lane3_misr_addr = 0x15c, - .csid_csi2_rx_total_pkts_rcvd_addr = 0x160, - .csid_csi2_rx_stats_ecc_addr = 0x164, - .csid_csi2_rx_total_crc_err_addr = 0x168, + .cfg0_addr = 0x100, + .cfg1_addr = 0x104, + .capture_ctrl_addr = 0x108, + .rst_strobes_addr = 0x110, + .de_scramble_cfg0_addr = 0x114, + .de_scramble_cfg1_addr = 0x118, + .cap_unmap_long_pkt_hdr_0_addr = 0x120, + .cap_unmap_long_pkt_hdr_1_addr = 0x124, + .captured_short_pkt_0_addr = 0x128, + .captured_short_pkt_1_addr = 0x12c, + .captured_long_pkt_0_addr = 0x130, + .captured_long_pkt_1_addr = 0x134, + .captured_long_pkt_ftr_addr = 0x138, + .captured_cphy_pkt_hdr_addr = 0x13c, + .lane0_misr_addr = 0x150, + .lane1_misr_addr = 0x154, + .lane2_misr_addr = 0x158, + .lane3_misr_addr = 0x15c, + .total_pkts_rcvd_addr = 0x160, + .stats_ecc_addr = 0x164, + .total_crc_err_addr = 0x168, - .csi2_rst_srb_all = 0x3FFF, - .csi2_rst_done_shift_val = 27, - .csi2_irq_mask_all = 0xFFFFFFF, - .csi2_misr_enable_shift_val = 6, - .csi2_vc_mode_shift_val = 2, - .csi2_capture_long_pkt_en_shift = 0, - .csi2_capture_short_pkt_en_shift = 1, - .csi2_capture_cphy_pkt_en_shift = 2, - .csi2_capture_long_pkt_dt_shift = 4, - .csi2_capture_long_pkt_vc_shift = 10, - .csi2_capture_short_pkt_vc_shift = 15, - .csi2_capture_cphy_pkt_dt_shift = 20, - .csi2_capture_cphy_pkt_vc_shift = 26, - .csi2_rx_phy_num_mask = 0x7, + .rst_srb_all = 0x3FFF, + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0x7, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, }; -static struct cam_ife_csid_csi2_tpg_reg_offset - cam_ife_csid_lite_480_tpg_reg_offset = { +static struct cam_ife_csid_ver1_tpg_reg_info + cam_ife_csid_lite_480_tpg_reg_info = { /*CSID TPG control */ - .csid_tpg_ctrl_addr = 0x600, - .csid_tpg_vc_cfg0_addr = 0x604, - .csid_tpg_vc_cfg1_addr = 0x608, - .csid_tpg_lfsr_seed_addr = 0x60c, - .csid_tpg_dt_n_cfg_0_addr = 0x610, - .csid_tpg_dt_n_cfg_1_addr = 0x614, - .csid_tpg_dt_n_cfg_2_addr = 0x618, - .csid_tpg_color_bars_cfg_addr = 0x640, - .csid_tpg_color_box_cfg_addr = 0x644, - .csid_tpg_common_gen_cfg_addr = 0x648, - .csid_tpg_cgen_n_cfg_addr = 0x650, - .csid_tpg_cgen_n_x0_addr = 0x654, - .csid_tpg_cgen_n_x1_addr = 0x658, - .csid_tpg_cgen_n_x2_addr = 0x65c, - .csid_tpg_cgen_n_xy_addr = 0x660, - .csid_tpg_cgen_n_y1_addr = 0x664, - .csid_tpg_cgen_n_y2_addr = 0x668, + .ctrl_addr = 0x600, + .vc_cfg0_addr = 0x604, + .vc_cfg1_addr = 0x608, + .lfsr_seed_addr = 0x60c, + .dt_n_cfg_0_addr = 0x610, + .dt_n_cfg_1_addr = 0x614, + .dt_n_cfg_2_addr = 0x618, + .color_bars_cfg_addr = 0x640, + .color_box_cfg_addr = 0x644, + .common_gen_cfg_addr = 0x648, + .cgen_n_cfg_addr = 0x650, + .cgen_n_x0_addr = 0x654, + .cgen_n_x1_addr = 0x658, + .cgen_n_x2_addr = 0x65c, + .cgen_n_xy_addr = 0x660, + .cgen_n_y1_addr = 0x664, + .cgen_n_y2_addr = 0x668, /* configurations */ - .tpg_dtn_cfg_offset = 0xc, - .tpg_cgen_cfg_offset = 0x20, - .tpg_cpas_ife_reg_offset = 0x28, + .dtn_cfg_offset = 0xc, + .cgen_cfg_offset = 0x20, + .cpas_ife_reg_offset = 0x28, + .hbi = 0x740, + .vbi = 0x3FF, + .lfsr_seed = 0x12345678, + .ctrl_cfg = 0x408007, + .color_bar = 1, + .num_frames = 0, + .line_interleave_mode = 0x1, + .payload_mode = 0x8, + .num_active_lanes_mask = 0x30, + .num_active_dt = 0, + .fmt_shift = 16, + .num_frame_shift = 16, + .width_shift = 16, + .vbi_shift = 12, + .line_interleave_shift = 10, + .num_active_dt_shift = 8, + .color_bar_shift = 5, + .height_shift = 0, + .hbi_shift = 0, }; -static struct cam_ife_csid_common_reg_offset - cam_ife_csid_lite_480_cmn_reg_offset = { - .csid_hw_version_addr = 0x0, - .csid_cfg0_addr = 0x4, - .csid_ctrl_addr = 0x8, - .csid_reset_addr = 0xc, - .csid_rst_strobes_addr = 0x10, - - .csid_test_bus_ctrl_addr = 0x14, - .csid_top_irq_status_addr = 0x70, - .csid_top_irq_mask_addr = 0x74, - .csid_top_irq_clear_addr = 0x78, - .csid_top_irq_set_addr = 0x7c, - .csid_irq_cmd_addr = 0x80, - +static struct cam_ife_csid_ver1_common_reg_info + cam_ife_csid_lite_480_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .ctrl_addr = 0x8, + .reset_addr = 0xc, + .rst_strobes_addr = 0x10, + .test_bus_ctrl_addr = 0x14, + .top_irq_status_addr = 0x70, + .top_irq_mask_addr = 0x74, + .top_irq_clear_addr = 0x78, + .top_irq_set_addr = 0x7c, + .irq_cmd_addr = 0x80, /*configurations */ - .major_version = 4, - .minor_version = 8, - .version_incr = 0, - .num_rdis = 4, - .num_pix = 0, - .num_ppp = 0, - .csid_reg_rst_stb = 1, - .csid_rst_stb = 0x1e, - .csid_rst_stb_sw_all = 0x1f, - .path_rst_stb_all = 0x7f, - .path_rst_done_shift_val = 1, - .path_en_shift_val = 31, - .packing_fmt_shift_val = 30, - .dt_id_shift_val = 27, - .vc_shift_val = 22, - .dt_shift_val = 16, - .fmt_shift_val = 12, - .plain_fmt_shit_val = 10, - .crop_v_en_shift_val = 6, - .crop_h_en_shift_val = 5, - .drop_v_en_shift_val = 4, - .drop_h_en_shift_val = 3, - .crop_shift = 16, - .ipp_irq_mask_all = 0x7FFF, - .rdi_irq_mask_all = 0x7FFF, - .ppp_irq_mask_all = 0xFFFF, - .measure_en_hbi_vbi_cnt_mask = 0xC, - .format_measure_en_val = 1, + .major_version = 4, + .minor_version = 8, + .version_incr = 0, + .num_rdis = 4, + .num_pix = 0, + .num_ppp = 0, + .rst_sw_reg_stb = 1, + .rst_hw_reg_stb = 0x1e, + .rst_sw_hw_reg_stb = 0x1f, + .path_rst_stb_all = 0x7f, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .fmt_shift_val = 12, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .ipp_irq_mask_all = 0x7FFF, + .rdi_irq_mask_all = 0x7FFF, + .ppp_irq_mask_all = 0xFFFF, + .measure_en_hbi_vbi_cnt_mask = 0xC, + .timestamp_strobe_val = 0x2, + .timestamp_stb_sel_shift_val = 0, }; -static struct cam_ife_csid_reg_offset cam_ife_csid_lite_480_reg_offset = { - .cmn_reg = &cam_ife_csid_lite_480_cmn_reg_offset, - .csi2_reg = &cam_ife_csid_lite_480_csi2_reg_offset, +static struct cam_ife_csid_ver1_reg_info cam_ife_csid_lite_480_reg_info = { + .cmn_reg = &cam_ife_csid_lite_480_cmn_reg_info, + .csi2_reg = &cam_ife_csid_lite_480_csi2_reg_info, .ipp_reg = NULL, .ppp_reg = NULL, .rdi_reg = { - &cam_ife_csid_lite_480_rdi_0_reg_offset, - &cam_ife_csid_lite_480_rdi_1_reg_offset, - &cam_ife_csid_lite_480_rdi_2_reg_offset, - &cam_ife_csid_lite_480_rdi_3_reg_offset, + &cam_ife_csid_lite_480_rdi_0_reg_info, + &cam_ife_csid_lite_480_rdi_1_reg_info, + &cam_ife_csid_lite_480_rdi_2_reg_info, + &cam_ife_csid_lite_480_rdi_3_reg_info, }, - .tpg_reg = &cam_ife_csid_lite_480_tpg_reg_offset, + .tpg_reg = &cam_ife_csid_lite_480_tpg_reg_info, }; - -#endif /*_CAM_IFE_CSID_LITE480_H_ */ +#endif /*_CAM_IFE_CSID_LITE_480_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite680.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite680.h new file mode 100644 index 0000000000..cc7ce7e2bb --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite680.h @@ -0,0 +1,585 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_IFE_CSID_LITE_680_H_ +#define _CAM_IFE_CSID_LITE_680_H_ + +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_hw_ver2.h" + +static struct cam_ife_csid_ver2_common_reg_info + cam_ife_csid_lite_680_cmn_reg_info = { + .hw_version_addr = 0x0, + .cfg0_addr = 0x4, + .global_cmd_addr = 0x8, + .reset_cfg_addr = 0xc, + .reset_cmd_addr = 0x10, + .irq_cmd_addr = 0x14, + .rup_aup_cmd_addr = 0x18, + .offline_cmd_addr = 0x1C, + .shdr_master_slave_cfg_addr = 0x20, + .top_irq_status_addr = 0x7C, + .top_irq_mask_addr = 0x80, + .top_irq_clear_addr = 0x84, + .top_irq_set_addr = 0x88, + .buf_done_irq_status_addr = 0x8C, + .buf_done_irq_mask_addr = 0x90, + .buf_done_irq_clear_addr = 0x94, + .buf_done_irq_set_addr = 0x98, + + /*configurations */ + .major_version = 6, + .minor_version = 8, + .version_incr = 0, + .num_rdis = 4, + .num_pix = 1, + .num_ppp = 0, + .rst_done_shift_val = 1, + .path_en_shift_val = 31, + .dt_id_shift_val = 27, + .vc_shift_val = 22, + .dt_shift_val = 16, + .crop_shift_val = 16, + .decode_format_shift_val = 12, + .frame_id_decode_en_shift_val = 1, + .multi_vcdt_vc1_shift_val = 2, + .multi_vcdt_dt1_shift_val = 7, + .multi_vcdt_en_shift_val = 0, + .timestamp_stb_sel_shift_val = 0, + .vfr_en_shift_val = 0, + .early_eof_supported = 1, + .vfr_supported = 1, + .multi_vcdt_supported = 1, + .frame_id_dec_supported = 1, + .measure_en_hbi_vbi_cnt_mask = 0xc, + .measure_pixel_line_en_mask = 0x3, + .crop_pix_start_mask = 0x3fff, + .crop_pix_end_mask = 0xffff, + .crop_line_start_mask = 0x3fff, + .crop_line_end_mask = 0xffff, + .drop_supported = 1, + .ipp_irq_mask_all = 0x7FFF, + .rdi_irq_mask_all = 0x7FFF, + .rst_loc_path_only_val = 0x0, + .rst_loc_complete_csid_val = 0x1, + .rst_mode_frame_boundary_val = 0x0, + .rst_mode_immediate_val = 0x1, + .rst_cmd_hw_reset_complete_val = 0x0, + .rst_cmd_sw_reset_complete_val = 0x1, + .rst_cmd_irq_ctrl_only_val = 0x2, + .timestamp_strobe_val = 0x2, + .top_reset_irq_shift_val = 0, + .global_reset = 1, + .rup_supported = 1, +}; + +static struct cam_ife_csid_csi2_rx_reg_info + cam_ife_csid_lite_680_csi2_reg_info = { + .irq_status_addr = 0x9C, + .irq_mask_addr = 0xA0, + .irq_clear_addr = 0xA4, + .irq_set_addr = 0xA8, + /*CSI2 rx control */ + .cfg0_addr = 0x200, + .cfg1_addr = 0x204, + .capture_ctrl_addr = 0x208, + .rst_strobes_addr = 0x20C, + .cap_unmap_long_pkt_hdr_0_addr = 0x210, + .cap_unmap_long_pkt_hdr_1_addr = 0x214, + .captured_short_pkt_0_addr = 0x218, + .captured_short_pkt_1_addr = 0x21c, + .captured_long_pkt_0_addr = 0x220, + .captured_long_pkt_1_addr = 0x224, + .captured_long_pkt_ftr_addr = 0x228, + .captured_cphy_pkt_hdr_addr = 0x22c, + .lane0_misr_addr = 0x230, + .lane1_misr_addr = 0x234, + .lane2_misr_addr = 0x238, + .lane3_misr_addr = 0x23c, + .total_pkts_rcvd_addr = 0x240, + .stats_ecc_addr = 0x244, + .total_crc_err_addr = 0x248, + .de_scramble_type3_cfg0_addr = 0x24C, + .de_scramble_type3_cfg1_addr = 0x250, + .de_scramble_type2_cfg0_addr = 0x254, + .de_scramble_type2_cfg1_addr = 0x258, + .de_scramble_type1_cfg0_addr = 0x25C, + .de_scramble_type1_cfg1_addr = 0x260, + .de_scramble_type0_cfg0_addr = 0x264, + .de_scramble_type0_cfg1_addr = 0x268, + + .rst_done_shift_val = 27, + .irq_mask_all = 0xFFFFFFF, + .misr_enable_shift_val = 6, + .vc_mode_shift_val = 2, + .capture_long_pkt_en_shift = 0, + .capture_short_pkt_en_shift = 1, + .capture_cphy_pkt_en_shift = 2, + .capture_long_pkt_dt_shift = 4, + .capture_long_pkt_vc_shift = 10, + .capture_short_pkt_vc_shift = 15, + .capture_cphy_pkt_dt_shift = 20, + .capture_cphy_pkt_vc_shift = 26, + .phy_num_mask = 0xf, + .vc_mask = 0x7C00000, + .dt_mask = 0x3f0000, + .wc_mask = 0xffff0000, + .calc_crc_mask = 0xffff, + .expected_crc_mask = 0xffff, + .ecc_correction_shift_en = 0, + .lane_num_shift = 0, + .lane_cfg_shift = 4, + .phy_type_shift = 24, + .phy_num_shift = 20, + .tpg_mux_en_shift = 27, + .phy_bist_shift_en = 7, + .epd_mode_shift_en = 8, + .eotp_shift_en = 9, + .dyn_sensor_switch_shift_en = 10, + .fatal_err_mask = 0x78000, + .part_fatal_err_mask = 0x1801800, + .non_fatal_err_mask = 0x380000, +}; + +static struct cam_ife_csid_ver2_pxl_reg_info + cam_ife_csid_lite_680_ipp_reg_info = { + .irq_status_addr = 0xAC, + .irq_mask_addr = 0xB0, + .irq_clear_addr = 0xB4, + .irq_set_addr = 0xB8, + .cfg0_addr = 0x300, + .ctrl_addr = 0x304, + .debug_clr_cmd_addr = 0x308, + .multi_vcdt_cfg0_addr = 0x30c, + .cfg1_addr = 0x310, + .err_recovery_cfg0_addr = 0x318, + .err_recovery_cfg1_addr = 0x31C, + .err_recovery_cfg2_addr = 0x320, + .camif_frame_cfg_addr = 0x330, + .epoch_irq_cfg_addr = 0x334, + .epoch0_subsample_ptrn_addr = 0x338, + .epoch1_subsample_ptrn_addr = 0x33C, + .debug_camif_1_addr = 0x340, + .debug_camif_0_addr = 0x344, + .debug_halt_status_addr = 0x348, + .debug_misr_val0_addr = 0x34C, + .debug_misr_val1_addr = 0x350, + .debug_misr_val2_addr = 0x354, + .debug_misr_val3_addr = 0x358, + .hcrop_addr = 0x35c, + .vcrop_addr = 0x360, + .pix_drop_pattern_addr = 0x364, + .pix_drop_period_addr = 0x368, + .line_drop_pattern_addr = 0x36C, + .line_drop_period_addr = 0x370, + .frm_drop_pattern_addr = 0x374, + .frm_drop_period_addr = 0x378, + .irq_subsample_pattern_addr = 0x37C, + .irq_subsample_period_addr = 0x380, + .format_measure_cfg0_addr = 0x384, + .format_measure_cfg1_addr = 0x388, + .format_measure0_addr = 0x38C, + .format_measure1_addr = 0x390, + .format_measure2_addr = 0x394, + .timestamp_curr0_sof_addr = 0x398, + .timestamp_curr1_sof_addr = 0x39C, + .timestamp_perv0_sof_addr = 0x3A0, + .timestamp_perv1_sof_addr = 0x3A4, + .timestamp_curr0_eof_addr = 0x3A8, + .timestamp_curr1_eof_addr = 0x3AC, + .timestamp_perv0_eof_addr = 0x3B0, + .timestamp_perv1_eof_addr = 0x3B4, + .batch_period_cfg_addr = 0x3C4, + .batch_stream_id_cfg_addr = 0x3C8, + .epoch0_cfg_batch_id0_addr = 0x3CC, + .epoch1_cfg_batch_id0_addr = 0x3D0, + .epoch0_cfg_batch_id1_addr = 0x3D4, + .epoch1_cfg_batch_id1_addr = 0x3D8, + .epoch0_cfg_batch_id2_addr = 0x3DC, + .epoch1_cfg_batch_id2_addr = 0x3E0, + .epoch0_cfg_batch_id3_addr = 0x3E4, + .epoch1_cfg_batch_id3_addr = 0x3E8, + .epoch0_cfg_batch_id4_addr = 0x3EC, + .epoch1_cfg_batch_id4_addr = 0x3F0, + .epoch0_cfg_batch_id5_addr = 0x3F4, + .epoch1_cfg_batch_id5_addr = 0x3F8, + + /* configurations */ + .start_mode_internal = 0x0, + .start_mode_global = 0x1, + .start_mode_master = 0x2, + .start_mode_slave = 0x3, + .start_mode_shift = 2, + .start_master_sel_val = 0, + .start_master_sel_shift = 4, + .resume_frame_boundary = 1, + .crop_v_en_shift_val = 13, + .crop_h_en_shift_val = 12, + .drop_v_en_shift_val = 11, + .drop_h_en_shift_val = 10, + .pix_store_en_shift_val = 14, + .early_eof_en_shift_val = 16, + .format_measure_en_shift_val = 8, + .timestamp_en_shift_val = 9, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .min_hbi_shift_val = 4, + .start_master_sel_shift_val = 4, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_lite_680_rdi_0_reg_info = { + .irq_status_addr = 0xEC, + .irq_mask_addr = 0xF0, + .irq_clear_addr = 0xF4, + .irq_set_addr = 0xF8, + .cfg0_addr = 0x500, + .ctrl_addr = 0x504, + .debug_clr_cmd_addr = 0x508, + .multi_vcdt_cfg0_addr = 0x50c, + .cfg1_addr = 0x510, + .err_recovery_cfg0_addr = 0x514, + .err_recovery_cfg1_addr = 0x518, + .err_recovery_cfg2_addr = 0x51C, + .debug_byte_cntr_ping_addr = 0x520, + .debug_byte_cntr_pong_addr = 0x524, + .camif_frame_cfg_addr = 0x528, + .epoch_irq_cfg_addr = 0x52C, + .epoch0_subsample_ptrn_addr = 0x530, + .epoch1_subsample_ptrn_addr = 0x534, + .debug_camif_1_addr = 0x538, + .debug_camif_0_addr = 0x53C, + .frm_drop_pattern_addr = 0x540, + .frm_drop_period_addr = 0x540, + .irq_subsample_pattern_addr = 0x548, + .irq_subsample_period_addr = 0x54C, + .hcrop_addr = 0x550, + .vcrop_addr = 0x554, + .pix_drop_pattern_addr = 0x558, + .pix_drop_period_addr = 0x55C, + .line_drop_pattern_addr = 0x560, + .line_drop_period_addr = 0x564, + .debug_halt_status_addr = 0x568, + .debug_misr_val0_addr = 0x570, + .debug_misr_val1_addr = 0x574, + .debug_misr_val2_addr = 0x578, + .debug_misr_val3_addr = 0x57C, + .format_measure_cfg0_addr = 0x580, + .format_measure_cfg1_addr = 0x584, + .format_measure0_addr = 0x588, + .format_measure1_addr = 0x58C, + .format_measure2_addr = 0x590, + .timestamp_curr0_sof_addr = 0x594, + .timestamp_curr1_sof_addr = 0x598, + .timestamp_perv0_sof_addr = 0x59C, + .timestamp_perv1_sof_addr = 0x5A0, + .timestamp_curr0_eof_addr = 0x5A4, + .timestamp_curr1_eof_addr = 0x5A8, + .timestamp_perv0_eof_addr = 0x5AC, + .timestamp_perv1_eof_addr = 0x5B0, + .batch_period_cfg_addr = 0x5BC, + .batch_stream_id_cfg_addr = 0x5C0, + .epoch0_cfg_batch_id0_addr = 0x5C4, + .epoch1_cfg_batch_id0_addr = 0x5C8, + .epoch0_cfg_batch_id1_addr = 0x5CC, + .epoch1_cfg_batch_id1_addr = 0x5D0, + .epoch0_cfg_batch_id2_addr = 0x5D4, + .epoch1_cfg_batch_id2_addr = 0x5D8, + .epoch0_cfg_batch_id3_addr = 0x5DC, + .epoch1_cfg_batch_id3_addr = 0x5E0, + .epoch0_cfg_batch_id4_addr = 0x5E4, + .epoch1_cfg_batch_id4_addr = 0x5E8, + .epoch0_cfg_batch_id5_addr = 0x5EC, + .epoch1_cfg_batch_id5_addr = 0x5F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .mipi_pack_supported = 1, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_lite_680_rdi_1_reg_info = { + .irq_status_addr = 0xFC, + .irq_mask_addr = 0x100, + .irq_clear_addr = 0x104, + .irq_set_addr = 0x108, + .cfg0_addr = 0x600, + .ctrl_addr = 0x604, + .debug_clr_cmd_addr = 0x608, + .multi_vcdt_cfg0_addr = 0x60c, + .cfg1_addr = 0x610, + .err_recovery_cfg0_addr = 0x614, + .err_recovery_cfg1_addr = 0x618, + .err_recovery_cfg2_addr = 0x61C, + .debug_byte_cntr_ping_addr = 0x620, + .debug_byte_cntr_pong_addr = 0x624, + .camif_frame_cfg_addr = 0x628, + .epoch_irq_cfg_addr = 0x62C, + .epoch0_subsample_ptrn_addr = 0x630, + .epoch1_subsample_ptrn_addr = 0x634, + .debug_camif_1_addr = 0x638, + .debug_camif_0_addr = 0x63C, + .frm_drop_pattern_addr = 0x640, + .frm_drop_period_addr = 0x644, + .irq_subsample_pattern_addr = 0x648, + .irq_subsample_period_addr = 0x64C, + .hcrop_addr = 0x650, + .vcrop_addr = 0x654, + .pix_drop_pattern_addr = 0x658, + .pix_drop_period_addr = 0x65C, + .line_drop_pattern_addr = 0x660, + .line_drop_period_addr = 0x664, + .debug_halt_status_addr = 0x66C, + .debug_misr_val0_addr = 0x670, + .debug_misr_val1_addr = 0x674, + .debug_misr_val2_addr = 0x678, + .debug_misr_val3_addr = 0x67C, + .format_measure_cfg0_addr = 0x680, + .format_measure_cfg1_addr = 0x684, + .format_measure0_addr = 0x688, + .format_measure1_addr = 0x68C, + .format_measure2_addr = 0x690, + .timestamp_curr0_sof_addr = 0x694, + .timestamp_curr1_sof_addr = 0x698, + .timestamp_perv0_sof_addr = 0x69C, + .timestamp_perv1_sof_addr = 0x6A0, + .timestamp_curr0_eof_addr = 0x6A4, + .timestamp_curr1_eof_addr = 0x6A8, + .timestamp_perv0_eof_addr = 0x6AC, + .timestamp_perv1_eof_addr = 0x6B0, + .batch_period_cfg_addr = 0x6BC, + .batch_stream_id_cfg_addr = 0x6C0, + .epoch0_cfg_batch_id0_addr = 0x6C4, + .epoch1_cfg_batch_id0_addr = 0x6C8, + .epoch0_cfg_batch_id1_addr = 0x6CC, + .epoch1_cfg_batch_id1_addr = 0x6D0, + .epoch0_cfg_batch_id2_addr = 0x6D4, + .epoch1_cfg_batch_id2_addr = 0x6D8, + .epoch0_cfg_batch_id3_addr = 0x6DC, + .epoch1_cfg_batch_id3_addr = 0x6E0, + .epoch0_cfg_batch_id4_addr = 0x6E4, + .epoch1_cfg_batch_id4_addr = 0x6E8, + .epoch0_cfg_batch_id5_addr = 0x6EC, + .epoch1_cfg_batch_id5_addr = 0x6F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_lite_680_rdi_2_reg_info = { + .irq_status_addr = 0x10C, + .irq_mask_addr = 0x110, + .irq_clear_addr = 0x114, + .irq_set_addr = 0x118, + .cfg0_addr = 0x700, + .ctrl_addr = 0x704, + .debug_clr_cmd_addr = 0x708, + .multi_vcdt_cfg0_addr = 0x70c, + .cfg1_addr = 0x710, + .err_recovery_cfg0_addr = 0x714, + .err_recovery_cfg1_addr = 0x718, + .err_recovery_cfg2_addr = 0x71C, + .debug_byte_cntr_ping_addr = 0x720, + .debug_byte_cntr_pong_addr = 0x724, + .camif_frame_cfg_addr = 0x728, + .epoch_irq_cfg_addr = 0x72C, + .epoch0_subsample_ptrn_addr = 0x730, + .epoch1_subsample_ptrn_addr = 0x734, + .debug_camif_1_addr = 0x738, + .debug_camif_0_addr = 0x73C, + .frm_drop_pattern_addr = 0x740, + .frm_drop_period_addr = 0x744, + .irq_subsample_pattern_addr = 0x748, + .irq_subsample_period_addr = 0x74C, + .hcrop_addr = 0x750, + .vcrop_addr = 0x754, + .pix_drop_pattern_addr = 0x758, + .pix_drop_period_addr = 0x75C, + .line_drop_pattern_addr = 0x760, + .line_drop_period_addr = 0x764, + .debug_halt_status_addr = 0x76C, + .debug_misr_val0_addr = 0x770, + .debug_misr_val1_addr = 0x774, + .debug_misr_val2_addr = 0x778, + .debug_misr_val3_addr = 0x77C, + .format_measure_cfg0_addr = 0x780, + .format_measure_cfg1_addr = 0x784, + .format_measure0_addr = 0x788, + .format_measure1_addr = 0x78C, + .format_measure2_addr = 0x790, + .timestamp_curr0_sof_addr = 0x794, + .timestamp_curr1_sof_addr = 0x798, + .timestamp_perv0_sof_addr = 0x79C, + .timestamp_perv1_sof_addr = 0x7A0, + .timestamp_curr0_eof_addr = 0x7A4, + .timestamp_curr1_eof_addr = 0x7A8, + .timestamp_perv0_eof_addr = 0x7AC, + .timestamp_perv1_eof_addr = 0x7B0, + .batch_period_cfg_addr = 0x7BC, + .batch_stream_id_cfg_addr = 0x7C0, + .epoch0_cfg_batch_id0_addr = 0x7C4, + .epoch1_cfg_batch_id0_addr = 0x7C8, + .epoch0_cfg_batch_id1_addr = 0x7CC, + .epoch1_cfg_batch_id1_addr = 0x7D0, + .epoch0_cfg_batch_id2_addr = 0x7D4, + .epoch1_cfg_batch_id2_addr = 0x7D8, + .epoch0_cfg_batch_id3_addr = 0x7DC, + .epoch1_cfg_batch_id3_addr = 0x7E0, + .epoch0_cfg_batch_id4_addr = 0x7E4, + .epoch1_cfg_batch_id4_addr = 0x7E8, + .epoch0_cfg_batch_id5_addr = 0x7EC, + .epoch1_cfg_batch_id5_addr = 0x7F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, +}; + +static struct cam_ife_csid_ver2_rdi_reg_info + cam_ife_csid_lite_680_rdi_3_reg_info = { + .irq_status_addr = 0x11C, + .irq_mask_addr = 0x120, + .irq_clear_addr = 0x124, + .irq_set_addr = 0x128, + .cfg0_addr = 0x800, + .ctrl_addr = 0x804, + .debug_clr_cmd_addr = 0x808, + .multi_vcdt_cfg0_addr = 0x80c, + .cfg1_addr = 0x810, + .err_recovery_cfg0_addr = 0x814, + .err_recovery_cfg1_addr = 0x818, + .err_recovery_cfg2_addr = 0x81C, + .debug_byte_cntr_ping_addr = 0x820, + .debug_byte_cntr_pong_addr = 0x824, + .camif_frame_cfg_addr = 0x828, + .epoch_irq_cfg_addr = 0x82C, + .epoch0_subsample_ptrn_addr = 0x830, + .epoch1_subsample_ptrn_addr = 0x834, + .debug_camif_1_addr = 0x838, + .debug_camif_0_addr = 0x83C, + .frm_drop_pattern_addr = 0x840, + .frm_drop_period_addr = 0x840, + .irq_subsample_pattern_addr = 0x848, + .irq_subsample_period_addr = 0x84C, + .hcrop_addr = 0x850, + .vcrop_addr = 0x854, + .pix_drop_pattern_addr = 0x858, + .pix_drop_period_addr = 0x85C, + .line_drop_pattern_addr = 0x860, + .line_drop_period_addr = 0x864, + .debug_halt_status_addr = 0x868, + .debug_misr_val0_addr = 0x870, + .debug_misr_val1_addr = 0x874, + .debug_misr_val2_addr = 0x878, + .debug_misr_val3_addr = 0x87C, + .format_measure_cfg0_addr = 0x880, + .format_measure_cfg1_addr = 0x884, + .format_measure0_addr = 0x888, + .format_measure1_addr = 0x88C, + .format_measure2_addr = 0x890, + .timestamp_curr0_sof_addr = 0x894, + .timestamp_curr1_sof_addr = 0x898, + .timestamp_perv0_sof_addr = 0x89C, + .timestamp_perv1_sof_addr = 0x8A0, + .timestamp_curr0_eof_addr = 0x8A4, + .timestamp_curr1_eof_addr = 0x8A8, + .timestamp_perv0_eof_addr = 0x8AC, + .timestamp_perv1_eof_addr = 0x8B0, + .batch_period_cfg_addr = 0x8BC, + .batch_stream_id_cfg_addr = 0x8C0, + .epoch0_cfg_batch_id0_addr = 0x8C4, + .epoch1_cfg_batch_id0_addr = 0x8C8, + .epoch0_cfg_batch_id1_addr = 0x8CC, + .epoch1_cfg_batch_id1_addr = 0x8D0, + .epoch0_cfg_batch_id2_addr = 0x8D4, + .epoch1_cfg_batch_id2_addr = 0x8D8, + .epoch0_cfg_batch_id3_addr = 0x8DC, + .epoch1_cfg_batch_id3_addr = 0x8E0, + .epoch0_cfg_batch_id4_addr = 0x8E4, + .epoch1_cfg_batch_id4_addr = 0x8E8, + .epoch0_cfg_batch_id5_addr = 0x8EC, + .epoch1_cfg_batch_id5_addr = 0x8F0, + /* configurations */ + .resume_frame_boundary = 1, + .overflow_ctrl_en = 1, + .overflow_ctrl_mode_val = 0x8, + .packing_fmt_shift_val = 15, + .plain_alignment_shift_val = 11, + .plain_fmt_shift_val = 12, + .crop_v_en_shift_val = 8, + .crop_h_en_shift_val = 7, + .drop_v_en_shift_val = 6, + .drop_h_en_shift_val = 5, + .early_eof_en_shift_val = 14, + .format_measure_en_shift_val = 3, + .timestamp_en_shift_val = 4, + .debug_byte_cntr_rst_shift_val = 2, + .ccif_violation_en = 1, + .fatal_err_mask = 0x4, + .non_fatal_err_mask = 0x28000, +}; + +static struct cam_ife_csid_ver2_reg_info cam_ife_csid_lite_680_reg_info = { + .cmn_reg = &cam_ife_csid_lite_680_cmn_reg_info, + .csi2_reg = &cam_ife_csid_lite_680_csi2_reg_info, + .ipp_reg = &cam_ife_csid_lite_680_ipp_reg_info, + .ppp_reg = NULL, + .rdi_reg = { + &cam_ife_csid_lite_680_rdi_0_reg_info, + &cam_ife_csid_lite_680_rdi_1_reg_info, + &cam_ife_csid_lite_680_rdi_2_reg_info, + &cam_ife_csid_lite_680_rdi_3_reg_info, + }, + .need_top_cfg = 0, +}; +#endif /* _CAM_IFE_CSID_LITE_680_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite_mod.c similarity index 61% rename from drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.c rename to drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite_mod.c index cf0174d6b6..52451d8d9d 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite_mod.c @@ -1,23 +1,32 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ #include +#include "camera_main.h" +#include "cam_ife_csid_dev.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" #include "cam_ife_csid_lite17x.h" #include "cam_ife_csid_lite480.h" -#include "cam_ife_csid_core.h" -#include "cam_ife_csid_dev.h" -#include "camera_main.h" +#include "cam_ife_csid_lite680.h" #define CAM_CSID_LITE_DRV_NAME "csid_lite" -static struct cam_ife_csid_hw_info cam_ife_csid_lite_17x_hw_info = { - .csid_reg = &cam_ife_csid_lite_17x_reg_offset, +static struct cam_ife_csid_core_info cam_ife_csid_lite_17x_hw_info = { + .csid_reg = &cam_ife_csid_lite_17x_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, }; -static struct cam_ife_csid_hw_info cam_ife_csid_lite_480_hw_info = { - .csid_reg = &cam_ife_csid_lite_480_reg_offset, +static struct cam_ife_csid_core_info cam_ife_csid_lite_480_hw_info = { + .csid_reg = &cam_ife_csid_lite_480_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid_lite_680_hw_info = { + .csid_reg = &cam_ife_csid_lite_680_reg_info, + .sw_version = CAM_IFE_CSID_VER_2_0, }; static const struct of_device_id cam_ife_csid_lite_dt_match[] = { @@ -29,6 +38,10 @@ static const struct of_device_id cam_ife_csid_lite_dt_match[] = { .compatible = "qcom,csid-lite175", .data = &cam_ife_csid_lite_17x_hw_info, }, + { + .compatible = "qcom,csid-lite165", + .data = &cam_ife_csid_lite_17x_hw_info, + }, { .compatible = "qcom,csid-lite480", .data = &cam_ife_csid_lite_480_hw_info, @@ -37,8 +50,13 @@ static const struct of_device_id cam_ife_csid_lite_dt_match[] = { .compatible = "qcom,csid-lite580", .data = &cam_ife_csid_lite_480_hw_info, }, + { + .compatible = "qcom,csid-lite680", + .data = &cam_ife_csid_lite_680_hw_info, + }, {} }; + MODULE_DEVICE_TABLE(of, cam_ife_csid_lite_dt_match); struct platform_driver cam_ife_csid_lite_driver = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_mod.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_mod.c new file mode 100644 index 0000000000..75136bb8e2 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_mod.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "cam_ife_csid_dev.h" +#include "camera_main.h" +#include "cam_ife_csid_common.h" +#include "cam_ife_csid_hw_ver1.h" +#include "cam_ife_csid_hw_ver2.h" +#include "cam_ife_csid170.h" +#include "cam_ife_csid170_200.h" +#include "cam_ife_csid175.h" +#include "cam_ife_csid175_200.h" +#include "cam_ife_csid480.h" +#include "cam_ife_csid580.h" +#include "cam_ife_csid680.h" + +#define CAM_CSID_DRV_NAME "csid" + +static struct cam_ife_csid_core_info cam_ife_csid170_hw_info = { + .csid_reg = &cam_ife_csid_170_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid170_200_hw_info = { + .csid_reg = &cam_ife_csid_170_200_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid175_hw_info = { + .csid_reg = &cam_ife_csid_175_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid175_200_hw_info = { + .csid_reg = &cam_ife_csid_175_200_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid165_204_hw_info = { + .csid_reg = &cam_ife_csid_175_200_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid480_hw_info = { + .csid_reg = &cam_ife_csid_480_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid580_hw_info = { + .csid_reg = &cam_ife_csid_580_reg_info, + .sw_version = CAM_IFE_CSID_VER_1_0, +}; + +static struct cam_ife_csid_core_info cam_ife_csid680_hw_info = { + .csid_reg = &cam_ife_csid_680_reg_info, + .sw_version = CAM_IFE_CSID_VER_2_0, +}; + +static const struct of_device_id cam_ife_csid_dt_match[] = { + + { + .compatible = "qcom,csid170", + .data = &cam_ife_csid170_hw_info, + }, + { + .compatible = "qcom,csid170_200", + .data = &cam_ife_csid170_200_hw_info, + }, + { + .compatible = "qcom,csid175", + .data = &cam_ife_csid175_hw_info, + }, + { + .compatible = "qcom,csid175_200", + .data = &cam_ife_csid175_200_hw_info, + }, + { + .compatible = "qcom,csid165_204", + .data = &cam_ife_csid165_204_hw_info, + }, + { + .compatible = "qcom,csid480", + .data = &cam_ife_csid480_hw_info, + }, + { + .compatible = "qcom,csid580", + .data = &cam_ife_csid580_hw_info, + }, + { + .compatible = "qcom,csid680", + .data = &cam_ife_csid680_hw_info, + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, cam_ife_csid_dt_match); + +struct platform_driver cam_ife_csid_driver = { + .probe = cam_ife_csid_probe, + .remove = cam_ife_csid_remove, + .driver = { + .name = CAM_CSID_DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = cam_ife_csid_dt_match, + .suppress_bind_attrs = true, + }, +}; + +int cam_ife_csid_init_module(void) +{ + return platform_driver_register(&cam_ife_csid_driver); +} + +void cam_ife_csid_exit_module(void) +{ + platform_driver_unregister(&cam_ife_csid_driver); +} + +MODULE_DESCRIPTION("CAM IFE_CSID driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index 795ab14d24..5303f9853e 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -11,9 +11,19 @@ /* MAX IFE CSID instance */ #define CAM_IFE_CSID_HW_NUM_MAX 7 -#define CAM_IFE_CSID_RDI_MAX 4 #define CAM_IFE_CSID_UDI_MAX 3 +/** + * enum cam_ife_csid_input_core_type - Specify the csid input core + */ +enum cam_ife_csid_input_core_type { + CAM_IFE_CSID_INPUT_CORE_NONE, + CAM_IFE_CSID_INPUT_CORE_IFE, + CAM_IFE_CSID_INPUT_CORE_SFE_IFE, + CAM_IFE_CSID_INPUT_CORE_SFE, + CAM_IFE_CSID_INPUT_CORE_CUST_IFE, +}; + /** * enum cam_ife_pix_path_res_id - Specify the csid patch */ @@ -22,6 +32,7 @@ enum cam_ife_pix_path_res_id { CAM_IFE_PIX_PATH_RES_RDI_1, CAM_IFE_PIX_PATH_RES_RDI_2, CAM_IFE_PIX_PATH_RES_RDI_3, + CAM_IFE_PIX_PATH_RES_RDI_4, CAM_IFE_PIX_PATH_RES_IPP, CAM_IFE_PIX_PATH_RES_PPP, CAM_IFE_PIX_PATH_RES_UDI_0, @@ -43,13 +54,15 @@ enum cam_ife_cid_res_id { /** * struct cam_ife_csid_hw_caps- get the CSID hw capability - * @num_rdis: number of rdis supported by CSID HW device - * @num_pix: number of pxl paths supported by CSID HW device - * @num_ppp: number of ppp paths supported by CSID HW device - * @major_version : major version - * @minor_version: minor version - * @version_incr: version increment - * @is_lite: is the ife_csid lite + * @num_rdis: number of rdis supported by CSID HW device + * @num_pix: number of pxl paths supported by CSID HW device + * @num_ppp: number of ppp paths supported by CSID HW device + * @major_version : major version + * @minor_version: minor version + * @version_incr: version increment + * @is_lite: is the ife_csid lite + * @global_reset_en: flag to indicate if global reset is enabled + * @rup_en: flag to indicate if rup is on csid side */ struct cam_ife_csid_hw_caps { uint32_t num_rdis; @@ -59,6 +72,8 @@ struct cam_ife_csid_hw_caps { uint32_t minor_version; uint32_t version_incr; bool is_lite; + bool global_reset_en; + bool rup_en; }; struct cam_isp_out_port_generic_info { @@ -115,26 +130,33 @@ struct cam_isp_in_port_generic_info { /** * struct cam_csid_hw_reserve_resource- hw reserve - * @res_type : Reource type CID or PATH - * if type is CID, then res_id is not required, - * if type is path then res id need to be filled - * @res_id : Resource id to be reserved - * @in_port : Input port resource info - * @out_port: Output port resource info, used for RDI path only - * @sync_mode: Sync mode - * Sync mode could be master, slave or none - * @master_idx: Master device index to be configured in the slave path - * for master path, this value is not required. - * only slave need to configure the master index value - * @cid: cid (DT_ID) value for path, this is applicable for CSID path - * reserve - * @node_res : Reserved resource structure pointer - * @crop_enable : Flag to indicate CSID crop enable - * @drop_enable : Flag to indicate CSID drop enable - * @priv: private data to be sent in callback - * @event_cb: CSID event callback to hw manager - * @phy_sel: Phy selection number if tpg is enabled from userspace - * @can_use_lite: Flag to indicate if current call qualifies for acquire lite + * @res_type : Reource type CID or PATH + * if type is CID, then res_id is not required, + * if type is path then res id need to be filled + * @res_id : Resource id to be reserved + * @in_port : Input port resource info + * @out_port: Output port resource info, used for RDI path only + * @sync_mode: Sync mode + * Sync mode could be master, slave or none + * @master_idx: Master device index to be configured in the + * slave path + * for master path, this value is not required. + * only slave need to configure the master index value + * @dual_core_id: In case of dual csid, core id of another hw + * reserve + * @node_res : Reserved resource structure pointer + * @crop_enable : Flag to indicate CSID crop enable + * @drop_enable : Flag to indicate CSID drop enable + * @sfe_inline_shdr: Flag to indicate if sfe is inline shdr + * @need_top_cfg: Flag to indicate if top cfg is needed + * @tasklet: Tasklet to schedule bottom halves + * @buf_done_controller: IRQ controller for buf done for version 680 hw + * @cdm_ops: CDM Ops + * @event_cb: Callback function to hw mgr in case of hw events + * @cb_priv: Private pointer to return to callback + * @phy_sel: Phy selection number if tpg is enabled from userspace + * @can_use_lite: Flag to indicate if current call qualifies for + * acquire lite * */ struct cam_csid_hw_reserve_resource_args { @@ -144,14 +166,19 @@ struct cam_csid_hw_reserve_resource_args { struct cam_isp_out_port_generic_info *out_port; enum cam_isp_hw_sync_mode sync_mode; uint32_t master_idx; - uint32_t cid; + uint32_t dual_core_id; struct cam_isp_resource_node *node_res; bool crop_enable; bool drop_enable; - void *priv; + bool sfe_inline_shdr; + bool need_top_cfg; + void *tasklet; + void *buf_done_controller; + void *cdm_ops; cam_hw_mgr_event_cb_func event_cb; uint32_t phy_sel; bool can_use_lite; + void *cb_priv; }; /** @@ -240,19 +267,6 @@ struct cam_csid_get_time_stamp_args { uint64_t boot_timestamp; }; -/** - * enum cam_ife_csid_cmd_type - Specify the csid command - */ -enum cam_ife_csid_cmd_type { - CAM_IFE_CSID_CMD_GET_TIME_STAMP, - CAM_IFE_CSID_SET_CSID_DEBUG, - CAM_IFE_CSID_SOF_IRQ_DEBUG, - CAM_IFE_CSID_SET_CONFIG, - CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, - CAM_IFE_CSID_LOG_ACQUIRE_DATA, - CAM_IFE_CSID_CMD_MAX, -}; - /** * cam_ife_csid_hw_init() * @@ -276,9 +290,11 @@ struct cam_ife_csid_clock_update_args { /* * struct cam_ife_csid_qcfa_update_args: * + * @res: Res node pointer * @qcfa_binning: QCFA binning supported */ struct cam_ife_csid_qcfa_update_args { + struct cam_isp_resource_node *res; uint32_t qcfa_binning; }; @@ -294,14 +310,50 @@ struct cam_ife_csid_epd_update_args { /* * struct cam_ife_sensor_dim_update_args: * - * @ppp_path: expected ppp path configuration - * @ipp_path: expected ipp path configuration - * @rdi_path: expected rdi path configuration + * @res: Resource for which data is updated + * @sensor_data: expected path configuration */ struct cam_ife_sensor_dimension_update_args { - struct cam_isp_sensor_dimension ppp_path; - struct cam_isp_sensor_dimension ipp_path; - struct cam_isp_sensor_dimension rdi_path[CAM_IFE_CSID_RDI_MAX]; + struct cam_isp_resource_node *res; + struct cam_isp_sensor_dimension sensor_data; }; +/* struct cam_ife_csid_top_config_args: + * + * @input_core_type: Input core type for CSID + * @core_idx: Core idx for out core + * @is_sfe_offline: flag to indicate if sfe is offline + */ +struct cam_ife_csid_top_config_args { + uint32_t input_core_type; + uint32_t core_idx; + bool is_sfe_offline; +}; + +/* + * struct cam_ife_csid_dual_sync_args: + * + * @sync_mode: Sync mode for dual csid master/slave + * @dual_core_id: Core idx for another core in case of dual isp + * + */ +struct cam_ife_csid_dual_sync_args { + enum cam_isp_hw_sync_mode sync_mode; + uint32_t dual_core_id; +}; + +/* + * struct cam_ife_csid_get_cmd_reg_update: + * + * @cmd: cmd buf update args + * @node_res: Node res pointer + * @num_res: Num of resources + * @is_mup_update: Flag to indicate if mup update + */ +struct cam_ife_csid_reg_update_args { + struct cam_isp_hw_cmd_buf_update cmd; + struct cam_isp_resource_node *res[CAM_IFE_PIX_PATH_RES_MAX]; + uint32_t num_res; + bool is_mup_update; +}; #endif /* _CAM_CSID_HW_INTF_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index 21c0e0e27a..293bb1d2d8 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -18,6 +18,7 @@ #define CAM_ISP_HW_DUMP_TAG_MAX_LEN 32 /* Max isp hw pid values number */ #define CAM_ISP_HW_MAX_PID_VAL 4 + /* * struct cam_isp_timestamp: * @@ -136,6 +137,15 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_DISABLE_UBWC_COMP, CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG, CAM_ISP_HW_CMD_QUERY_BUS_CAP, + CAM_IFE_CSID_CMD_GET_TIME_STAMP, + CAM_IFE_CSID_SET_CSID_DEBUG, + CAM_IFE_CSID_SOF_IRQ_DEBUG, + CAM_IFE_CSID_SET_CONFIG, + CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, + CAM_IFE_CSID_LOG_ACQUIRE_DATA, + CAM_IFE_CSID_TOP_CONFIG, + CAM_IFE_CSID_PROGRAM_OFFLINE_CMD, + CAM_IFE_CSID_SET_DUAL_SYNC_CONFIG, CAM_ISP_HW_CMD_MAX, }; @@ -289,13 +299,18 @@ struct cam_isp_hw_get_res_for_mid { /* * struct cam_isp_hw_get_cmd_update: * - * @Brief: Get cmd buffer update for different CMD types + * @Brief: Get cmd buffer update for different CMD types * * @res: Resource node * @cmd_type: Command type for which to get update - * @cdm_id: CDM id + * @cdm_id : CDM id + * @cmd: Command buffer information + * @res: Resource node + * @cmd_type: Command type for which to get update * @cmd: Command buffer information * @use_scratch_cfg: To indicate if it's scratch buffer config + * @trigger_cdm_en: Flag to indicate if cdm is trigger + * @is_mup_update: Flag to indicate if MUP is updated * */ struct cam_isp_hw_get_cmd_update { @@ -310,6 +325,7 @@ struct cam_isp_hw_get_cmd_update { struct cam_isp_hw_get_wm_update *rm_update; }; bool trigger_cdm_en; + bool is_mup_update; }; /* diff --git a/drivers/camera_main.c b/drivers/camera_main.c index f59be8dbe1..5c345fd7da 100644 --- a/drivers/camera_main.c +++ b/drivers/camera_main.c @@ -89,7 +89,7 @@ static const struct camera_submodule_component camera_tfe[] = { static const struct camera_submodule_component camera_isp[] = { #ifdef CONFIG_SPECTRA_ISP {&cam_top_tpg_init_module, &cam_top_tpg_exit_module}, - {&cam_ife_csid17x_init_module, &cam_ife_csid17x_exit_module}, + {&cam_ife_csid_init_module, &cam_ife_csid_exit_module}, {&cam_ife_csid_lite_init_module, &cam_ife_csid_lite_exit_module}, {&cam_vfe_init_module, &cam_vfe_exit_module}, #ifdef CONFIG_SPECTRA_SFE diff --git a/drivers/camera_main.h b/drivers/camera_main.h index 4cc6a6ae3e..7ee4a71d70 100644 --- a/drivers/camera_main.h +++ b/drivers/camera_main.h @@ -16,7 +16,7 @@ extern struct platform_driver cam_cdm_intf_driver; extern struct platform_driver cam_hw_cdm_driver; #ifdef CONFIG_SPECTRA_ISP extern struct platform_driver cam_top_tpg_driver; -extern struct platform_driver cam_ife_csid17x_driver; +extern struct platform_driver cam_ife_csid_driver; extern struct platform_driver cam_ife_csid_lite_driver; extern struct platform_driver cam_vfe_driver; #ifdef CONFIG_SPECTRA_SFE @@ -89,7 +89,7 @@ static struct platform_driver *const cam_component_drivers[] = { #endif #ifdef CONFIG_SPECTRA_ISP &cam_top_tpg_driver, - &cam_ife_csid17x_driver, + &cam_ife_csid_driver, &cam_ife_csid_lite_driver, &cam_vfe_driver, #ifdef CONFIG_SPECTRA_SFE diff --git a/include/uapi/camera/media/cam_isp.h b/include/uapi/camera/media/cam_isp.h index 848bab7f22..f6273fae3e 100644 --- a/include/uapi/camera/media/cam_isp.h +++ b/include/uapi/camera/media/cam_isp.h @@ -163,7 +163,7 @@ #define CAM_ISP_ACQ_CUSTOM_PRIMARY 1 #define CAM_ISP_ACQ_CUSTOM_SECONDARY 2 -#define CAM_IFE_CSID_RDI_MAX 4 +#define CAM_IFE_CSID_RDI_MAX 5 /* Feature Flag indicators */ #define CAM_ISP_PARAM_FETCH_SECURITY_MODE BIT(0)