Browse Source

msm: camera: isp: Update CSID halt sequence

Added below change as per discussion with HW team:
1. Disable/enable CG for all the path before/after halting paths
2. Enable PPP CSID path before IPP path during start.

CRs-Fixed: 3835814
Change-Id: I6716c789840292d8ea17cd788dd5e3f28ec0e715
Signed-off-by: Yash Upadhyay <[email protected]>
Signed-off-by: Alok Chauhan <[email protected]>
Alok Chauhan 8 months ago
parent
commit
14e77a674a

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -3650,7 +3650,7 @@ static int cam_tfe_mgr_restart_hw(void *start_hw_args)
 
 	CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d", ctx->ctx_index);
 	/* Start the TFE CSID HW devices */
-	list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
+	list_for_each_entry_reverse(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
 		rc = cam_tfe_hw_mgr_start_hw_res(hw_mgr_res, ctx);
 		if (rc) {
 			CAM_ERR(CAM_ISP, "Can not start TFE CSID (%d)",
@@ -3855,7 +3855,7 @@ start_only:
 	CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d",
 		ctx->ctx_index);
 	/* Start the TFE CSID HW devices */
-	list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
+	list_for_each_entry_reverse(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
 		rc = cam_tfe_hw_mgr_start_hw_res(hw_mgr_res, ctx);
 		if (rc) {
 			CAM_ERR(CAM_ISP, "Can not start TFE CSID (%d)",

+ 7 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid665.h

@@ -51,6 +51,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_665_ipp_reg_offset = {
 	.early_eof_en_shift_val              = 29,
 	.halt_master_sel_shift               = 4,
 	.halt_mode_shift                     = 2,
+	.halt_mode_mask                      = 3,
 	.halt_master_sel_master_val          = 1,
 	.halt_master_sel_slave_val           = 0,
 	.binning_supported                   = 3,
@@ -59,6 +60,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_665_ipp_reg_offset = {
 	.is_multi_vc_dt_supported            = true,
 	.format_measure_en_shift_val         = 0,
 	.measure_en_hbi_vbi_cnt_val          = 0xc,
+	.cgc_mode_en_shift_val               = 9,
 };
 
 static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_665_ppp_reg_offset = {
@@ -103,6 +105,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_665_ppp_reg_offset = {
 	.early_eof_en_shift_val              = 29,
 	.halt_master_sel_shift               = 4,
 	.halt_mode_shift                     = 2,
+	.halt_mode_mask                      = 3,
 	.halt_master_sel_master_val          = 3,
 	.halt_master_sel_slave_val           = 2,
 	.binning_supported                   = 0,
@@ -111,6 +114,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_665_ppp_reg_offset = {
 	.is_multi_vc_dt_supported            = true,
 	.format_measure_en_shift_val         = 0,
 	.measure_en_hbi_vbi_cnt_val          = 0xc,
+	.cgc_mode_en_shift_val               = 9,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_0_reg_offset = {
@@ -156,6 +160,7 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_0_reg_offset = {
 	.is_multi_vc_dt_supported                 = true,
 	.format_measure_en_shift_val              = 0,
 	.measure_en_hbi_vbi_cnt_val               = 0xc,
+	.cgc_mode_en_shift_val                    = 8,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_1_reg_offset = {
@@ -201,6 +206,7 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_1_reg_offset = {
 	.is_multi_vc_dt_supported                 = true,
 	.format_measure_en_shift_val              = 0,
 	.measure_en_hbi_vbi_cnt_val               = 0xc,
+	.cgc_mode_en_shift_val                    = 8,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_2_reg_offset = {
@@ -246,6 +252,7 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_665_rdi_2_reg_offset = {
 	.is_multi_vc_dt_supported                 = true,
 	.format_measure_en_shift_val              = 0,
 	.measure_en_hbi_vbi_cnt_val               = 0xc,
+	.cgc_mode_en_shift_val                    = 8,
 };
 
 static struct cam_tfe_csid_csi2_rx_reg_offset

+ 7 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid770.h

@@ -51,6 +51,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_770_ipp_reg_offset = {
 	.early_eof_en_shift_val              = 29,
 	.halt_master_sel_shift               = 4,
 	.halt_mode_shift                     = 2,
+	.halt_mode_mask                      = 3,
 	.halt_master_sel_master_val          = 1,
 	.halt_master_sel_slave_val           = 0,
 	.binning_supported                   = 3,
@@ -59,6 +60,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_770_ipp_reg_offset = {
 	.is_multi_vc_dt_supported            = true,
 	.format_measure_en_shift_val         = 0,
 	.measure_en_hbi_vbi_cnt_val          = 0xc,
+	.cgc_mode_en_shift_val               = 9,
 };
 
 static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_770_ppp_reg_offset = {
@@ -103,6 +105,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_770_ppp_reg_offset = {
 	.early_eof_en_shift_val              = 29,
 	.halt_master_sel_shift               = 4,
 	.halt_mode_shift                     = 2,
+	.halt_mode_mask                      = 3,
 	.halt_master_sel_master_val          = 3,
 	.halt_master_sel_slave_val           = 2,
 	.binning_supported                   = 0,
@@ -111,6 +114,7 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_770_ppp_reg_offset = {
 	.is_multi_vc_dt_supported            = true,
 	.format_measure_en_shift_val         = 0,
 	.measure_en_hbi_vbi_cnt_val          = 0xc,
+	.cgc_mode_en_shift_val               = 9,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_0_reg_offset = {
@@ -156,6 +160,7 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_0_reg_offset = {
 	.is_multi_vc_dt_supported                 = true,
 	.format_measure_en_shift_val              = 0,
 	.measure_en_hbi_vbi_cnt_val               = 0xc,
+	.cgc_mode_en_shift_val                    = 8,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_1_reg_offset = {
@@ -201,6 +206,7 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_1_reg_offset = {
 	.is_multi_vc_dt_supported                 = true,
 	.format_measure_en_shift_val              = 0,
 	.measure_en_hbi_vbi_cnt_val               = 0xc,
+	.cgc_mode_en_shift_val                    = 8,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_2_reg_offset = {
@@ -246,6 +252,7 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_770_rdi_2_reg_offset = {
 	.is_multi_vc_dt_supported                 = true,
 	.format_measure_en_shift_val              = 0,
 	.measure_en_hbi_vbi_cnt_val               = 0xc,
+	.cgc_mode_en_shift_val                    = 8,
 };
 
 static struct cam_tfe_csid_csi2_rx_reg_offset

+ 108 - 49
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c

@@ -1804,11 +1804,9 @@ static int cam_tfe_csid_change_pxl_halt_mode(
 static int cam_tfe_csid_disable_pxl_path(
 	struct cam_tfe_csid_hw          *csid_hw,
 	struct cam_isp_resource_node    *res,
-	enum cam_tfe_csid_halt_cmd       stop_cmd,
-	bool csid_with_ppp_en)
+	enum cam_tfe_csid_halt_cmd       stop_cmd)
 {
 	int rc = 0;
-	uint32_t val = 0;
 	const struct cam_tfe_csid_reg_offset       *csid_reg;
 	struct cam_hw_soc_info                     *soc_info;
 	struct cam_tfe_csid_path_cfg               *path_data;
@@ -1862,43 +1860,10 @@ static int cam_tfe_csid_disable_pxl_path(
 	path_data->init_frame_drop = 0;
 	path_data->res_sof_cnt     = 0;
 
-	if (((path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) ||
-		(path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)) && !csid_with_ppp_en)
-		/* Set halt mode for dual master/slave without pdaf */
-		val = (TFE_CSID_HALT_MODE_GLOBAL << pxl_reg->halt_mode_shift) |
-			(TFE_CSID_HALT_CMD_SOURCE_EXTERNAL << pxl_reg->halt_master_sel_shift) |
-			(CAM_TFE_CSID_HALT_IMMEDIATELY << pxl_reg->halt_cmd_shift);
-	else if ((path_data->is_shdr && path_data->is_shdr_master) ||
-		(path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER))
-		/* Set halt mode for shdr/dual master */
-		val = (TFE_CSID_HALT_MODE_MASTER << pxl_reg->halt_mode_shift) |
-			(TFE_CSID_HALT_CMD_SOURCE_NONE << pxl_reg->halt_master_sel_shift) |
-			(CAM_TFE_CSID_HALT_AT_FRAME_BOUNDARY << pxl_reg->halt_cmd_shift);
-	else if ((path_data->is_shdr && !path_data->is_shdr_master) ||
-		(path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)) {
-		/* Set halt mode for shdr/dual slave */
-		CAM_DBG(CAM_ISP, "skip programming halt mode for slave in %s case",
-			(path_data->is_shdr) ? "SHDR" : "Dual TFE");
-		goto end;
-	} else if (csid_with_ppp_en)
-		/* Set halt mode for single tfe + pdaf */
-		val = (TFE_CSID_HALT_MODE_INTERNAL << pxl_reg->halt_mode_shift) |
-			(TFE_CSID_HALT_CMD_SOURCE_NONE << pxl_reg->halt_master_sel_shift) |
-			(CAM_TFE_CSID_HALT_AT_FRAME_BOUNDARY << pxl_reg->halt_cmd_shift);
-	else
-		/* Set halt mode for default */
-		val = (TFE_CSID_HALT_MODE_GLOBAL << pxl_reg->halt_mode_shift) |
-			(TFE_CSID_HALT_CMD_SOURCE_EXTERNAL << pxl_reg->halt_master_sel_shift) |
-			(CAM_TFE_CSID_HALT_AT_FRAME_BOUNDARY << pxl_reg->halt_cmd_shift);
-
-	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
-		pxl_reg->csid_pxl_ctrl_addr);
-
 	CAM_DBG(CAM_ISP, "halt CSID:%d sync_mode:%d res_id:%d IPP path pxl_ctrl=0x%x",
 		csid_hw->hw_intf->hw_idx, path_data->sync_mode, res->res_id,
 		cam_io_r_mb(soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_ctrl_addr));
 
-end:
 	return rc;
 }
 
@@ -3097,13 +3062,16 @@ static int cam_tfe_csid_stop(void *hw_priv,
 	void *stop_args, uint32_t arg_size)
 {
 	int rc = 0;
-	struct cam_tfe_csid_hw               *csid_hw;
-	struct cam_hw_info                   *csid_hw_info;
-	struct cam_isp_resource_node         *res;
-	struct cam_tfe_csid_hw_stop_args     *csid_stop;
-	uint32_t  i;
+	struct cam_tfe_csid_hw                    *csid_hw;
+	struct cam_hw_info                        *csid_hw_info;
+	struct cam_isp_resource_node              *res;
+	struct cam_tfe_csid_hw_stop_args          *csid_stop;
+	struct cam_hw_soc_info                    *soc_info;
+	const struct cam_tfe_csid_reg_offset      *csid_reg;
+	const struct cam_tfe_csid_pxl_reg_offset  *pxl_reg;
+	uint32_t  i, val = 0;
 	uint32_t res_mask = 0;
-	bool csid_with_ppp_en = false;
+	void __iomem *mem_base;
 
 	if (!hw_priv || !stop_args ||
 		(arg_size != sizeof(struct cam_tfe_csid_hw_stop_args))) {
@@ -3119,13 +3087,74 @@ static int cam_tfe_csid_stop(void *hw_priv,
 
 	csid_hw_info = (struct cam_hw_info  *)hw_priv;
 	csid_hw = (struct cam_tfe_csid_hw   *)csid_hw_info->core_info;
+	csid_reg = csid_hw->csid_info->csid_reg;
+	soc_info = &csid_hw->hw_info->soc_info;
+	mem_base = soc_info->reg_map[0].mem_base;
+
+	/* Disalbe cgc for all the path */
+	for (i = 0; i < csid_stop->num_res; i++) {
+		res = csid_stop->node_res[i];
+		switch (res->res_type) {
+		case CAM_ISP_RESOURCE_PIX_PATH:
+			if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) {
+				pxl_reg = csid_reg->ipp_reg;
+				val = cam_io_r_mb(mem_base + pxl_reg->csid_pxl_cfg0_addr);
+				val = val | (1 << pxl_reg->cgc_mode_en_shift_val);
+				cam_io_w_mb(val, mem_base + pxl_reg->csid_pxl_cfg0_addr);
+			} else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP) {
+				pxl_reg = csid_reg->ppp_reg;
+				val = cam_io_r_mb(mem_base + pxl_reg->csid_pxl_cfg0_addr);
+				val = val | (1 << pxl_reg->cgc_mode_en_shift_val);
+				cam_io_w_mb(val, mem_base + pxl_reg->csid_pxl_cfg0_addr);
+			}
+			CAM_DBG(CAM_ISP, "CSID:%d cgc change res_type %d res_id %d val:0x%x",
+				csid_hw->hw_intf->hw_idx,
+				res->res_type, res->res_id, val);
+			break;
+		default:
+			CAM_DBG(CAM_ISP, "CSID:%d Invalid res type%d",
+				csid_hw->hw_intf->hw_idx, res->res_type);
+			break;
+		}
+	}
 
-	if (csid_hw->ppp_res.res_state == CAM_ISP_RESOURCE_STATE_STREAMING)
-		csid_with_ppp_en = true;
+	/* csid ctrl to resume at frame boundary */
+	cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
+		mem_base + csid_reg->cmn_reg->csid_ctrl_addr);
 
-	CAM_DBG(CAM_ISP, "CSID:%d num_res %d csid_with_ppp_en:%d",
-		csid_hw->hw_intf->hw_idx, csid_stop->num_res,
-		csid_with_ppp_en);
+	/* halt to global */
+	for (i = 0; i < csid_stop->num_res; i++) {
+		res = csid_stop->node_res[i];
+		switch (res->res_type) {
+		case CAM_ISP_RESOURCE_PIX_PATH:
+			if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) {
+				pxl_reg = csid_reg->ipp_reg;
+				val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+				val &= ~(pxl_reg->halt_mode_mask << pxl_reg->halt_mode_shift);
+				val |= (TFE_CSID_HALT_MODE_GLOBAL << pxl_reg->halt_mode_shift);
+				cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+			} else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP) {
+				pxl_reg = csid_reg->ppp_reg;
+				val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+				val &= ~(pxl_reg->halt_mode_mask << pxl_reg->halt_mode_shift);
+				val |= (TFE_CSID_HALT_MODE_GLOBAL << pxl_reg->halt_mode_shift);
+				cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+			}
+			CAM_DBG(CAM_ISP, "CSID:%d global change res_type %d res_id %d val:0x%x",
+				csid_hw->hw_intf->hw_idx,
+				res->res_type, res->res_id, val);
+			break;
+		default:
+			CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
+				csid_hw->hw_intf->hw_idx,
+				res->res_type);
+			break;
+		}
+	}
 
 	/* Stop the resource first */
 	for (i = 0; i < csid_stop->num_res; i++) {
@@ -3138,14 +3167,13 @@ static int cam_tfe_csid_stop(void *hw_priv,
 			res_mask |= (1 << res->res_id);
 			if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP)
 				rc = cam_tfe_csid_disable_pxl_path(csid_hw,
-					res, csid_stop->stop_cmd, csid_with_ppp_en);
+					res, csid_stop->stop_cmd);
 			else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP)
 				rc = cam_tfe_csid_disable_ppp_path(csid_hw,
 					res, csid_stop->stop_cmd);
 			else
 				rc = cam_tfe_csid_disable_rdi_path(csid_hw,
 					res, csid_stop->stop_cmd);
-
 			break;
 		default:
 			CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
@@ -3155,9 +3183,40 @@ static int cam_tfe_csid_stop(void *hw_priv,
 		}
 	}
 
+	/* issue global cmd */
+	cam_io_w_mb(CAM_TFE_CSID_HALT_IMMEDIATELY,
+		mem_base + csid_reg->cmn_reg->csid_ctrl_addr);
+
 	if (res_mask)
 		rc = cam_tfe_csid_poll_stop_status(csid_hw, res_mask);
 
+	for (i = 0; i < csid_stop->num_res; i++) {
+		res = csid_stop->node_res[i];
+		CAM_DBG(CAM_ISP, "CSID:%d cgc change to dynamic 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_PIX_PATH:
+			if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) {
+				pxl_reg = csid_reg->ipp_reg;
+				val = cam_io_r_mb(mem_base + pxl_reg->csid_pxl_cfg0_addr);
+				val &= ~(1 << pxl_reg->cgc_mode_en_shift_val);
+				cam_io_w_mb(val, mem_base + pxl_reg->csid_pxl_cfg0_addr);
+			} else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP) {
+				pxl_reg = csid_reg->ipp_reg;
+				val = cam_io_r_mb(mem_base + pxl_reg->csid_pxl_cfg0_addr);
+				val &= ~(1 << pxl_reg->cgc_mode_en_shift_val);
+				cam_io_w_mb(val, mem_base + pxl_reg->csid_pxl_cfg0_addr);
+			} else
+				continue;
+		default:
+			CAM_DBG(CAM_ISP, "CSID:%d Invalid res type%d",
+				csid_hw->hw_intf->hw_idx,
+				res->res_type);
+			break;
+		}
+	}
+
 	for (i = 0; i < csid_stop->num_res; i++) {
 		res = csid_stop->node_res[i];
 		res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;

+ 3 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h

@@ -160,6 +160,7 @@ struct cam_tfe_csid_pxl_reg_offset {
 	uint32_t early_eof_en_shift_val;
 	uint32_t halt_master_sel_shift;
 	uint32_t halt_mode_shift;
+	uint32_t halt_mode_mask;
 	uint32_t halt_cmd_shift;
 	uint32_t halt_master_sel_master_val;
 	uint32_t halt_master_sel_slave_val;
@@ -169,6 +170,7 @@ struct cam_tfe_csid_pxl_reg_offset {
 	uint32_t format_measure_en_shift_val;
 	uint32_t measure_en_hbi_vbi_cnt_val;
 	bool     is_multi_vc_dt_supported;
+	uint32_t cgc_mode_en_shift_val;
 };
 
 struct cam_tfe_csid_rdi_reg_offset {
@@ -216,6 +218,7 @@ struct cam_tfe_csid_rdi_reg_offset {
 	uint32_t format_measure_en_shift_val;
 	uint32_t measure_en_hbi_vbi_cnt_val;
 	bool     is_multi_vc_dt_supported;
+	uint32_t cgc_mode_en_shift_val;
 };
 
 struct cam_tfe_csid_csi2_rx_reg_offset {

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -2620,7 +2620,8 @@ static int cam_tfe_ppp_resource_start(
 	ppp_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
 
 	CAM_DBG(CAM_ISP, "TFE: %d Start PPP Done, core_cfg 0 val:0x%x",
-		core_info->core_index, val);
+		core_info->core_index,
+		cam_io_r_mb(rsrc_data->mem_base + rsrc_data->common_reg->core_cfg_0));
 	return 0;
 }