Эх сурвалжийг харах

msm: camera: isp: Handle init discard frame config for dynamic switch

In case of dynamic switch shdr use-case ensure discard config is only
applied on number of starting exposures. The change also avoids
programming fetch enable/disable via AHB if already programmed
via CDM at stream on.

CRs-Fixed: 2841729
Change-Id: I36719ca447eeb890f0059489709ab11dcc37dd38
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 3 жил өмнө
parent
commit
2dfbe62d1f

+ 34 - 34
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -7566,22 +7566,21 @@ static int cam_isp_blob_csid_discard_init_frame_update(
 }
 
 
-static int cam_isp_blob_csid_mup_update(
+static int cam_isp_blob_csid_dynamic_switch_update(
 	uint32_t                               blob_type,
 	struct cam_isp_generic_blob_info      *blob_info,
 	struct cam_isp_mode_switch_info       *mup_config,
 	struct cam_hw_prepare_update_args     *prepare)
 {
-	struct cam_ife_hw_mgr_ctx             *ctx = NULL;
-	struct cam_isp_hw_mgr_res             *hw_mgr_res;
-	struct cam_hw_intf                    *hw_intf;
-	struct cam_ife_csid_mup_update_args    csid_mup_upd_args;
-	struct cam_isp_prepare_hw_update_data *prepare_hw_data;
-	uint64_t                               mup_val = 0;
-	int                                    rc = -EINVAL;
-	uint32_t                               i;
+	struct cam_ife_hw_mgr_ctx                  *ctx = NULL;
+	struct cam_hw_intf                         *hw_intf;
+	struct cam_ife_csid_mode_switch_update_args csid_mup_upd_args;
+	struct cam_ife_hw_mgr                      *ife_hw_mgr;
+	struct cam_isp_prepare_hw_update_data      *prepare_hw_data;
+	int                                         i, rc = -EINVAL;
 
 	ctx = prepare->ctxt_to_hw_map;
+	ife_hw_mgr = ctx->hw_mgr;
 
 	CAM_DBG(CAM_ISP,
 		"csid mup value=%u", mup_config->mup);
@@ -7590,30 +7589,31 @@ static int cam_isp_blob_csid_mup_update(
 			prepare->priv;
 	prepare_hw_data->mup_en = true;
 
-	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
-		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
-			mup_val = 0;
-			if (!hw_mgr_res->hw_res[i])
-				continue;
-			if (i == CAM_ISP_HW_SPLIT_RIGHT)
-				continue;
-			mup_val = mup_config->mup;
-			hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
-			if (hw_intf && hw_intf->hw_ops.process_cmd) {
-				csid_mup_upd_args.mup = mup_val;
-				CAM_DBG(CAM_ISP, "i= %d mup=%llu\n ctx %d",
-				i, csid_mup_upd_args.mup, ctx->ctx_index);
+	csid_mup_upd_args.mup_args.mup = mup_config->mup;
+	for (i = 0; i < ctx->num_base; i++) {
+		if (ctx->base[i].hw_type != CAM_ISP_HW_TYPE_CSID)
+			continue;
 
-				rc = hw_intf->hw_ops.process_cmd(
-					hw_intf->hw_priv,
-					CAM_ISP_HW_CMD_CSID_MUP_UPDATE,
-					&csid_mup_upd_args,
-					sizeof(
-					struct cam_ife_csid_mup_update_args));
-				if (rc)
-					CAM_ERR(CAM_ISP, "MUP Update failed");
-			} else
-				CAM_ERR(CAM_ISP, "NULL hw_intf!");
+		if (ctx->base[i].split_id != CAM_ISP_HW_SPLIT_LEFT)
+			continue;
+
+		/* For sHDR dynamic switch update num starting exposures to CSID for INIT */
+		if ((prepare_hw_data->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) &&
+			(ctx->flags.is_sfe_shdr)) {
+			csid_mup_upd_args.exp_update_args.reset_discard_cfg = true;
+			csid_mup_upd_args.exp_update_args.num_exposures =
+				mup_config->num_expoures;
+		}
+
+		hw_intf = ife_hw_mgr->csid_devices[ctx->base[i].idx];
+		if (hw_intf && hw_intf->hw_ops.process_cmd) {
+			rc = hw_intf->hw_ops.process_cmd(
+				hw_intf->hw_priv,
+				CAM_ISP_HW_CMD_CSID_DYNAMIC_SWITCH_UPDATE,
+				&csid_mup_upd_args,
+				sizeof(struct cam_ife_csid_mode_switch_update_args));
+			if (rc)
+				CAM_ERR(CAM_ISP, "Dynamic switch update failed");
 		}
 	}
 
@@ -8962,8 +8962,8 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
 
 		mup_config = (struct cam_isp_mode_switch_info *)blob_data;
 
-		rc = cam_isp_blob_csid_mup_update(blob_type, blob_info,
-			mup_config, prepare);
+		rc = cam_isp_blob_csid_dynamic_switch_update(
+			blob_type, blob_info, mup_config, prepare);
 		if (rc)
 			CAM_ERR(CAM_ISP, "MUP Update Failed");
 	}

+ 40 - 14
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -410,6 +410,7 @@ static inline void cam_ife_csid_ver2_reset_discard_frame_cfg(
 
 	/* Reset discard config params */
 	path_cfg->discard_init_frames = false;
+	path_cfg->skip_discard_frame_cfg = false;
 	path_cfg->num_frames_discard = 0;
 	path_cfg->sof_cnt = 0;
 
@@ -1873,6 +1874,7 @@ static int cam_ife_csid_ver2_disable_path(
 
 	/* Reset frame drop fields at stream off */
 	path_cfg->discard_init_frames = false;
+	path_cfg->skip_discard_frame_cfg = false;
 	path_cfg->num_frames_discard = 0;
 	path_cfg->sof_cnt = 0;
 	return rc;
@@ -4428,21 +4430,45 @@ static int cam_ife_csid_ver2_print_hbi_vbi(
 	return 0;
 }
 
-static int cam_ife_csid_ver2_set_mup_config(
-	struct cam_ife_csid_ver2_hw          *csid_hw,
-	void *cmd_args)
+static int cam_ife_csid_ver2_set_dynamic_switch_config(
+	struct cam_ife_csid_ver2_hw *csid_hw,
+	void                        *cmd_args)
 {
-	struct cam_ife_csid_mup_update_args *mup_update = NULL;
+	struct cam_ife_csid_mode_switch_update_args *switch_update = NULL;
 
 	if (!csid_hw)
 		return -EINVAL;
 
-	mup_update =
-		(struct cam_ife_csid_mup_update_args *)cmd_args;
-
-	csid_hw->rx_cfg.mup = mup_update->mup;
-	CAM_INFO(CAM_ISP, "CSID[%u] MUP %u", csid_hw->hw_intf->hw_idx,
-		csid_hw->rx_cfg.mup);
+	switch_update =
+		(struct cam_ife_csid_mode_switch_update_args *)cmd_args;
+
+	csid_hw->rx_cfg.mup = switch_update->mup_args.mup;
+	CAM_DBG(CAM_ISP, "CSID[%u] MUP %u",
+		csid_hw->hw_intf->hw_idx, csid_hw->rx_cfg.mup);
+
+	/* Handle number of frames to initially drop based on num starting exposures */
+	if (switch_update->exp_update_args.reset_discard_cfg) {
+		struct cam_ife_csid_discard_frame_cfg_update *exp_update_args;
+		struct cam_ife_csid_ver2_path_cfg            *path_cfg;
+		struct cam_isp_resource_node                 *res;
+		int i;
+
+		exp_update_args = &switch_update->exp_update_args;
+		for (i = CAM_IFE_PIX_PATH_RES_RDI_0; i <= CAM_IFE_PIX_PATH_RES_RDI_2; i++) {
+			res = &csid_hw->path_res[i];
+			path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv;
+			if ((i - CAM_IFE_PIX_PATH_RES_RDI_0) >= exp_update_args->num_exposures) {
+				path_cfg->skip_discard_frame_cfg = true;
+				if (path_cfg->discard_init_frames) {
+					path_cfg->discard_init_frames = false;
+					path_cfg->num_frames_discard = 0;
+					atomic_dec(&csid_hw->discard_frame_per_path);
+					CAM_DBG(CAM_ISP, "CSID[%u] Reset discard config for %s",
+						csid_hw->hw_intf->hw_idx, res->res_name);
+				}
+			}
+		}
+	}
 
 	return 0;
 }
@@ -4524,9 +4550,9 @@ static int cam_ife_csid_ver2_set_discard_frame_cfg(
 	/* Handle first stream on and consecutive streamons post flush */
 	if ((res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) ||
 		(res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW)) {
-		/* Skip if already set */
+		/* Skip if already set or need to skip based on stream on exposures */
 		path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv;
-		if (path_cfg->discard_init_frames)
+		if (path_cfg->skip_discard_frame_cfg || path_cfg->discard_init_frames)
 			goto end;
 
 		path_cfg->discard_init_frames = true;
@@ -4602,8 +4628,8 @@ static int cam_ife_csid_ver2_process_cmd(void *hw_priv,
 		rc = cam_ife_csid_ver2_program_offline_go_cmd(
 			csid_hw, cmd_args, arg_size);
 		break;
-	case CAM_ISP_HW_CMD_CSID_MUP_UPDATE:
-		rc = cam_ife_csid_ver2_set_mup_config(csid_hw, cmd_args);
+	case CAM_ISP_HW_CMD_CSID_DYNAMIC_SWITCH_UPDATE:
+		rc = cam_ife_csid_ver2_set_dynamic_switch_config(csid_hw, cmd_args);
 		break;
 	case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE:
 		break;

+ 37 - 31
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h

@@ -128,37 +128,42 @@ struct cam_ife_csid_ver2_camif_data {
 /*
  * struct cam_ife_csid_ver2_path_cfg: place holder for path parameters
  *
- * @camif_data:          CAMIF data
- * @error_ts:            Error timestamp
- * @cid:                 cid value for path
- * @in_format:           input format
- * @out_format:          output format
- * @start_pixel:         start pixel for horizontal crop
- * @end_pixel:           end pixel for horizontal  crop
- * @start_line:          start line for vertical crop
- * @end_line:            end line for vertical crop
- * @width:               width of incoming data
- * @height:              height of incoming data
- * @master_idx:          master idx
- * @horizontal_bin:      horizontal binning enable/disable on path
- * @vertical_bin:        vertical binning enable/disable on path
- * @qcfa_bin    :        qcfa binning enable/disable on path
- * @hor_ver_bin :        horizontal vertical binning enable/disable on path
- * @num_bytes_out:       Number of bytes out
- * @irq_handle:          IRQ handle
- * @err_irq_handle:      Error IRQ handle
- * @discard_irq_handle:  IRQ handle for SOF when discarding initial frames
- * @irq_reg_idx:         IRQ Reg index
- * @sof_cnt:             SOF counter
- * @num_frames_discard:  number of frames to discard
- * @sync_mode   :        Sync mode--> master/slave/none
- * @vfr_en   :           flag to indicate if variable frame rate is enabled
- * @frame_id_dec_en:     flag to indicate if frame id decoding is enabled
- * @crop_enable:         flag to indicate crop enable
- * @drop_enable:         flag to indicate drop enable
- * @discard_init_frames: discard initial frames
- * @en_secondary_evt:    Enable secondary evt for this path, to notify
- *                       hw manager
+ * @camif_data:             CAMIF data
+ * @error_ts:               Error timestamp
+ * @cid:                    cid value for path
+ * @in_format:              input format
+ * @out_format:             output format
+ * @start_pixel:            start pixel for horizontal crop
+ * @end_pixel:              end pixel for horizontal  crop
+ * @start_line:             start line for vertical crop
+ * @end_line:               end line for vertical crop
+ * @width:                  width of incoming data
+ * @height:                 height of incoming data
+ * @master_idx:             master idx
+ * @horizontal_bin:         horizontal binning enable/disable on path
+ * @vertical_bin:           vertical binning enable/disable on path
+ * @qcfa_bin    :           qcfa binning enable/disable on path
+ * @hor_ver_bin :           horizontal vertical binning enable/disable on path
+ * @num_bytes_out:          Number of bytes out
+ * @irq_handle:             IRQ handle
+ * @err_irq_handle:         Error IRQ handle
+ * @discard_irq_handle:     IRQ handle for SOF when discarding initial frames
+ * @irq_reg_idx:            IRQ Reg index
+ * @sof_cnt:                SOF counter
+ * @num_frames_discard:     number of frames to discard
+ * @sync_mode   :           Sync mode--> master/slave/none
+ * @vfr_en   :              flag to indicate if variable frame rate is enabled
+ * @frame_id_dec_en:        flag to indicate if frame id decoding is enabled
+ * @crop_enable:            flag to indicate crop enable
+ * @drop_enable:            flag to indicate drop enable
+ * @discard_init_frames:    discard initial frames
+ * @skip_discard_frame_cfg: Skip handling discard config, the blob order between
+ *                          discard config and dynamic switch update cannot be gauranteed
+ *                          If we know the number of paths to avoid configuring discard
+ *                          for before processing discard config we can skip it for
+ *                          the corresponding paths
+ * @en_secondary_evt:       Enable secondary evt for this path, to notify
+ *                          hw manager
  *
  */
 struct cam_ife_csid_ver2_path_cfg {
@@ -193,6 +198,7 @@ struct cam_ife_csid_ver2_path_cfg {
 	bool                                drop_enable;
 	bool                                handle_camif_irq;
 	bool                                discard_init_frames;
+	bool                                skip_discard_frame_cfg;
 	bool                                en_secondary_evt;
 };
 

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

@@ -390,7 +390,30 @@ struct cam_ife_csid_offline_cmd_update_args {
  * @mup:                MUP for incoming VC of next frame
  */
 struct cam_ife_csid_mup_update_args {
-	uint32_t                           mup;
+	uint32_t mup;
+};
+
+/*
+ * struct cam_ife_csid_discard_frame_cfg_update:
+ *
+ * @reset_discard_cfg:  Set if discard config needs to be reset
+ * @num_exposures:      Number of current exposures for sHDR
+ */
+struct cam_ife_csid_discard_frame_cfg_update {
+	uint32_t num_exposures;
+	bool     reset_discard_cfg;
+};
+
+
+/*
+ * struct cam_ife_csid_mode_switch_update_args:
+ *
+ * @mup_args:         MUP related arguments
+ * @exp_update_args:  Exposure update arguments
+ */
+struct cam_ife_csid_mode_switch_update_args {
+	struct cam_ife_csid_mup_update_args          mup_args;
+	struct cam_ife_csid_discard_frame_cfg_update exp_update_args;
 };
 
 /*

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -184,7 +184,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_IFE_CSID_TOP_CONFIG,
 	CAM_IFE_CSID_PROGRAM_OFFLINE_CMD,
 	CAM_IFE_CSID_SET_DUAL_SYNC_CONFIG,
-	CAM_ISP_HW_CMD_CSID_MUP_UPDATE,
+	CAM_ISP_HW_CMD_CSID_DYNAMIC_SWITCH_UPDATE,
 	CAM_ISP_HW_CMD_CSID_DISCARD_INIT_FRAMES,
 	CAM_ISP_HW_CMD_BUF_UPDATE,
 	CAM_ISP_HW_CMD_BUF_UPDATE_RM,

+ 12 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_rd.c

@@ -79,10 +79,10 @@ struct cam_sfe_bus_rd_common_data {
 };
 
 struct cam_sfe_bus_rd_rm_resource_data {
-	uint32_t             index;
 	struct cam_sfe_bus_rd_common_data            *common_data;
 	struct cam_sfe_bus_rd_reg_offset_bus_client  *hw_regs;
 	void                *ctx;
+	uint32_t             index;
 	uint32_t             min_vbi;
 	uint32_t             fs_mode;
 	uint32_t             hbi_count;
@@ -95,10 +95,11 @@ struct cam_sfe_bus_rd_rm_resource_data {
 	uint32_t             burst_len;
 	uint32_t             en_cfg;
 	uint32_t             input_if_cmd;
-	bool                 enable_caching;
 	uint32_t             cache_cfg;
 	uint32_t             current_scid;
 	uint32_t             offset;
+	bool                 enable_caching;
+	bool                 enable_disable_cfg_done;
 };
 
 struct cam_sfe_bus_rd_data {
@@ -404,6 +405,7 @@ static int cam_sfe_bus_acquire_rm(
 	rsrc_data->latency_buf_allocation =
 		BUS_RD_DEFAULT_LATENCY_BUF_ALLOC;
 	rsrc_data->enable_caching =  false;
+	rsrc_data->enable_disable_cfg_done = false;
 	rsrc_data->offset = 0;
 	/* Default register value */
 	rsrc_data->cache_cfg = 0x20;
@@ -459,7 +461,10 @@ static int cam_sfe_bus_start_rm(struct cam_isp_resource_node *rm_res)
 		rm_data->hw_regs->unpacker_cfg);
 	cam_io_w_mb(rm_data->latency_buf_allocation, common_data->mem_base +
 		rm_data->hw_regs->latency_buf_allocation);
-	cam_io_w_mb(0x1, common_data->mem_base + rm_data->hw_regs->cfg);
+
+	/* Ignore if already configured via CDM */
+	if (!rm_data->enable_disable_cfg_done)
+		cam_io_w_mb(0x1, common_data->mem_base + rm_data->hw_regs->cfg);
 
 	rm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
 
@@ -486,6 +491,7 @@ static int cam_sfe_bus_stop_rm(struct cam_isp_resource_node *rm_res)
 
 	rm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
 	rsrc_data->enable_caching =  false;
+	rsrc_data->enable_disable_cfg_done = false;
 	rsrc_data->offset = 0;
 
 	CAM_DBG(CAM_SFE, "SFE:%d RM:%d stopped",
@@ -1450,6 +1456,9 @@ static int cam_sfe_bus_rd_update_rm_core_cfg(
 		}
 
 		rm_data = sfe_bus_rd_data->rm_res[i]->res_priv;
+		/* To avoid AHB write @ stream on */
+		rm_data->enable_disable_cfg_done = true;
+
 		CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
 			rm_data->hw_regs->cfg, enable_disable);
 		CAM_DBG(CAM_SFE, "SFE:%d RM:%d cfg:0x%x",