瀏覽代碼

msm: camera: isp: Add infra to select CC testbus for 780 sfe

Add support to enable and select Context Controller testbus
for debugging. We can select testbus using debugfs setting
to print sfe debug info in case of SFE HW errors.

Use the below setting to enable and select context controller
testbus.

Testbus1 :
adb shell "echo 0x100 > /sys/kernel/debug/camera_ife/sfe_debug".

Testbus2 :
adb shell "echo 0x200 > /sys/kernel/debug/camera_ife/sfe_debug".

CRs-Fixed: 2948116
Change-Id: Ifdc58751794e2a7b190e5e9972cace500ec9bd91
Signed-off-by: Chandan Kumar Jha <[email protected]>
Chandan Kumar Jha 4 年之前
父節點
當前提交
8629b24906

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe680.h

@@ -319,6 +319,7 @@ static struct cam_sfe_top_common_reg_offset  sfe680_top_commong_reg  = {
 	.sfe_mode                      = sfe_680_mode,
 	.ipp_violation_mask            = 0x4000,
 	.num_debug_registers           = 12,
+	.top_cc_test_bus_supported     = false,
 	.top_debug = {
 		0x0000004C,
 		0x00000050,

+ 165 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe780.h

@@ -203,6 +203,149 @@ static struct cam_sfe_wr_client_desc sfe_780_wr_client_desc[] = {
 	},
 };
 
+static struct cam_sfe_top_cc_testbus_info
+		sfe780_testbus1_info[] = {
+	{
+		.mask = BIT(0),
+		.shift = 0,
+		.clc_name = "sw_xcfa_mode_sel",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 1,
+		.clc_name = "bus_rd_line_done_rdi2",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 2,
+		.clc_name = "bus_rd_line_done_rdi1",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 3,
+		.clc_name = "bus_rd_line_done_rdi0",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 4,
+		.clc_name = "down_count_flag",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 5,
+		.clc_name = "rdi2_upcount_flag",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 6,
+		.clc_name = "rdi1_upcount_flag",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 7,
+		.clc_name = "rdi0_upcount_flag",
+	},
+	{
+		.mask = BIT(0) | BIT(1),
+		.shift = 8,
+		.clc_name = "rdi2_meta_pkts",
+	},
+	{
+		.mask = BIT(0) | BIT(1),
+		.shift = 10,
+		.clc_name = "rdi1_meta_pkts",
+	},
+	{
+		.mask = BIT(0) | BIT(1),
+		.shift = 12,
+		.clc_name = "rdi0_meta_pkts",
+	},
+	{
+		.mask = BIT(1) | BIT(2) | BIT(3),
+		.shift = 14,
+		.clc_name = "i_rdi2_sample",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 18,
+		.clc_name = "i_rdi2_vld",
+	},
+	{
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
+		.shift = 19,
+		.clc_name = "i_rdi1_sample",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 23,
+		.clc_name = "i_rdi1_vld",
+	},
+	{
+		.mask = BIT(1) | BIT(2) | BIT(3),
+		.shift = 24,
+		.clc_name = "i_rdi0_sample",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 28,
+		.clc_name = "i_rdi0_vl",
+	},
+};
+
+static struct cam_sfe_top_cc_testbus_info
+		sfe780_testbus2_info[] = {
+	{
+		.mask = BIT(0),
+		.shift = 0,
+		.clc_name = "meta_consumed_ipp",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 1,
+		.clc_name = "meta_consumed_bus_rd",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 2,
+		.clc_name = "o_rdi0_overflow_rdy",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 3,
+		.clc_name = "sw_single_dual_en",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 4,
+		.clc_name = "rd_rup_cond",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 5,
+		.clc_name = "bus_rd_rdy",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 6,
+		.clc_name = "next_state",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 7,
+		.clc_name = "curr_state",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 8,
+		.clc_name = "xcfa_mode_cpy",
+	},
+	{
+		.mask = BIT(0),
+		.shift = 9,
+		.clc_name = "rd_kick_off_cond",
+	},
+};
+
 static struct cam_sfe_mode sfe_780_mode[] = {
 	{
 		.value = 0x0,
@@ -389,12 +532,15 @@ static struct cam_sfe_top_common_reg_offset  sfe780_top_commong_reg  = {
 	.sfe_single_dual_cfg           = 0x000000D0,
 	.bus_overflow_status           = 0x00000868,
 	.top_debug_cfg                 = 0x0000007C,
+	.top_cc_test_bus_ctrl          = 0x000001F0,
 	.lcr_supported                 = false,
 	.ir_supported                  = true,
 	.qcfa_only                     = false,
 	.num_sfe_mode                  = ARRAY_SIZE(sfe_780_mode),
 	.sfe_mode                      = sfe_780_mode,
 	.ipp_violation_mask            = 0x4000,
+	.top_debug_testbus_reg         = 11,
+	.top_cc_test_bus_supported     = true,
 	.num_debug_registers           = 18,
 	.top_debug = {
 		0x0000004C,
@@ -495,6 +641,25 @@ static struct cam_sfe_top_hw_info sfe780_top_hw_info = {
 	.top_err_desc    = sfe_780_top_irq_err_desc,
 	.num_clc_module  = 11,
 	.clc_dbg_mod_info = &sfe780_clc_dbg_module_info,
+	.num_of_testbus = 2,
+	.test_bus_info = {
+		/* TEST BUS 1 INFO */
+		{
+			.debugfs_val  = SFE_DEBUG_ENABLE_TESTBUS1,
+			.enable       = false,
+			.value        = 0x1,
+			.size         = ARRAY_SIZE(sfe780_testbus1_info),
+			.testbus      = sfe780_testbus1_info,
+		},
+		/* TEST BUS 2 INFO */
+		{
+			.debugfs_val  = SFE_DEBUG_ENABLE_TESTBUS2,
+			.enable       = false,
+			.value        = 0x3,
+			.size         = ARRAY_SIZE(sfe780_testbus2_info),
+			.testbus      = sfe780_testbus2_info,
+		},
+	},
 };
 
 static struct cam_irq_register_set sfe780_bus_rd_irq_reg[1] = {

+ 8 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_core.h

@@ -45,6 +45,14 @@ struct cam_sfe_hw_core_info {
 #define SFE_DEBUG_ENABLE_FRAME_COUNTER            BIT(2)
 #define SFE_DEBUG_ENABLE_RD_DONE_IRQ              BIT(3)
 #define SFE_DEBUG_DISABLE_MMU_PREFETCH            BIT(4)
+#define SFE_DEBUG_ENABLE_TESTBUS1                 BIT(8)
+#define SFE_DEBUG_ENABLE_TESTBUS2                 BIT(9)
+
+/* Reserve 4 bits for future test-busses in debug config */
+#define SFE_DEBUG_ENABLE_TESTBUS_RESERVED1        BIT(10)
+#define SFE_DEBUG_ENABLE_TESTBUS_RESERVED2        BIT(11)
+#define SFE_DEBUG_ENABLE_TESTBUS_RESERVED3        BIT(12)
+#define SFE_DEBUG_ENABLE_TESTBUS_RESERVED4        BIT(13)
 
 int cam_sfe_get_hw_caps(void *device_priv,
 	void *get_hw_cap_args, uint32_t arg_size);

+ 70 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c

@@ -50,6 +50,7 @@ struct cam_sfe_top_priv {
 	struct cam_sfe_core_cfg         core_cfg;
 	uint32_t                        sfe_debug_cfg;
 	uint32_t                        sensor_sel_diag_cfg;
+	uint32_t                        cc_testbus_sel_cfg;
 	int                             error_irq_handle;
 	uint16_t                        reserve_cnt;
 	uint16_t                        start_stop_cnt;
@@ -203,6 +204,52 @@ static void cam_sfe_top_check_module_status(
 	}
 }
 
+static void cam_sfe_top_print_cc_test_bus(
+	struct cam_sfe_top_priv *top_priv)
+{
+	struct cam_sfe_top_common_data     *common_data = &top_priv->common_data;
+	struct cam_hw_soc_info             *soc_info = common_data->soc_info;
+	void __iomem                       *mem_base =
+		soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base;
+	struct cam_sfe_top_cc_testbus_info *testbus_info;
+	uint32_t dbg_testbus_reg = common_data->common_reg->top_debug_testbus_reg;
+	uint32_t size = 0, reg_val = 0, val = 0, i = 0;
+	size_t   len = 0;
+	uint8_t  log_buf[1024];
+
+	reg_val =  cam_io_r(mem_base +
+		common_data->common_reg->top_debug[dbg_testbus_reg]);
+
+	for (i = 0; i < top_priv->hw_info->num_of_testbus; i++) {
+		if (top_priv->cc_testbus_sel_cfg ==
+			top_priv->hw_info->test_bus_info[i].value) {
+			size = top_priv->hw_info->test_bus_info[i].size;
+			testbus_info =
+				top_priv->hw_info->test_bus_info[i].testbus;
+		       break;
+		}
+	}
+
+	if (i == top_priv->hw_info->num_of_testbus) {
+		CAM_WARN(CAM_SFE,
+			"Unexpected value[%d] is programed in test_bus_ctrl reg",
+			top_priv->cc_testbus_sel_cfg);
+		return;
+	}
+
+	for (i = 0; i < size; i++) {
+		val = reg_val >> testbus_info[i].shift;
+		val &= testbus_info[i].mask;
+		if (val)
+			CAM_INFO_BUF(CAM_SFE, log_buf, 1024, &len, "%s [val:%u]",
+				 testbus_info[i].clc_name, val);
+	}
+
+	CAM_INFO(CAM_SFE, "SFE_TOP_DEBUG_%d val %d  config %s",
+		common_data->common_reg->top_debug_testbus_reg,
+		reg_val, log_buf);
+}
+
 static void cam_sfe_top_print_debug_reg_info(
 	struct cam_sfe_top_priv *top_priv)
 {
@@ -234,6 +281,10 @@ static void cam_sfe_top_print_debug_reg_info(
 	cam_sfe_top_check_module_status(top_priv->num_clc_module,
 		reg_val, top_priv->clc_dbg_mod_info);
 
+	if (common_data->common_reg->top_cc_test_bus_supported &&
+		top_priv->cc_testbus_sel_cfg)
+		cam_sfe_top_print_cc_test_bus(top_priv);
+
 	kfree(reg_val);
 }
 
@@ -1482,6 +1533,24 @@ int cam_sfe_top_start(
 		path_data->mem_base +
 		path_data->common_reg->top_debug_cfg);
 
+	/* Enables the context controller testbus*/
+	if (path_data->common_reg->top_cc_test_bus_supported) {
+		for (i = 0; i < top_priv->hw_info->num_of_testbus; i++) {
+			if ((top_priv->sfe_debug_cfg &
+				top_priv->hw_info->test_bus_info[i].debugfs_val) ||
+				top_priv->hw_info->test_bus_info[i].enable) {
+				top_priv->cc_testbus_sel_cfg =
+					top_priv->hw_info->test_bus_info[i].value;
+				break;
+			}
+		}
+
+		if (top_priv->cc_testbus_sel_cfg)
+			cam_io_w(top_priv->cc_testbus_sel_cfg,
+				path_data->mem_base +
+				path_data->common_reg->top_cc_test_bus_ctrl);
+	}
+
 	/* Enable sensor diag info */
 	if (top_priv->sfe_debug_cfg &
 		SFE_DEBUG_ENABLE_SENSOR_DIAG_INFO) {
@@ -1787,6 +1856,7 @@ int cam_sfe_top_init(
 	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;
+	top_priv->cc_testbus_sel_cfg = 0;
 
 	sfe_top->hw_ops.process_cmd = cam_sfe_top_process_cmd;
 	sfe_top->hw_ops.start = cam_sfe_top_start;

+ 19 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.h

@@ -20,6 +20,7 @@
 #define CAM_SHIFT_TOP_CORE_CFG_FS_MODE_CFG     0
 
 #define CAM_SFE_TOP_DBG_REG_MAX                18
+#define CAM_SFE_TOP_TESTBUS_MAX                 2
 
 struct cam_sfe_top_module_desc {
 	uint32_t id;
@@ -52,6 +53,19 @@ struct cam_sfe_top_debug_info {
 	char     *clc_name;
 };
 
+struct cam_sfe_top_cc_testbus_info {
+	uint32_t  mask;
+	uint32_t  shift;
+	char     *clc_name;
+};
+
+struct cam_sfe_testbus_info {
+	uint32_t  debugfs_val;
+	bool      enable;
+	uint32_t  value;
+	uint32_t  size;
+	struct cam_sfe_top_cc_testbus_info *testbus;
+};
 
 struct cam_sfe_top_common_reg_offset {
 	uint32_t hw_version;
@@ -76,12 +90,15 @@ struct cam_sfe_top_common_reg_offset {
 	uint32_t sfe_single_dual_cfg;
 	uint32_t bus_overflow_status;
 	uint32_t top_debug_cfg;
+	uint32_t top_cc_test_bus_ctrl;
 	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 top_debug_testbus_reg;
+	uint32_t top_cc_test_bus_supported;
 	uint32_t num_debug_registers;
 	uint32_t top_debug[CAM_SFE_TOP_DBG_REG_MAX];
 };
@@ -124,6 +141,8 @@ struct cam_sfe_top_hw_info {
 	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];
+	uint32_t                                  num_of_testbus;
+	struct cam_sfe_testbus_info               test_bus_info[CAM_SFE_TOP_TESTBUS_MAX];
 };
 
 int cam_sfe_top_init(