Merge "msm: camera: isp: Add support of SFE HW for v780" into camera-kernel.lnx.5.0

This commit is contained in:
Savita Patted
2021-07-23 19:19:20 -07:00
committed by Gerrit - the friendly Code Review server
9 changed files with 1818 additions and 386 deletions

View File

@@ -10,7 +10,8 @@
#include "cam_sfe_bus_rd.h"
#include "cam_sfe_bus_wr.h"
static struct cam_sfe_top_module_desc sfe_mod_desc[] = {
static struct cam_sfe_top_module_desc sfe_680_mod_desc[] = {
{
.id = 0,
.desc = "CRC_ZSL",
@@ -109,7 +110,7 @@ static struct cam_sfe_top_module_desc sfe_mod_desc[] = {
},
};
static struct cam_sfe_wr_client_desc sfe_wr_client_desc[] = {
static struct cam_sfe_wr_client_desc sfe_680_wr_client_desc[] = {
{
.wm_id = 0,
.desc = "REMOSAIC",
@@ -130,7 +131,8 @@ static struct cam_sfe_wr_client_desc sfe_wr_client_desc[] = {
.wm_id = 4,
.desc = "STATS_BE1",
},
{ .wm_id = 5,
{
.wm_id = 5,
.desc = "STATS_BHIST1",
},
{
@@ -163,6 +165,132 @@ static struct cam_sfe_wr_client_desc sfe_wr_client_desc[] = {
},
};
static struct cam_sfe_mode sfe_680_mode[] = {
{
.value = 0x1,
.desc = "FS Mode",
},
{
.value = 0x3,
.desc = "Offline Mode",
},
{
.value = 0x4,
.desc = "sHDR mode",
},
};
static struct cam_sfe_top_err_irq_desc sfe_680_top_irq_err_desc[] = {
{
.bitmask = BIT(14),
.err_name = "PP_VIOLATION",
.desc = "CCIF protocol violation within any of the modules in pixel pipeline",
},
{
.bitmask = BIT(15),
.err_name = "DIAG_VIOLATION",
.desc = "HBI is less than the minimum required HBI",
},
{
.bitmask = BIT(16),
.err_name = "LINE_SMOOTH_VIOLATION",
.desc = "Line Smoothner IRQ fire",
},
};
static struct cam_sfe_top_debug_info sfe680_clc_dbg_module_info[CAM_SFE_TOP_DBG_REG_MAX][8] = {
SFE_DBG_INFO_ARRAY_4bit(
"test_bus_reserved",
"test_bus_reserved",
"test_bus_reserved",
"test_bus_reserved",
"test_bus_reserved",
"test_bus_reserved",
"test_bus_reserved",
"test_bus_reserved"
),
SFE_DBG_INFO_ARRAY_4bit(
"zsl_throttle",
"crc_zsl",
"comp_zsl",
"crc_prev",
"hdrc_ch2",
"hdrc_ch1",
"hdrc_ch0",
"stats_bhist_ch0"
),
SFE_DBG_INFO_ARRAY_4bit(
"stats_bg_ch0",
"lsc_ch0",
"crc_ch0",
"ccif_2x2_to_2x1",
"decomp",
"msb_align_ch0",
"bpc_pdpc",
"ch0_gain"
),
SFE_DBG_INFO_ARRAY_4bit(
"bhist_ch1",
"stats_bg_ch1",
"lsc_ch1",
"crc_ch1",
"msb_align_ch1",
"ch1_gain",
"bhist_ch2",
"stats_bg_ch2"
),
SFE_DBG_INFO_ARRAY_4bit(
"lsc_ch2",
"crc_ch2",
"msb_align_ch2",
"ch2_gain",
"lcr_throttle",
"lcr",
"demux_fetch2",
"demux_fetch1"
),
SFE_DBG_INFO_ARRAY_4bit(
"demux_fetch0",
"csid_ccif",
"RDI4",
"RDI3",
"RDI2",
"RDI1",
"RDI0",
"bhist2_bus_wr"
),
SFE_DBG_INFO_ARRAY_4bit(
"bg2_bus_wr",
"bhist1_bus_wr",
"bg1_bus_wr",
"bhist0_bus_wr",
"bg0_bus_wr",
"lcr_bus_wr",
"zsl_bus_wr",
"sfe_op_throttle"
),
SFE_DBG_INFO_ARRAY_4bit(
"line_smooth",
"pp",
"bus_conv_ch2",
"bus_conv_ch1",
"bus_conv_ch0",
"fe_ch2",
"fe_ch1",
"fe_ch0"
),
SFE_DBG_INFO_ARRAY_4bit(
"rdi4",
"rdi3",
"rdi2",
"rdi1",
"rdi0",
"pixel",
"reserved",
"reserved"
),
};
static struct cam_sfe_top_common_reg_offset sfe680_top_commong_reg = {
.hw_version = 0x00000000,
.hw_capability = 0x00000004,
@@ -170,7 +298,7 @@ static struct cam_sfe_top_common_reg_offset sfe680_top_commong_reg = {
.core_cgc_ctrl = 0x00000010,
.ahb_clk_ovd = 0x00000014,
.core_cfg = 0x00000018,
.violation_status = 0x00000030,
.ipp_violation_status = 0x00000030,
.diag_config = 0x00000034,
.diag_sensor_status_0 = 0x00000038,
.diag_sensor_status_1 = 0x0000003C,
@@ -184,6 +312,13 @@ static struct cam_sfe_top_common_reg_offset sfe680_top_commong_reg = {
.sfe_op_throttle_cfg = 0x000000C4,
.bus_overflow_status = 0x00000868,
.top_debug_cfg = 0x0000007C,
.lcr_supported = true,
.ir_supported = false,
.qcfa_only = true,
.num_sfe_mode = ARRAY_SIZE(sfe_680_mode),
.sfe_mode = sfe_680_mode,
.ipp_violation_mask = 0x4000,
.num_debug_registers = 12,
.top_debug = {
0x0000004C,
0x00000050,
@@ -202,12 +337,12 @@ static struct cam_sfe_top_common_reg_offset sfe680_top_commong_reg = {
static struct cam_sfe_modules_common_reg_offset sfe680_modules_common_reg = {
.demux_module_cfg = 0x00003060,
.demux_qcfa_cfg = 0x00003064,
.demux_xcfa_cfg = 0x00003064,
.demux_hdr_cfg = 0x00003074,
.demux_lcr_sel = 0x00003078,
.hdrc_remo_mod_cfg = 0x00005860,
.hdrc_remo_qcfa_bin_cfg = 0x00005A78,
.qcfa_hdrc_remo_out_mux_cfg = 0x00005A74,
.hdrc_remo_xcfa_bin_cfg = 0x00005A78,
.xcfa_hdrc_remo_out_mux_cfg = 0x00005A74,
};
static struct cam_sfe_top_common_reg_data sfe_680_top_common_reg_data = {
@@ -257,8 +392,8 @@ static struct cam_sfe_top_hw_info sfe680_top_hw_info = {
.common_reg = &sfe680_top_commong_reg,
.modules_hw_info = &sfe680_modules_common_reg,
.common_reg_data = &sfe_680_top_common_reg_data,
.module_desc = sfe_mod_desc,
.wr_client_desc = sfe_wr_client_desc,
.ipp_module_desc = sfe_680_mod_desc,
.wr_client_desc = sfe_680_wr_client_desc,
.pix_reg_data = &sfe_680_pix_reg_data,
.rdi_reg_data[0] = &sfe_680_rdi0_reg_data,
.rdi_reg_data[1] = &sfe_680_rdi1_reg_data,
@@ -274,6 +409,10 @@ static struct cam_sfe_top_hw_info sfe680_top_hw_info = {
CAM_SFE_RDI_VER_1_0,
CAM_SFE_RDI_VER_1_0,
},
.num_top_errors = ARRAY_SIZE(sfe_680_top_irq_err_desc),
.top_err_desc = sfe_680_top_irq_err_desc,
.num_clc_module = 9,
.clc_dbg_mod_info = &sfe680_clc_dbg_module_info,
};
static struct cam_irq_register_set sfe680_bus_rd_irq_reg[1] = {
@@ -1050,7 +1189,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
};
static struct cam_irq_register_set sfe680_top_irq_reg_set[1] = {
{
{
.mask_reg_offset = 0x00000020,
.clear_reg_offset = 0x00000024,
.status_reg_offset = 0x00000028,

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,7 @@
#include "cam_sfe_core.h"
#include "cam_sfe_soc.h"
#include "cam_sfe680.h"
#include "cam_sfe780.h"
#include "cam_debug_util.h"
#include "camera_main.h"
@@ -225,6 +226,10 @@ static const struct of_device_id cam_sfe_dt_match[] = {
.compatible = "qcom,sfe680",
.data = &cam_sfe680_hw_info,
},
{
.compatible = "qcom,sfe780",
.data = &cam_sfe780_hw_info,
},
{}
};
MODULE_DEVICE_TABLE(of, cam_sfe_dt_match);

View File

@@ -47,6 +47,7 @@ struct cam_sfe_bus_rd_reg_offset_bus_client {
uint32_t unpacker_cfg;
uint32_t latency_buf_allocation;
uint32_t system_cache_cfg;
uint32_t addr_cfg;
};
/*

View File

@@ -196,6 +196,7 @@ struct cam_sfe_bus_wr_priv {
void *tasklet_info;
uint32_t num_cons_err;
struct cam_sfe_constraint_error_info *constraint_error_list;
struct cam_sfe_bus_sfe_out_hw_info *sfe_out_hw_info;
};
static int cam_sfe_bus_wr_process_cmd(
@@ -215,6 +216,7 @@ static bool cam_sfe_bus_can_be_secure(uint32_t out_type)
case CAM_SFE_BUS_SFE_OUT_RDI2:
case CAM_SFE_BUS_SFE_OUT_RDI3:
case CAM_SFE_BUS_SFE_OUT_RDI4:
case CAM_SFE_BUS_SFE_OUT_IR:
return true;
case CAM_SFE_BUS_SFE_OUT_LCR:
case CAM_SFE_BUS_SFE_OUT_BE_0:
@@ -223,6 +225,9 @@ static bool cam_sfe_bus_can_be_secure(uint32_t out_type)
case CAM_SFE_BUS_SFE_OUT_BHIST_1:
case CAM_SFE_BUS_SFE_OUT_BE_2:
case CAM_SFE_BUS_SFE_OUT_BHIST_2:
case CAM_SFE_BUS_SFE_OUT_BAYER_RS_0:
case CAM_SFE_BUS_SFE_OUT_BAYER_RS_1:
case CAM_SFE_BUS_SFE_OUT_BAYER_RS_2:
default:
return false;
}
@@ -258,6 +263,14 @@ static enum cam_sfe_bus_sfe_out_type
return CAM_SFE_BUS_SFE_OUT_BHIST_2;
case CAM_ISP_SFE_OUT_RES_LCR:
return CAM_SFE_BUS_SFE_OUT_LCR;
case CAM_ISP_SFE_OUT_RES_IR:
return CAM_SFE_BUS_SFE_OUT_IR;
case CAM_ISP_SFE_OUT_BAYER_RS_STATS_0:
return CAM_SFE_BUS_SFE_OUT_BAYER_RS_0;
case CAM_ISP_SFE_OUT_BAYER_RS_STATS_1:
return CAM_SFE_BUS_SFE_OUT_BAYER_RS_1;
case CAM_ISP_SFE_OUT_BAYER_RS_STATS_2:
return CAM_SFE_BUS_SFE_OUT_BAYER_RS_2;
default:
return CAM_SFE_BUS_SFE_OUT_MAX;
}
@@ -268,52 +281,90 @@ static int cam_sfe_bus_get_comp_sfe_out_res_id_list(
{
int count = 0;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_RDI0))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI0)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_0;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_RDI1))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI1)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_1;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_RDI2))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI2)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_2;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_RDI3))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI3)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_3;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_RDI4))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RDI4)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_RDI_4;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_RAW_DUMP))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_RAW_DUMP)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_RAW_DUMP;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_BE_0))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BE_0)))
out_list[count++] = CAM_ISP_SFE_OUT_BE_STATS_0;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_BHIST_0))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BHIST_0)))
out_list[count++] = CAM_ISP_SFE_OUT_BHIST_STATS_0;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_BE_1))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BE_1)))
out_list[count++] = CAM_ISP_SFE_OUT_BE_STATS_1;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_BHIST_1))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BHIST_1)))
out_list[count++] = CAM_ISP_SFE_OUT_BHIST_STATS_1;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_BE_2))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BE_2)))
out_list[count++] = CAM_ISP_SFE_OUT_BE_STATS_2;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_BHIST_2))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BHIST_2)))
out_list[count++] = CAM_ISP_SFE_OUT_BHIST_STATS_2;
if (comp_mask & (1 << CAM_SFE_BUS_SFE_OUT_LCR))
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_LCR)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_LCR;
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_IR)))
out_list[count++] = CAM_ISP_SFE_OUT_RES_IR;
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BAYER_RS_0)))
out_list[count++] = CAM_ISP_SFE_OUT_BAYER_RS_STATS_0;
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BAYER_RS_1)))
out_list[count++] = CAM_ISP_SFE_OUT_BAYER_RS_STATS_1;
if (comp_mask & (BIT(CAM_SFE_BUS_SFE_OUT_BAYER_RS_2)))
out_list[count++] = CAM_ISP_SFE_OUT_BAYER_RS_STATS_2;
*num_out = count;
return 0;
}
static enum cam_sfe_bus_wr_packer_format
cam_sfe_bus_get_packer_fmt(uint32_t out_fmt, int wm_index)
bool cam_sfe_is_mipi_pcking_needed(
struct cam_sfe_bus_wr_priv *bus_priv,
int wm_index)
{
int i;
for(i = 0; i < bus_priv->num_out; i++)
{
if (((wm_index == bus_priv->sfe_out_hw_info[i].wm_idx) &&
(bus_priv->sfe_out_hw_info[i].sfe_out_type ==
CAM_SFE_BUS_SFE_OUT_RAW_DUMP)) ||
((wm_index == bus_priv->sfe_out_hw_info[i].wm_idx) &&
(bus_priv->sfe_out_hw_info[i].sfe_out_type ==
CAM_SFE_BUS_SFE_OUT_IR)))
return true;
}
return false;
}
static enum cam_sfe_bus_wr_packer_format
cam_sfe_bus_get_packer_fmt(
struct cam_sfe_bus_wr_priv *bus_priv,
uint32_t out_fmt,
int wm_index)
{
bool is_mipi_packing =
cam_sfe_is_mipi_pcking_needed(bus_priv, wm_index);
switch (out_fmt) {
case CAM_FORMAT_MIPI_RAW_6:
case CAM_FORMAT_MIPI_RAW_8:
@@ -323,22 +374,22 @@ static enum cam_sfe_bus_wr_packer_format
case CAM_FORMAT_PD8:
return PACKER_FMT_PLAIN_128;
case CAM_FORMAT_MIPI_RAW_10:
if (wm_index == 0)
if (is_mipi_packing)
return PACKER_FMT_MIPI10;
else
return PACKER_FMT_PLAIN_128;
case CAM_FORMAT_MIPI_RAW_12:
if (wm_index == 0)
if (is_mipi_packing)
return PACKER_FMT_MIPI12;
else
return PACKER_FMT_PLAIN_128;
case CAM_FORMAT_MIPI_RAW_14:
if (wm_index == 0)
if (is_mipi_packing)
return PACKER_FMT_MIPI14;
else
return PACKER_FMT_PLAIN_128;
case CAM_FORMAT_MIPI_RAW_20:
if (wm_index == 0)
if (is_mipi_packing)
return PACKER_FMT_MIPI20;
else
return PACKER_FMT_PLAIN_128;
@@ -604,8 +655,8 @@ static int cam_sfe_bus_acquire_wm(
rsrc_data = wm_res->res_priv;
wm_idx = rsrc_data->index;
rsrc_data->format = out_port_info->format;
rsrc_data->pack_fmt = cam_sfe_bus_get_packer_fmt(rsrc_data->format,
wm_idx);
rsrc_data->pack_fmt = cam_sfe_bus_get_packer_fmt(bus_priv,
rsrc_data->format, wm_idx);
rsrc_data->width = out_port_info->width;
rsrc_data->height = out_port_info->height;
@@ -647,8 +698,22 @@ static int cam_sfe_bus_acquire_wm(
default:
break;
}
} else if (sfe_out_res_id == CAM_SFE_BUS_SFE_OUT_IR) {
rsrc_data->stride = rsrc_data->width;
rsrc_data->en_cfg = 0x1;
switch (rsrc_data->format) {
case CAM_FORMAT_PLAIN16_10:
case CAM_FORMAT_PLAIN16_12:
case CAM_FORMAT_PLAIN16_14:
case CAM_FORMAT_PLAIN16_16:
/* LSB aligned */
rsrc_data->pack_fmt |= 0x20;
break;
default:
break;
}
} else if ((sfe_out_res_id >= CAM_SFE_BUS_SFE_OUT_BE_0) &&
(sfe_out_res_id <= CAM_SFE_BUS_SFE_OUT_BHIST_2)) {
(sfe_out_res_id <= CAM_SFE_BUS_SFE_OUT_BAYER_RS_2)) {
rsrc_data->width = 0;
rsrc_data->height = 0;
rsrc_data->stride = 1;
@@ -3001,6 +3066,7 @@ int cam_sfe_bus_wr_init(
bus_priv->common_data.sfe_irq_controller = sfe_irq_controller;
bus_priv->num_cons_err = hw_info->num_cons_err;
bus_priv->constraint_error_list = hw_info->constraint_error_list;
bus_priv->sfe_out_hw_info = hw_info->sfe_out_hw_info;
rc = cam_cpas_get_cpas_hw_version(&bus_priv->common_data.hw_version);
if (rc) {
CAM_ERR(CAM_SFE, "Failed to get hw_version rc:%d", rc);

View File

@@ -9,7 +9,7 @@
#include "cam_sfe_bus.h"
#define CAM_SFE_BUS_WR_MAX_CLIENTS 13
#define CAM_SFE_BUS_WR_MAX_CLIENTS 16
#define CAM_SFE_BUS_WR_MAX_SUB_GRPS 6
#define CAM_SFE_BUS_CONS_ERR_MAX 32
@@ -51,6 +51,10 @@ enum cam_sfe_bus_sfe_out_type {
CAM_SFE_BUS_SFE_OUT_BHIST_1,
CAM_SFE_BUS_SFE_OUT_BE_2,
CAM_SFE_BUS_SFE_OUT_BHIST_2,
CAM_SFE_BUS_SFE_OUT_BAYER_RS_0,
CAM_SFE_BUS_SFE_OUT_BAYER_RS_1,
CAM_SFE_BUS_SFE_OUT_BAYER_RS_2,
CAM_SFE_BUS_SFE_OUT_IR,
CAM_SFE_BUS_SFE_OUT_MAX,
};
@@ -107,6 +111,7 @@ struct cam_sfe_bus_reg_offset_bus_client {
uint32_t framedrop_period;
uint32_t framedrop_pattern;
uint32_t system_cache_cfg;
uint32_t addr_cfg;
uint32_t addr_status_0;
uint32_t addr_status_1;
uint32_t addr_status_2;

View File

@@ -56,8 +56,10 @@ struct cam_sfe_top_priv {
void *priv_per_stream;
spinlock_t spin_lock;
cam_hw_mgr_event_cb_func event_cb;
struct cam_sfe_top_module_desc *module_desc;
struct cam_sfe_wr_client_desc *wr_client_desc;
struct cam_sfe_top_hw_info *hw_info;
uint32_t num_clc_module;
struct cam_sfe_top_debug_info (*clc_dbg_mod_info)[CAM_SFE_TOP_DBG_REG_MAX][8];
};
struct cam_sfe_path_data {
@@ -73,320 +75,6 @@ struct cam_sfe_path_data {
int sof_eof_handle;
};
struct cam_sfe_top_debug_info {
uint32_t shift;
char *clc_name;
};
static const struct cam_sfe_top_debug_info sfe_dbg_list[][8] = {
{
{
.shift = 0,
.clc_name = "test_bus_reserved"
},
{
.shift = 4,
.clc_name = "test_bus_reserved"
},
{
.shift = 8,
.clc_name = "test_bus_reserved"
},
{
.shift = 12,
.clc_name = "test_bus_reserved"
},
{
.shift = 16,
.clc_name = "test_bus_reserved"
},
{
.shift = 20,
.clc_name = "test_bus_reserved"
},
{
.shift = 24,
.clc_name = "test_bus_reserved"
},
{
.shift = 28,
.clc_name = "test_bus_reserved"
},
},
{
{
.shift = 0,
.clc_name = "zsl_throttle"
},
{
.shift = 4,
.clc_name = "crc_zsl"
},
{
.shift = 8,
.clc_name = "comp_zsl"
},
{
.shift = 12,
.clc_name = "crc_prev"
},
{
.shift = 16,
.clc_name = "hdrc_ch2"
},
{
.shift = 20,
.clc_name = "hdrc_ch1"
},
{
.shift = 24,
.clc_name = "hdrc_ch0"
},
{
.shift = 28,
.clc_name = "stats_bhist_ch0"
},
},
{
{
.shift = 0,
.clc_name = "stats_bg_ch0"
},
{
.shift = 4,
.clc_name = "lsc_ch0"
},
{
.shift = 8,
.clc_name = "crc_ch0"
},
{
.shift = 12,
.clc_name = "ccif_2x2_to_2x1"
},
{
.shift = 16,
.clc_name = "decomp"
},
{
.shift = 20,
.clc_name = "msb_align_ch0"
},
{
.shift = 24,
.clc_name = "bpc_pdpc"
},
{
.shift = 28,
.clc_name = "ch0_gain"
},
},
{
{
.shift = 0,
.clc_name = "bhist_ch1"
},
{
.shift = 4,
.clc_name = "stats_bg_ch1"
},
{
.shift = 8,
.clc_name = "lsc_ch1"
},
{
.shift = 12,
.clc_name = "crc_ch1"
},
{
.shift = 16,
.clc_name = "msb_align_ch1"
},
{
.shift = 20,
.clc_name = "ch1_gain"
},
{
.shift = 24,
.clc_name = "bhist_ch2"
},
{
.shift = 28,
.clc_name = "stats_bg_ch2"
},
},
{
{
.shift = 0,
.clc_name = "lsc_ch2"
},
{
.shift = 4,
.clc_name = "crc_ch2"
},
{
.shift = 8,
.clc_name = "msb_align_ch2"
},
{
.shift = 12,
.clc_name = "ch2_gain"
},
{
.shift = 16,
.clc_name = "lcr_throttle"
},
{
.shift = 20,
.clc_name = "lcr"
},
{
.shift = 24,
.clc_name = "demux_fetch2"
},
{
.shift = 28,
.clc_name = "demux_fetch1"
},
},
{
{
.shift = 0,
.clc_name = "demux_fetch0"
},
{
.shift = 4,
.clc_name = "csid_ccif"
},
{
.shift = 8,
.clc_name = "RDI4"
},
{
.shift = 12,
.clc_name = "RDI3"
},
{
.shift = 16,
.clc_name = "RDI2"
},
{
.shift = 20,
.clc_name = "RDI1"
},
{
.shift = 24,
.clc_name = "RDI0"
},
{
.shift = 28,
.clc_name = "bhist2_bus_wr"
},
},
{
{
.shift = 0,
.clc_name = "bg2_bus_wr"
},
{
.shift = 4,
.clc_name = "bhist1_bus_wr"
},
{
.shift = 8,
.clc_name = "bg1_bus_wr"
},
{
.shift = 12,
.clc_name = "bhist0_bus_wr"
},
{
.shift = 16,
.clc_name = "bg0_bus_wr"
},
{
.shift = 20,
.clc_name = "lcr_bus_wr"
},
{
.shift = 24,
.clc_name = "zsl_bus_wr"
},
{
.shift = 28,
.clc_name = "sfe_op_throttle"
},
},
{
{
.shift = 0,
.clc_name = "line_smooth"
},
{
.shift = 4,
.clc_name = "pp"
},
{
.shift = 8,
.clc_name = "bus_conv_ch2"
},
{
.shift = 12,
.clc_name = "bus_conv_ch1"
},
{
.shift = 16,
.clc_name = "bus_conv_ch0"
},
{
.shift = 20,
.clc_name = "fe_ch2"
},
{
.shift = 24,
.clc_name = "fe_ch1"
},
{
.shift = 28,
.clc_name = "fe_ch0"
},
},
{
{
.shift = 0,
.clc_name = "rdi4"
},
{
.shift = 4,
.clc_name = "rdi3"
},
{
.shift = 8,
.clc_name = "rdi2"
},
{
.shift = 12,
.clc_name = "rdi1"
},
{
.shift = 16,
.clc_name = "rdi0"
},
{
.shift = 20,
.clc_name = "pixel"
},
{
.shift = 24,
.clc_name = "reserved"
},
{
.shift = 28,
.clc_name = "reserved"
},
},
};
static int cam_sfe_top_apply_clock_start_stop(struct cam_sfe_top_priv *top_priv);
static int cam_sfe_top_apply_bw_start_stop(struct cam_sfe_top_priv *top_priv);
@@ -480,7 +168,7 @@ end:
static void cam_sfe_top_check_module_status(
uint32_t num_reg, uint32_t *reg_val,
const struct cam_sfe_top_debug_info status_list[][8])
struct cam_sfe_top_debug_info (*status_list)[CAM_SFE_TOP_DBG_REG_MAX][8])
{
bool found = false;
uint32_t i, j, val = 0;
@@ -496,13 +184,13 @@ static void cam_sfe_top_check_module_status(
continue;
for (j = 0; j < 8; j++) {
val = reg_val[i] >> status_list[i][j].shift;
val = reg_val[i] >> (*status_list)[i][j].shift;
val &= 0xF;
if (val == 0 || val == 5)
continue;
CAM_INFO_BUF(CAM_SFE, log_buf, 1024, &len, "%s [I:%u V:%u R:%u]",
status_list[i][j].clc_name,
(*status_list)[i][j].clc_name,
((val >> 2) & 1), ((val >> 1) & 1), (val & 1));
found = true;
}
@@ -522,11 +210,12 @@ static void cam_sfe_top_print_debug_reg_info(
struct cam_sfe_top_common_data *common_data;
struct cam_hw_soc_info *soc_info;
uint32_t *reg_val = NULL;
uint32_t num_reg = CAM_SFE_TOP_DBG_REG_MAX;
uint32_t num_reg = 0;
int i = 0, j;
common_data = &top_priv->common_data;
soc_info = common_data->soc_info;
num_reg = common_data->common_reg->num_debug_registers;
mem_base = soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base;
reg_val = kcalloc(num_reg, sizeof(uint32_t), GFP_KERNEL);
if (!reg_val)
@@ -542,8 +231,8 @@ static void cam_sfe_top_print_debug_reg_info(
(i - 2), reg_val[i - 2], (i - 1), reg_val[i - 1]);
}
cam_sfe_top_check_module_status(num_reg,
reg_val, sfe_dbg_list);
cam_sfe_top_check_module_status(top_priv->num_clc_module,
reg_val, top_priv->clc_dbg_mod_info);
kfree(reg_val);
}
@@ -1483,8 +1172,8 @@ static int cam_sfe_top_handle_err_irq_top_half(
cam_isp_hw_get_timestamp(&evt_payload->ts);
evt_payload->violation_status =
cam_io_r(base +
top_priv->common_data.common_reg->violation_status);
cam_io_r(base +
top_priv->common_data.common_reg->ipp_violation_status);
th_payload->evt_payload_priv = evt_payload;
@@ -1580,6 +1269,45 @@ void cam_sfe_top_sel_frame_counter(
}
}
static void cam_sfe_top_print_ipp_violation_info(
struct cam_sfe_top_priv *top_priv,
uint32_t violation_status)
{
struct cam_sfe_top_common_data *common_data = &top_priv->common_data;
struct cam_hw_soc_info *soc_info = common_data->soc_info;
uint32_t val = violation_status;
CAM_INFO(CAM_SFE, "SFE[%u] IPP Violation status 0x%x",
soc_info->index, val);
if (top_priv->hw_info->ipp_module_desc)
CAM_ERR(CAM_SFE, "SFE[%u] IPP Violation Module id: [%u %s]",
soc_info->index,
top_priv->hw_info->ipp_module_desc[val].id,
top_priv->hw_info->ipp_module_desc[val].desc);
}
static void cam_sfe_top_print_top_irq_error(
struct cam_sfe_top_priv *top_priv,
uint32_t irq_status,
uint32_t violation_status)
{
uint32_t i = 0;
for (i = 0; i < top_priv->hw_info->num_top_errors; i++) {
if (top_priv->hw_info->top_err_desc[i].bitmask &
irq_status) {
CAM_ERR(CAM_SFE, "%s %s",
top_priv->hw_info->top_err_desc[i].err_name,
top_priv->hw_info->top_err_desc[i].desc);
}
}
if (irq_status & top_priv->common_data.common_reg->ipp_violation_mask)
cam_sfe_top_print_ipp_violation_info(top_priv, violation_status);
}
static int cam_sfe_top_handle_err_irq_bottom_half(
void *handler_priv, void *evt_payload_priv)
@@ -1602,24 +1330,11 @@ static int cam_sfe_top_handle_err_irq_bottom_half(
if (irq_status[0] &
top_priv->common_data.common_reg_data->error_irq_mask) {
if (irq_status[0] & 0x4000)
CAM_ERR(CAM_SFE, "PP VIOLATION");
if (irq_status[0] & 0x8000)
CAM_ERR(CAM_SFE, "DIAG VIOLATION");
if (irq_status[0] & 0x10000)
CAM_ERR(CAM_SFE, "LINE SMOOTH VIOLATION");
viol_sts = payload->violation_status;
CAM_INFO(CAM_SFE, "Violation status 0x%x",
viol_sts);
if (top_priv->module_desc)
CAM_ERR(CAM_ISP, "SFE:%u Violating Module [ID: %d name: %s]",
evt_info.hw_idx,
top_priv->module_desc[viol_sts].id,
top_priv->module_desc[viol_sts].desc);
cam_sfe_top_print_top_irq_error(top_priv,
irq_status[0], viol_sts);
evt_info.err_type = CAM_SFE_IRQ_STATUS_VIOLATION;
cam_sfe_top_print_debug_reg_info(top_priv);
if (top_priv->event_cb)
@@ -1705,6 +1420,7 @@ int cam_sfe_top_start(
struct cam_sfe_soc_private *soc_private = NULL;
uint32_t error_mask[CAM_SFE_IRQ_REGISTERS_MAX];
uint32_t sof_eof_mask[CAM_SFE_IRQ_REGISTERS_MAX];
uint32_t core_cfg = 0, i = 0;
if (!priv || !start_args) {
CAM_ERR(CAM_SFE, "Invalid args");
@@ -1744,11 +1460,22 @@ int cam_sfe_top_start(
return rc;
}
core_cfg = cam_io_r_mb(path_data->mem_base +
path_data->common_reg->core_cfg);
/* core cfg updated via CDM */
CAM_DBG(CAM_SFE, "SFE HW [%u] core_cfg: 0x%x",
hw_info->soc_info.index,
cam_io_r_mb(path_data->mem_base +
path_data->common_reg->core_cfg));
hw_info->soc_info.index, core_cfg);
for (i = 0; i < path_data->common_reg->num_sfe_mode; i++) {
if (path_data->common_reg->sfe_mode[i].value ==
core_cfg) {
CAM_DBG(CAM_SFE, "SFE HW [%u] : [%s]",
hw_info->soc_info.index,
path_data->common_reg->sfe_mode[i].desc);
break;
}
}
/* Enable debug cfg registers */
cam_io_w(path_data->common_reg_data->top_debug_cfg_en,
@@ -2055,10 +1782,10 @@ int cam_sfe_top_init(
top_priv->common_data.hw_intf = hw_intf;
top_priv->common_data.common_reg =
sfe_top_hw_info->common_reg;
top_priv->common_data.common_reg_data =
sfe_top_hw_info->common_reg_data;
top_priv->module_desc = sfe_top_hw_info->module_desc;
top_priv->wr_client_desc = sfe_top_hw_info->wr_client_desc;
top_priv->hw_info = sfe_top_hw_info;
top_priv->wr_client_desc = sfe_top_hw_info->wr_client_desc;
top_priv->num_clc_module = sfe_top_hw_info->num_clc_module;
top_priv->clc_dbg_mod_info = sfe_top_hw_info->clc_dbg_mod_info;
top_priv->sfe_debug_cfg = 0;
sfe_top->hw_ops.process_cmd = cam_sfe_top_process_cmd;

View File

@@ -19,7 +19,7 @@
#define CAM_SHIFT_TOP_CORE_CFG_OPS_MODE_CFG 1
#define CAM_SHIFT_TOP_CORE_CFG_FS_MODE_CFG 0
#define CAM_SFE_TOP_DBG_REG_MAX 12
#define CAM_SFE_TOP_DBG_REG_MAX 18
struct cam_sfe_top_module_desc {
uint32_t id;
@@ -31,11 +31,28 @@ struct cam_sfe_top {
struct cam_hw_ops hw_ops;
};
struct cam_sfe_mode {
int value;
char *desc;
};
struct cam_sfe_wr_client_desc {
uint32_t wm_id;
uint8_t *desc;
};
struct cam_sfe_top_err_irq_desc {
uint32_t bitmask;
char *err_name;
char *desc;
};
struct cam_sfe_top_debug_info {
uint32_t shift;
char *clc_name;
};
struct cam_sfe_top_common_reg_offset {
uint32_t hw_version;
uint32_t hw_capability;
@@ -43,7 +60,7 @@ struct cam_sfe_top_common_reg_offset {
uint32_t core_cgc_ctrl;
uint32_t ahb_clk_ovd;
uint32_t core_cfg;
uint32_t violation_status;
uint32_t ipp_violation_status;
uint32_t diag_config;
uint32_t diag_sensor_status_0;
uint32_t diag_sensor_status_1;
@@ -55,19 +72,28 @@ struct cam_sfe_top_common_reg_offset {
uint32_t lcr_throttle_cfg;
uint32_t hdr_throttle_cfg;
uint32_t sfe_op_throttle_cfg;
uint32_t irc_throttle_cfg;
uint32_t sfe_single_dual_cfg;
uint32_t bus_overflow_status;
uint32_t top_debug_cfg;
bool lcr_supported;
bool ir_supported;
bool qcfa_only;
struct cam_sfe_mode *sfe_mode;
uint32_t num_sfe_mode;
uint32_t ipp_violation_mask;
uint32_t num_debug_registers;
uint32_t top_debug[CAM_SFE_TOP_DBG_REG_MAX];
};
struct cam_sfe_modules_common_reg_offset {
uint32_t demux_module_cfg;
uint32_t demux_qcfa_cfg;
uint32_t demux_xcfa_cfg;
uint32_t demux_hdr_cfg;
uint32_t demux_lcr_sel;
uint32_t hdrc_remo_mod_cfg;
uint32_t hdrc_remo_qcfa_bin_cfg;
uint32_t qcfa_hdrc_remo_out_mux_cfg;
uint32_t hdrc_remo_xcfa_bin_cfg;
uint32_t xcfa_hdrc_remo_out_mux_cfg;
};
struct cam_sfe_top_common_reg_data {
@@ -87,13 +113,17 @@ struct cam_sfe_top_hw_info {
struct cam_sfe_top_common_reg_offset *common_reg;
struct cam_sfe_modules_common_reg_offset *modules_hw_info;
struct cam_sfe_top_common_reg_data *common_reg_data;
struct cam_sfe_top_module_desc *module_desc;
struct cam_sfe_top_module_desc *ipp_module_desc;
struct cam_sfe_wr_client_desc *wr_client_desc;
struct cam_sfe_path_common_reg_data *pix_reg_data;
struct cam_sfe_path_common_reg_data *rdi_reg_data[CAM_SFE_RDI_MAX];
uint32_t num_inputs;
uint32_t input_type[
CAM_SFE_TOP_IN_PORT_MAX];
uint32_t num_top_errors;
struct cam_sfe_top_err_irq_desc *top_err_desc;
uint32_t num_clc_module;
struct cam_sfe_top_debug_info (*clc_dbg_mod_info)[CAM_SFE_TOP_DBG_REG_MAX][8];
};
int cam_sfe_top_init(
@@ -108,4 +138,18 @@ int cam_sfe_top_deinit(
uint32_t hw_version,
struct cam_sfe_top **sfe_top);
#define SFE_DBG_INFO(shift_val, name) {.shift = shift_val, .clc_name = name}
#define SFE_DBG_INFO_ARRAY_4bit(name1, name2, name3, name4, name5, name6, name7, name8) \
{ \
SFE_DBG_INFO(0, name1), \
SFE_DBG_INFO(4, name2), \
SFE_DBG_INFO(8, name3), \
SFE_DBG_INFO(12, name4), \
SFE_DBG_INFO(16, name5), \
SFE_DBG_INFO(20, name6), \
SFE_DBG_INFO(24, name7), \
SFE_DBG_INFO(28, name8), \
}
#endif /* _CAM_SFE_TOP_H_ */

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef __UAPI_CAM_ISP_SFE_H__
@@ -22,8 +22,12 @@
#define CAM_ISP_SFE_OUT_BHIST_STATS_2 (CAM_ISP_SFE_OUT_RES_BASE + 10)
#define CAM_ISP_SFE_OUT_RES_LCR (CAM_ISP_SFE_OUT_RES_BASE + 11)
#define CAM_ISP_SFE_OUT_RES_RAW_DUMP (CAM_ISP_SFE_OUT_RES_BASE + 12)
#define CAM_ISP_SFE_OUT_RES_IR (CAM_ISP_SFE_OUT_RES_BASE + 13)
#define CAM_ISP_SFE_OUT_BAYER_RS_STATS_0 (CAM_ISP_SFE_OUT_RES_BASE + 14)
#define CAM_ISP_SFE_OUT_BAYER_RS_STATS_1 (CAM_ISP_SFE_OUT_RES_BASE + 15)
#define CAM_ISP_SFE_OUT_BAYER_RS_STATS_2 (CAM_ISP_SFE_OUT_RES_BASE + 16)
#define CAM_ISP_SFE_OUT_RES_MAX (CAM_ISP_SFE_OUT_RES_BASE + 13)
#define CAM_ISP_SFE_OUT_RES_MAX (CAM_ISP_SFE_OUT_RES_BASE + 17)
/* SFE input port resource type */
#define CAM_ISP_SFE_IN_RES_BASE 0x5000