Forráskód Böngészése

msm: camera: isp: Additional fixes for KMD internal recovery

Avoid programming RUP/AUP at CSID start for internal recovery.
The request being recovered will configure this appropriately via CDM.
Also avoid resetting epoch factor for IFE PIX resource at stream off
that is triggered internally, the UMD configured epoch factor is
needed to stream on again post recovery.

CRs-Fixed: 3045706
Change-Id: I865ad0c2c08330a29eacfea63b4e15892a84bd69
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 3 éve
szülő
commit
fa319fa819

+ 5 - 3
drivers/cam_isp/cam_isp_context.c

@@ -4192,7 +4192,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
 		stop_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
 		stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_IMMEDIATELY;
 		stop_isp.stop_only = true;
-		stop_isp.internal_trigger = false;
+		stop_isp.is_internal_stop = false;
 		stop_args.args = (void *)&stop_isp;
 		rc = ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
 			&stop_args);
@@ -6078,6 +6078,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
 	start_isp.hw_config.init_packet = 1;
 	start_isp.hw_config.reapply_type = CAM_CONFIG_REAPPLY_NONE;
 	start_isp.hw_config.cdm_reset_before_apply = false;
+	start_isp.is_internal_start = false;
 
 	ctx_isp->last_applied_req_id = req->request_id;
 
@@ -6190,7 +6191,7 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
 
 		stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_IMMEDIATELY;
 		stop_isp.stop_only = false;
-		stop_isp.internal_trigger = false;
+		stop_isp.is_internal_stop = false;
 
 		stop.args = (void *) &stop_isp;
 		ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
@@ -6451,7 +6452,7 @@ static int __cam_isp_ctx_reset_and_recover(
 	stop_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
 	stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_IMMEDIATELY;
 	stop_isp.stop_only = true;
-	stop_isp.internal_trigger = true;
+	stop_isp.is_internal_stop = true;
 	stop_args.args = (void *)&stop_isp;
 	rc = ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
 		&stop_args);
@@ -6495,6 +6496,7 @@ static int __cam_isp_ctx_reset_and_recover(
 	start_isp.hw_config.reapply_type = CAM_CONFIG_REAPPLY_IQ;
 	start_isp.hw_config.cdm_reset_before_apply = false;
 	start_isp.start_only = true;
+	start_isp.is_internal_start = true;
 
 	__cam_isp_context_reset_internal_recovery_params(ctx_isp);
 

+ 10 - 7
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -786,8 +786,9 @@ err:
 }
 
 static int cam_ife_mgr_csid_start_hw(
-	struct cam_ife_hw_mgr_ctx *ctx,
-	uint32_t primary_rdi_csid_res)
+	struct   cam_ife_hw_mgr_ctx *ctx,
+	uint32_t primary_rdi_csid_res,
+	bool     is_internal_start)
 {
 	struct cam_isp_hw_mgr_res      *hw_mgr_res;
 	struct cam_isp_resource_node   *isp_res;
@@ -825,6 +826,7 @@ static int cam_ife_mgr_csid_start_hw(
 			hw_intf =  res[0]->hw_intf;
 			start_args.num_res = cnt;
 			start_args.node_res = res;
+			start_args.is_internal_start = is_internal_start;
 			hw_intf->hw_ops.start(hw_intf->hw_priv, &start_args,
 			    sizeof(start_args));
 		}
@@ -6190,7 +6192,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 	/* Ensure HW layer does not reset any clk data since it's
 	 * internal stream off/resume
 	 */
-	if (stop_isp->internal_trigger)
+	if (stop_isp->is_internal_stop)
 		cam_ife_mgr_finish_clk_bw_update(ctx, 0, true);
 
 	/* check to avoid iterating loop */
@@ -6229,7 +6231,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 	cam_tasklet_stop(ctx->common.tasklet_info);
 
 	/* reset scratch buffer/mup expect INIT again for UMD triggered stop/flush */
-	if (!stop_isp->internal_trigger) {
+	if (!stop_isp->is_internal_stop) {
 		ctx->current_mup = 0;
 		if (ctx->sfe_info.scratch_config)
 			memset(ctx->sfe_info.scratch_config, 0,
@@ -6248,7 +6250,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 			ctx->applied_req_id, ctx->ctx_index);
 
 	/* Reset CDM for KMD internal stop */
-	if (stop_isp->internal_trigger) {
+	if (stop_isp->is_internal_stop) {
 		rc = cam_cdm_reset_hw(ctx->cdm_handle);
 		if (rc) {
 			CAM_WARN(CAM_ISP, "CDM: %u reset failed rc: %d in ctx: %u",
@@ -6406,7 +6408,7 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args)
 
 	CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d", ctx->ctx_index);
 	/* Start the IFE CSID HW devices */
-	cam_ife_mgr_csid_start_hw(ctx, CAM_IFE_PIX_PATH_RES_MAX);
+	cam_ife_mgr_csid_start_hw(ctx, CAM_IFE_PIX_PATH_RES_MAX, false);
 
 	/* Start IFE root node: do nothing */
 	CAM_DBG(CAM_ISP, "Exit...(success)");
@@ -6747,7 +6749,8 @@ start_only:
 	CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d",
 		ctx->ctx_index);
 	/* Start the IFE CSID HW devices */
-	cam_ife_mgr_csid_start_hw(ctx, primary_rdi_csid_res);
+	cam_ife_mgr_csid_start_hw(ctx, primary_rdi_csid_res,
+		start_isp->is_internal_start);
 
 	/* Start IFE root node: do nothing */
 	CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index);

+ 4 - 2
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -107,14 +107,14 @@ enum cam_isp_hw_stop_cmd {
  * struct cam_isp_stop_args - hardware stop arguments
  *
  * @hw_stop_cmd:               Hardware stop command type information
- * @internal_trigger:          Stop triggered internally for reset & recovery
+ * @is_internal_stop:          Stop triggered internally for reset & recovery
  * @stop_only:                 Send stop only to hw drivers. No Deinit to be
  *                             done.
  *
  */
 struct cam_isp_stop_args {
 	enum cam_isp_hw_stop_cmd      hw_stop_cmd;
-	bool                          internal_trigger;
+	bool                          is_internal_stop;
 	bool                          stop_only;
 };
 
@@ -361,12 +361,14 @@ struct cam_isp_hw_cmd_args {
  * struct cam_isp_start_args - isp hardware start arguments
  *
  * @config_args:               Hardware configuration commands.
+ * @is_internal_start:         Start triggered internally for reset & recovery
  * @start_only                 Send start only to hw drivers. No init to
  *                             be done.
  *
  */
 struct cam_isp_start_args {
 	struct cam_hw_config_args hw_config;
+	bool                      is_internal_start;
 	bool                      start_only;
 };
 

+ 13 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -4220,13 +4220,20 @@ int cam_ife_csid_ver2_start(void *hw_priv, void *args,
 		}
 	}
 
-	/* Configure RUP/AUP/MUP @ streamon for all paths together */
+	/*
+	 * Configure RUP/AUP/MUP @ streamon for all enabled paths
+	 * For internal recovery - skip this, CDM packet corresponding
+	 * to the request being recovered will apply the appropriate RUP/AUP/MUP
+	 */
 	rup_aup_mask |= (csid_hw->rx_cfg.mup << csid_reg->cmn_reg->mup_shift_val);
-	cam_io_w_mb(rup_aup_mask,
-		soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base +
-		csid_reg->cmn_reg->rup_aup_cmd_addr);
-	CAM_DBG(CAM_ISP, "CSID:%u RUP_AUP_MUP: 0x%x at start",
-		csid_hw->hw_intf->hw_idx, rup_aup_mask);
+	if (!start_args->is_internal_start)
+		cam_io_w_mb(rup_aup_mask,
+			soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base +
+			csid_reg->cmn_reg->rup_aup_cmd_addr);
+
+	CAM_DBG(CAM_ISP, "CSID:%u RUP_AUP_MUP: 0x%x at start updated: %s",
+		csid_hw->hw_intf->hw_idx, rup_aup_mask,
+		CAM_BOOL_TO_YESNO(!start_args->is_internal_start));
 
 	cam_ife_csid_ver2_enable_csi2(csid_hw);
 

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h

@@ -279,6 +279,7 @@ struct cam_csid_hw_stop_args {
 struct cam_csid_hw_start_args {
 	struct cam_isp_resource_node            **node_res;
 	uint32_t                                  num_res;
+	bool                                      is_internal_start;
 };
 
 

+ 3 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.c

@@ -146,7 +146,7 @@ static int cam_vfe_top_calc_hw_clk_rate(
 			max_req_clk_rate = top_common->req_clk_rate[i];
 	}
 
-	if (start_stop && !top_common->skip_clk_data_rst) {
+	if (start_stop && !top_common->skip_data_rst_on_stop) {
 		/* need to vote current clk immediately */
 		*final_clk_rate = max_req_clk_rate;
 		/* Reset everything, we can start afresh */
@@ -598,7 +598,7 @@ int cam_vfe_top_apply_clk_bw_update(struct cam_vfe_top_priv_common *top_common,
 	}
 
 	if (clk_bw_args->skip_clk_data_rst) {
-		top_common->skip_clk_data_rst = true;
+		top_common->skip_data_rst_on_stop = true;
 		CAM_DBG(CAM_ISP, "VFE:%u requested to avoid clk data rst", hw_intf->hw_idx);
 		return 0;
 	}
@@ -740,7 +740,7 @@ int cam_vfe_top_apply_clock_start_stop(struct cam_vfe_top_priv_common *top_commo
 
 end:
 	top_common->clk_state = CAM_CLK_BW_STATE_INIT;
-	top_common->skip_clk_data_rst = false;
+	top_common->skip_data_rst_on_stop = false;
 	return rc;
 }
 

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.h

@@ -36,7 +36,7 @@ struct cam_vfe_top_priv_common {
 	struct cam_hw_soc_info         *soc_info;
 	unsigned long                   applied_clk_rate;
 	unsigned long                   req_clk_rate[CAM_VFE_TOP_MUX_MAX];
-	bool                            skip_clk_data_rst;
+	bool                            skip_data_rst_on_stop;
 
 };
 

+ 9 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

@@ -788,7 +788,7 @@ int cam_vfe_top_ver4_stop(void *device_priv,
 		for (i = 0; i < top_priv->top_common.num_mux; i++) {
 			if (top_priv->top_common.mux_rsrc[i].res_id ==
 				mux_res->res_id) {
-				if (!top_priv->top_common.skip_clk_data_rst)
+				if (!top_priv->top_common.skip_data_rst_on_stop)
 					top_priv->top_common.req_clk_rate[i] = 0;
 				memset(&top_priv->top_common.req_axi_vote[i],
 					0, sizeof(struct cam_axi_vote));
@@ -1357,8 +1357,9 @@ static int cam_vfe_resource_stop(
 	struct cam_isp_resource_node *vfe_res)
 {
 	struct cam_vfe_mux_ver4_data        *vfe_priv;
-	int                                        rc = 0;
-	uint32_t                                   val = 0;
+	struct cam_vfe_top_ver4_priv        *top_priv;
+	int                                  rc = 0;
+	uint32_t                             val = 0;
 
 	if (!vfe_res) {
 		CAM_ERR(CAM_ISP, "Error, Invalid input arguments");
@@ -1370,6 +1371,7 @@ static int cam_vfe_resource_stop(
 		return 0;
 
 	vfe_priv = (struct cam_vfe_mux_ver4_data *)vfe_res->res_priv;
+	top_priv = vfe_priv->top_priv;
 
 	if (vfe_priv->is_lite || !vfe_priv->is_pixel_path)
 		goto skip_core_decfg;
@@ -1415,7 +1417,10 @@ skip_core_decfg:
 		vfe_priv->irq_err_handle = 0;
 	}
 
-	vfe_priv->epoch_factor = 0;
+	/* Skip epoch factor reset for internal recovery */
+	if (!top_priv->top_common.skip_data_rst_on_stop)
+		vfe_priv->epoch_factor = 0;
+
 	CAM_DBG(CAM_ISP, "VFE:%d Res: %s Stopped",
 		vfe_res->hw_intf->hw_idx,
 		vfe_res->res_name);