浏览代码

msm: camera: isp: Dumping CSID registers on image violations

Currently at image size violation we just get info about width
and height for that particular port which is sometimes not
sufficient if in case some other register incorrectly configured.
This change will dump few CSID registers like crop register in
case of error which will help to get more info.

CRs-Fixed: 3467438
Change-Id: I034f2686b3689b52cdd0309d09bbdb920f88222b
Signed-off-by: Yash Upadhyay <[email protected]>
Yash Upadhyay 2 年之前
父节点
当前提交
f69d8301bf

+ 56 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -4215,6 +4215,26 @@ static int cam_ife_mgr_check_and_update_fe(
 	return 0;
 }
 
+static int cam_ife_hw_mgr_convert_out_port_to_csid_path(uint64_t port_id)
+{
+	uint32_t path_id = CAM_IFE_PIX_PATH_RES_MAX;
+
+	if (port_id == max_ife_out_res)
+		goto end;
+
+	path_id = cam_ife_hw_mgr_get_ife_csid_rdi_res_type(port_id);
+	if (path_id >= CAM_IFE_PIX_PATH_RES_RDI_0 && path_id <= CAM_IFE_PIX_PATH_RES_RDI_4)
+		return path_id;
+	else if (cam_ife_hw_mgr_check_path_port_compat(CAM_ISP_HW_VFE_IN_PDLIB,
+		port_id))
+		path_id =  CAM_IFE_PIX_PATH_RES_PPP;
+	else
+		path_id = CAM_IFE_PIX_PATH_RES_IPP;
+
+end:
+		return path_id;
+}
+
 static int cam_ife_hw_mgr_preprocess_port(
 	struct cam_ife_hw_mgr_ctx   *ife_ctx,
 	struct cam_isp_in_port_generic_info *in_port)
@@ -13421,6 +13441,36 @@ end:
 	return rc;
 }
 
+static void cam_ife_hw_mgr_trigger_crop_reg_dump(
+	struct cam_hw_intf                      *hw_intf,
+	struct cam_isp_hw_event_info            *event_info)
+{
+	int rc = 0, path_id = 0, idx = -1;
+
+	while (event_info->out_port_id) {
+		idx++;
+		if (!(event_info->out_port_id & 0x1)) {
+			event_info->out_port_id >>= 1;
+			continue;
+		}
+
+		path_id = cam_ife_hw_mgr_convert_out_port_to_csid_path(
+				CAM_ISP_IFE_OUT_RES_BASE + idx);
+		if (hw_intf->hw_ops.process_cmd) {
+			rc = hw_intf->hw_ops.process_cmd(
+				hw_intf->hw_priv,
+				CAM_ISP_HW_CMD_CSID_DUMP_CROP_REG,
+				&path_id,
+				sizeof(path_id));
+			if (rc)
+				CAM_ERR(CAM_ISP, "CSID:%d Reg Dump failed for path=%u",
+					event_info->hw_idx, path_id);
+		}
+
+		event_info->out_port_id >>= 1;
+	}
+}
+
 static int cam_ife_hw_mgr_do_error_recovery(
 	struct cam_ife_hw_event_recovery_data  *ife_mgr_recovery_data)
 {
@@ -14059,6 +14109,7 @@ static int cam_ife_hw_mgr_handle_hw_err(
 	struct cam_isp_hw_error_event_info      *err_evt_info;
 	struct cam_isp_hw_error_event_data       error_event_data = {0};
 	struct cam_ife_hw_event_recovery_data    recovery_data = {0};
+	struct cam_hw_intf                      *hw_intf;
 	int                                      rc = -EINVAL;
 
 	if (!event_info->event_data) {
@@ -14072,6 +14123,11 @@ static int cam_ife_hw_mgr_handle_hw_err(
 	err_type =  err_evt_info->err_type;
 
 	spin_lock(&g_ife_hw_mgr.ctx_lock);
+	if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
+		hw_intf = g_ife_hw_mgr.csid_devices[event_info->hw_idx];
+		cam_ife_hw_mgr_trigger_crop_reg_dump(hw_intf, event_info);
+	}
+
 	if (event_info->res_type ==
 		CAM_ISP_RESOURCE_VFE_IN &&
 		!ife_hw_mgr_ctx->flags.is_rdi_only_context &&

+ 3 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c

@@ -3788,6 +3788,9 @@ static int cam_ife_csid_ver1_process_cmd(void *hw_priv,
 		/* Not supported for V1 */
 		rc = 0;
 		break;
+	case CAM_ISP_HW_CMD_CSID_DUMP_CROP_REG:
+		/* Not supported in V1*/
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);

+ 55 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -6179,6 +6179,58 @@ static int cam_ife_csid_ver2_dual_sync_cfg(
 	return 0;
 }
 
+static int cam_ife_csid_ver2_dump_crop_reg(
+	struct cam_hw_info  *hw_info, uint32_t *path_id)
+{
+	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;
+	const struct cam_ife_csid_ver2_path_reg_info   *path_reg;
+	struct cam_isp_resource_node                   *path_res;
+	struct cam_ife_csid_ver2_path_cfg              *path_cfg;
+	uint32_t hcrop = 0, vcrop = 0, cfg0 = 0, cfg1 = 0;
+	int rc = 0;
+	void __iomem *mem_base;
+
+	csid_hw = (struct cam_ife_csid_ver2_hw *)hw_info->core_info;
+
+	spin_lock(&csid_hw->lock_state);
+	if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP ||
+		*path_id >= CAM_IFE_PIX_PATH_RES_MAX || *path_id < 0) {
+		CAM_ERR(CAM_ISP, "CSID[%u] Invalid dev state :%d or path_id :%u",
+			csid_hw->hw_intf->hw_idx,
+			csid_hw->hw_info->hw_state);
+		spin_unlock(&csid_hw->lock_state);
+		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;
+
+	CAM_INFO(CAM_ISP, "CSID[%u] Clock Name=%s Clock Rate=%u",
+		csid_hw->hw_intf->hw_idx, soc_info->clk_name[soc_info->src_clk_idx],
+		cam_soc_util_get_applied_src_clk(soc_info, true));
+
+	path_res = &csid_hw->path_res[*path_id];
+	path_cfg = (struct cam_ife_csid_ver2_path_cfg *)path_res->res_priv;
+	if (path_res->res_state == CAM_ISP_RESOURCE_STATE_STREAMING && path_cfg) {
+		path_reg = csid_reg->path_reg[*path_id];
+		hcrop = cam_io_r_mb(mem_base + path_reg->hcrop_addr);
+		vcrop = cam_io_r_mb(mem_base + path_reg->vcrop_addr);
+		cfg0 = cam_io_r_mb(mem_base + path_reg->cfg0_addr);
+		cfg1 = cam_io_r_mb(mem_base + path_reg->cfg1_addr);
+		CAM_INFO(CAM_ISP, "CSID[%u] %s HCROP=0x%x VCROP=0x%x, CFG0=0x%x CFG1=0x%x",
+			csid_hw->hw_intf->hw_idx, path_res->res_name, hcrop, vcrop, cfg0, cfg1);
+		CAM_INFO(CAM_ISP, "CSID[%u] %s width=%d height=%d start line:%d end line:%d",
+			csid_hw->hw_intf->hw_idx, path_res->res_name, path_cfg->width,
+			path_cfg->height, path_cfg->start_line, path_cfg->end_line);
+	}
+
+	spin_unlock(&csid_hw->lock_state);
+	return rc;
+}
+
 static int cam_ife_csid_ver2_set_discard_frame_cfg(
 	struct cam_ife_csid_ver2_hw    *csid_hw,
 	void                           *cmd_args)
@@ -6528,6 +6580,9 @@ static int cam_ife_csid_ver2_process_cmd(void *hw_priv,
 	case CAM_IFE_CSID_RESET_OUT_OF_SYNC_CNT:
 		rc = cam_ife_csid_ver2_reset_out_of_sync_cnt(csid_hw, cmd_args);
 		break;
+	case CAM_ISP_HW_CMD_CSID_DUMP_CROP_REG:
+		rc = cam_ife_csid_ver2_dump_crop_reg(hw_info, (uint32_t *)cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%u unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);

+ 3 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -230,6 +230,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_USER_DUMP,
 	CAM_ISP_HW_CMD_RDI_LCR_CFG,
 	CAM_ISP_HW_CMD_DRV_CONFIG,
+	CAM_ISP_HW_CMD_CSID_DUMP_CROP_REG,
 	CAM_ISP_HW_CMD_MAX,
 };
 
@@ -334,6 +335,7 @@ struct cam_isp_hw_bufdone_event_info {
  *
  * @Brief:             Structure to pass event details to hw mgr
  *
+ * @out_port_id        Out port id on which event occurred
  * @res_type:          Type of IFE resource
  * @is_secondary_evt:  Indicates if event was requested by hw mgr
  * @res_id:            Unique resource ID
@@ -345,6 +347,7 @@ struct cam_isp_hw_bufdone_event_info {
  *
  */
 struct cam_isp_hw_event_info {
+	uint64_t                       out_port_id;
 	enum cam_isp_resource_type     res_type;
 	bool                           is_secondary_evt;
 	uint32_t                       res_id;

+ 7 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -2769,7 +2769,8 @@ static int cam_vfe_bus_ver3_err_irq_top_half(uint32_t evt_id,
 static void cam_vfe_print_violations(
 	char *error_type,
 	uint32_t status,
-	struct cam_vfe_bus_ver3_priv *bus_priv)
+	struct cam_vfe_bus_ver3_priv *bus_priv,
+	uint64_t *out_port)
 {
 	int i, j;
 	struct cam_isp_resource_node       *rsrc_node = NULL;
@@ -2802,6 +2803,7 @@ static void cam_vfe_print_violations(
 					bus_priv->common_data.core_index, error_type);
 				cam_vfe_bus_ver3_print_wm_info(wm_data,
 					common_data, wm_name);
+				*out_port |= BIT_ULL(rsrc_node->res_id & 0xFF);
 			}
 		}
 	}
@@ -2816,6 +2818,7 @@ static int cam_vfe_bus_ver3_err_irq_bottom_half(
 	struct cam_isp_hw_event_info evt_info;
 	struct cam_isp_hw_error_event_info err_evt_info;
 	uint32_t status = 0, image_size_violation = 0, ccif_violation = 0, constraint_violation = 0;
+	uint64_t out_port_id = 0;
 
 	if (!handler_priv || !evt_payload_priv)
 		return -EINVAL;
@@ -2845,13 +2848,13 @@ static int cam_vfe_bus_ver3_err_irq_bottom_half(
 			cam_vfe_bus_ver3_get_constraint_errors(bus_priv);
 		else {
 			cam_vfe_print_violations("Image Size", status,
-				bus_priv);
+				bus_priv, &out_port_id);
 		}
 	}
 
 	if (ccif_violation) {
 		status = evt_payload->ccif_violation_status;
-		cam_vfe_print_violations("CCIF", status, bus_priv);
+		cam_vfe_print_violations("CCIF", status, bus_priv, &out_port_id);
 	}
 
 	cam_vfe_bus_ver3_put_evt_payload(common_data, &evt_payload);
@@ -2862,6 +2865,7 @@ static int cam_vfe_bus_ver3_err_irq_bottom_half(
 	evt_info.hw_type = CAM_ISP_HW_TYPE_VFE;
 	err_evt_info.err_type = CAM_VFE_IRQ_STATUS_VIOLATION;
 	evt_info.event_data = (void *)&err_evt_info;
+	evt_info.out_port_id = out_port_id;
 
 	if (common_data->event_cb)
 		common_data->event_cb(common_data->priv, CAM_ISP_HW_EVENT_ERROR,