Browse Source

msm: camera: isp: Update scratch buffer scheme for IFE/SFE

For ePCR/PCRs allow different combinations of scratch buffer
and ZSL buffer to be applied for different SFE/IFE ports.

CRs-Fixed: 3110947
Change-Id: I11677deaaa820955a2bc408bf90a848660ab831a
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 3 years ago
parent
commit
b9aae5eaa6
2 changed files with 305 additions and 179 deletions
  1. 234 116
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
  2. 71 63
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

+ 234 - 116
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -76,7 +76,7 @@ static int cam_ife_hw_mgr_event_handler(
 	void                                *evt_info);
 	void                                *evt_info);
 
 
 static int cam_ife_mgr_prog_default_settings(
 static int cam_ife_mgr_prog_default_settings(
-	bool need_rup_aup, struct cam_ife_hw_mgr_ctx *ctx);
+	bool is_streamon, struct cam_ife_hw_mgr_ctx *ctx);
 
 
 static int cam_ife_mgr_cmd_get_sof_timestamp(struct cam_ife_hw_mgr_ctx *ife_ctx,
 static int cam_ife_mgr_cmd_get_sof_timestamp(struct cam_ife_hw_mgr_ctx *ife_ctx,
 	uint64_t *time_stamp, uint64_t *boot_time_stamp, uint64_t *prev_time_stamp);
 	uint64_t *time_stamp, uint64_t *boot_time_stamp, uint64_t *prev_time_stamp);
@@ -3529,7 +3529,7 @@ static int cam_ife_hw_mgr_acquire_csid_rdi_util(
 			 */
 			 */
 			if (ife_ctx->flags.is_aeb_mode) {
 			if (ife_ctx->flags.is_aeb_mode) {
 				if ((out_port->res_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
 				if ((out_port->res_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
-					ife_ctx->sfe_info.num_fetches) {
+					ife_ctx->scratch_buf_info.num_fetches) {
 					csid_acquire.sec_evt_config.en_secondary_evt = true;
 					csid_acquire.sec_evt_config.en_secondary_evt = true;
 					csid_acquire.sec_evt_config.evt_type = CAM_IFE_CSID_EVT_SOF;
 					csid_acquire.sec_evt_config.evt_type = CAM_IFE_CSID_EVT_SOF;
 					CAM_DBG(CAM_ISP,
 					CAM_DBG(CAM_ISP,
@@ -3819,7 +3819,7 @@ static int cam_ife_mgr_check_and_update_fe_v2(
 			in_port->res_type);
 			in_port->res_type);
 		is_sfe_rd = cam_ife_mgr_check_for_sfe_rd(in_port->sfe_in_path_type);
 		is_sfe_rd = cam_ife_mgr_check_for_sfe_rd(in_port->sfe_in_path_type);
 		if (is_sfe_rd)
 		if (is_sfe_rd)
-			ife_ctx->sfe_info.num_fetches++;
+			ife_ctx->scratch_buf_info.num_fetches++;
 
 
 		if ((!fetch_cfg) && ((in_port->res_type == CAM_ISP_IFE_IN_RES_RD) ||
 		if ((!fetch_cfg) && ((in_port->res_type == CAM_ISP_IFE_IN_RES_RD) ||
 			(is_sfe_rd))) {
 			(is_sfe_rd))) {
@@ -3851,7 +3851,7 @@ static int cam_ife_mgr_check_and_update_fe_v2(
 		ife_ctx->flags.is_offline,
 		ife_ctx->flags.is_offline,
 		ife_ctx->flags.is_sfe_fs,
 		ife_ctx->flags.is_sfe_fs,
 		ife_ctx->flags.is_sfe_shdr,
 		ife_ctx->flags.is_sfe_shdr,
-		ife_ctx->sfe_info.num_fetches);
+		ife_ctx->scratch_buf_info.num_fetches);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -4882,6 +4882,15 @@ static int cam_ife_mgr_acquire_get_unified_structure(
 	return 0;
 	return 0;
 }
 }
 
 
+static inline void cam_ife_mgr_reset_streamon_scratch_cfg(
+	struct cam_ife_hw_mgr_ctx *ctx)
+{
+	ctx->scratch_buf_info.ife_scratch_config->skip_scratch_cfg_streamon = false;
+	ctx->scratch_buf_info.sfe_scratch_config->skip_scratch_cfg_streamon = false;
+	ctx->scratch_buf_info.ife_scratch_config->streamon_buf_mask = 0;
+	ctx->scratch_buf_info.sfe_scratch_config->streamon_buf_mask = 0;
+}
+
 /* entry function: acquire_hw */
 /* entry function: acquire_hw */
 static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 {
 {
@@ -5096,25 +5105,25 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		(ife_ctx->flags.is_sfe_fs)) {
 		(ife_ctx->flags.is_sfe_fs)) {
 		acquire_args->op_flags |=
 		acquire_args->op_flags |=
 			CAM_IFE_CTX_APPLY_DEFAULT_CFG;
 			CAM_IFE_CTX_APPLY_DEFAULT_CFG;
-		ife_ctx->sfe_info.scratch_config =
+		ife_ctx->scratch_buf_info.sfe_scratch_config =
 			kzalloc(sizeof(struct cam_sfe_scratch_buf_cfg), GFP_KERNEL);
 			kzalloc(sizeof(struct cam_sfe_scratch_buf_cfg), GFP_KERNEL);
-		if (!ife_ctx->sfe_info.scratch_config) {
+		if (!ife_ctx->scratch_buf_info.sfe_scratch_config) {
 			CAM_ERR(CAM_ISP, "Failed to allocate SFE scratch config");
 			CAM_ERR(CAM_ISP, "Failed to allocate SFE scratch config");
 			rc = -ENOMEM;
 			rc = -ENOMEM;
 			goto free_cdm_cmd;
 			goto free_cdm_cmd;
 		}
 		}
 
 
-		ife_ctx->sfe_info.ife_scratch_config =
+		ife_ctx->scratch_buf_info.ife_scratch_config =
 			kzalloc(sizeof(struct cam_ife_scratch_buf_cfg), GFP_KERNEL);
 			kzalloc(sizeof(struct cam_ife_scratch_buf_cfg), GFP_KERNEL);
-		if (!ife_ctx->sfe_info.ife_scratch_config) {
+		if (!ife_ctx->scratch_buf_info.ife_scratch_config) {
 			CAM_ERR(CAM_ISP, "Failed to allocate IFE scratch config");
 			CAM_ERR(CAM_ISP, "Failed to allocate IFE scratch config");
 			rc = -ENOMEM;
 			rc = -ENOMEM;
-			kfree(ife_ctx->sfe_info.scratch_config);
+			kfree(ife_ctx->scratch_buf_info.sfe_scratch_config);
 			goto free_cdm_cmd;
 			goto free_cdm_cmd;
 		}
 		}
 
 
 		/* Set scratch by default at stream on */
 		/* Set scratch by default at stream on */
-		ife_ctx->sfe_info.skip_scratch_cfg_streamon = false;
+		cam_ife_mgr_reset_streamon_scratch_cfg(ife_ctx);
 	}
 	}
 
 
 	acquire_args->ctxt_to_hw_map = ife_ctx;
 	acquire_args->ctxt_to_hw_map = ife_ctx;
@@ -6424,15 +6433,14 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 	/* reset scratch buffer/mup expect INIT again for UMD triggered stop/flush */
 	/* reset scratch buffer/mup expect INIT again for UMD triggered stop/flush */
 	if (!stop_isp->is_internal_stop) {
 	if (!stop_isp->is_internal_stop) {
 		ctx->current_mup = 0;
 		ctx->current_mup = 0;
-		if (ctx->sfe_info.scratch_config)
-			memset(ctx->sfe_info.scratch_config, 0,
+		if (ctx->scratch_buf_info.sfe_scratch_config)
+			memset(ctx->scratch_buf_info.sfe_scratch_config, 0,
 				sizeof(struct cam_sfe_scratch_buf_cfg));
 				sizeof(struct cam_sfe_scratch_buf_cfg));
 
 
-		if (ctx->sfe_info.ife_scratch_config)
-			memset(ctx->sfe_info.ife_scratch_config, 0,
+		if (ctx->scratch_buf_info.ife_scratch_config)
+			memset(ctx->scratch_buf_info.ife_scratch_config, 0,
 				sizeof(struct cam_ife_scratch_buf_cfg));
 				sizeof(struct cam_ife_scratch_buf_cfg));
 	}
 	}
-	ctx->sfe_info.skip_scratch_cfg_streamon = false;
 
 
 	cam_ife_mgr_pause_hw(ctx);
 	cam_ife_mgr_pause_hw(ctx);
 
 
@@ -6975,12 +6983,13 @@ start_only:
 		}
 		}
 	}
 	}
 
 
-	if ((ctx->flags.is_sfe_fs || ctx->flags.is_sfe_shdr) &&
-		(!ctx->sfe_info.skip_scratch_cfg_streamon)) {
-		rc = cam_ife_mgr_prog_default_settings(false, ctx);
+	if ((ctx->flags.is_sfe_fs) || (ctx->flags.is_sfe_shdr)) {
+		rc = cam_ife_mgr_prog_default_settings(true, ctx);
 		if (rc)
 		if (rc)
 			goto err;
 			goto err;
-		ctx->sfe_info.skip_scratch_cfg_streamon = false;
+
+		/* Reset streamon related scratch buffer config */
+		cam_ife_mgr_reset_streamon_scratch_cfg(ctx);
 	}
 	}
 
 
 	CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d",
 	CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d",
@@ -7122,14 +7131,14 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
 	ctx->last_cdm_done_req = 0;
 	ctx->last_cdm_done_req = 0;
 	ctx->left_hw_idx = CAM_IFE_CSID_HW_NUM_MAX;
 	ctx->left_hw_idx = CAM_IFE_CSID_HW_NUM_MAX;
 	ctx->right_hw_idx = CAM_IFE_CSID_HW_NUM_MAX;
 	ctx->right_hw_idx = CAM_IFE_CSID_HW_NUM_MAX;
-	ctx->sfe_info.num_fetches = 0;
+	ctx->scratch_buf_info.num_fetches = 0;
 	ctx->num_acq_vfe_out = 0;
 	ctx->num_acq_vfe_out = 0;
 	ctx->num_acq_sfe_out = 0;
 	ctx->num_acq_sfe_out = 0;
 	ctx->buf_done_controller = NULL;
 	ctx->buf_done_controller = NULL;
-	kfree(ctx->sfe_info.scratch_config);
-	kfree(ctx->sfe_info.ife_scratch_config);
-	ctx->sfe_info.scratch_config = NULL;
-	ctx->sfe_info.ife_scratch_config = NULL;
+	kfree(ctx->scratch_buf_info.sfe_scratch_config);
+	kfree(ctx->scratch_buf_info.ife_scratch_config);
+	ctx->scratch_buf_info.sfe_scratch_config = NULL;
+	ctx->scratch_buf_info.ife_scratch_config = NULL;
 
 
 	memset(&ctx->flags, 0, sizeof(struct cam_ife_hw_mgr_ctx_flags));
 	memset(&ctx->flags, 0, sizeof(struct cam_ife_hw_mgr_ctx_flags));
 	atomic_set(&ctx->overflow_pending, 0);
 	atomic_set(&ctx->overflow_pending, 0);
@@ -7553,7 +7562,7 @@ static int cam_isp_blob_ife_scratch_buf_update(
 
 
 	ctx = prepare->ctxt_to_hw_map;
 	ctx = prepare->ctxt_to_hw_map;
 	ife_hw_mgr = ctx->hw_mgr;
 	ife_hw_mgr = ctx->hw_mgr;
-	ife_scratch_config = ctx->sfe_info.ife_scratch_config;
+	ife_scratch_config = ctx->scratch_buf_info.ife_scratch_config;
 
 
 	for (i = 0; i < scratch_config->num_ports; i++) {
 	for (i = 0; i < scratch_config->num_ports; i++) {
 		buffer_info = &scratch_config->port_scratch_cfg[i];
 		buffer_info = &scratch_config->port_scratch_cfg[i];
@@ -7629,18 +7638,20 @@ static int cam_isp_blob_sfe_scratch_buf_update(
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 
 
-		port_info = &ctx->sfe_info.scratch_config->buf_info[res_id_out];
+		port_info = &ctx->scratch_buf_info.sfe_scratch_config->buf_info[res_id_out];
 		rc = cam_isp_scratch_buf_update_util(buffer_info, port_info);
 		rc = cam_isp_scratch_buf_update_util(buffer_info, port_info);
 		if (rc)
 		if (rc)
 			goto end;
 			goto end;
 
 
-		ctx->sfe_info.scratch_config->num_config++;
+		ctx->scratch_buf_info.sfe_scratch_config->num_config++;
 	}
 	}
 
 
-	if (ctx->sfe_info.scratch_config->num_config != ctx->sfe_info.num_fetches) {
+	if (ctx->scratch_buf_info.sfe_scratch_config->num_config !=
+		ctx->scratch_buf_info.num_fetches) {
 		CAM_ERR(CAM_ISP,
 		CAM_ERR(CAM_ISP,
 			"Mismatch in number of scratch buffers provided: %u expected: %u",
 			"Mismatch in number of scratch buffers provided: %u expected: %u",
-			ctx->sfe_info.scratch_config->num_config, ctx->sfe_info.num_fetches);
+			ctx->scratch_buf_info.sfe_scratch_config->num_config,
+			ctx->scratch_buf_info.num_fetches);
 		rc = -EINVAL;
 		rc = -EINVAL;
 	}
 	}
 
 
@@ -7715,10 +7726,10 @@ static int cam_isp_blob_sfe_exp_order_update(
 		}
 		}
 
 
 		if ((order_cfg->res_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
 		if ((order_cfg->res_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
-			ctx->sfe_info.num_fetches) {
+			ctx->scratch_buf_info.num_fetches) {
 			CAM_DBG(CAM_ISP,
 			CAM_DBG(CAM_ISP,
 				"Skip cache config for resource: 0x%x, active fetches: %u [exp_order: %d %d] in %u ctx",
 				"Skip cache config for resource: 0x%x, active fetches: %u [exp_order: %d %d] in %u ctx",
-				order_cfg->res_type, ctx->sfe_info.num_fetches,
+				order_cfg->res_type, ctx->scratch_buf_info.num_fetches,
 				i, exp_order_max, ctx->ctx_index);
 				i, exp_order_max, ctx->ctx_index);
 			continue;
 			continue;
 		}
 		}
@@ -7885,7 +7896,7 @@ static int cam_isp_blob_sfe_update_fetch_core_cfg(
 		if ((ctx->ctx_config &
 		if ((ctx->ctx_config &
 			CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) &&
 			CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) &&
 			((res_id - CAM_ISP_SFE_IN_RD_0) >=
 			((res_id - CAM_ISP_SFE_IN_RD_0) >=
-			ctx->sfe_info.scratch_config->updated_num_exp))
+			ctx->scratch_buf_info.sfe_scratch_config->updated_num_exp))
 			enable = false;
 			enable = false;
 		else
 		else
 			enable = true;
 			enable = true;
@@ -7898,7 +7909,7 @@ static int cam_isp_blob_sfe_update_fetch_core_cfg(
 			"SFE:%u RM: %u res_id: 0x%x enable: %u num_exp: %u",
 			"SFE:%u RM: %u res_id: 0x%x enable: %u num_exp: %u",
 			blob_info->base_info->idx,
 			blob_info->base_info->idx,
 			(res_id - CAM_ISP_SFE_IN_RD_0), res_id, enable,
 			(res_id - CAM_ISP_SFE_IN_RD_0), res_id, enable,
-			ctx->sfe_info.scratch_config->updated_num_exp);
+			ctx->scratch_buf_info.sfe_scratch_config->updated_num_exp);
 
 
 		rc = cam_isp_add_cmd_buf_update(
 		rc = cam_isp_add_cmd_buf_update(
 			hw_mgr_res, blob_type,
 			hw_mgr_res, blob_type,
@@ -8546,7 +8557,7 @@ static int cam_ife_hw_mgr_update_scratch_offset(
 	struct cam_ife_sfe_scratch_buf_info       *port_info;
 	struct cam_ife_sfe_scratch_buf_info       *port_info;
 
 
 	if ((wm_config->port_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
 	if ((wm_config->port_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
-		ctx->sfe_info.num_fetches)
+		ctx->scratch_buf_info.num_fetches)
 		return 0;
 		return 0;
 
 
 	res_id = wm_config->port_type & 0xFF;
 	res_id = wm_config->port_type & 0xFF;
@@ -8557,14 +8568,14 @@ static int cam_ife_hw_mgr_update_scratch_offset(
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (!ctx->sfe_info.scratch_config->buf_info[res_id].config_done) {
+	if (!ctx->scratch_buf_info.sfe_scratch_config->buf_info[res_id].config_done) {
 		CAM_ERR(CAM_ISP,
 		CAM_ERR(CAM_ISP,
 			"Scratch buffer not configured on ctx: %u for res: %u",
 			"Scratch buffer not configured on ctx: %u for res: %u",
 			ctx->ctx_index, res_id);
 			ctx->ctx_index, res_id);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	port_info = &ctx->sfe_info.scratch_config->buf_info[res_id];
+	port_info = &ctx->scratch_buf_info.sfe_scratch_config->buf_info[res_id];
 	port_info->offset = wm_config->offset;
 	port_info->offset = wm_config->offset;
 
 
 	CAM_DBG(CAM_ISP, "Scratch addr: 0x%x offset: %u updated for: %s",
 	CAM_DBG(CAM_ISP, "Scratch addr: 0x%x offset: %u updated for: %s",
@@ -10134,7 +10145,7 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
 			prepare->priv;
 			prepare->priv;
 		mup_config = (struct cam_isp_mode_switch_info *)blob_data;
 		mup_config = (struct cam_isp_mode_switch_info *)blob_data;
 		if (ife_mgr_ctx->flags.is_sfe_shdr) {
 		if (ife_mgr_ctx->flags.is_sfe_shdr) {
-			ife_mgr_ctx->sfe_info.scratch_config->updated_num_exp =
+			ife_mgr_ctx->scratch_buf_info.sfe_scratch_config->updated_num_exp =
 				mup_config->num_expoures;
 				mup_config->num_expoures;
 			prepare_hw_data->num_exp = mup_config->num_expoures;
 			prepare_hw_data->num_exp = mup_config->num_expoures;
 
 
@@ -10260,6 +10271,15 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
 	return rc;
 	return rc;
 }
 }
 
 
+static inline bool cam_ife_mgr_validate_for_io_buffers(
+	uint32_t port_id, uint32_t scratch_cfg_mask)
+{
+	if (BIT(port_id) & scratch_cfg_mask)
+		return true;
+
+	return false;
+}
+
 static inline bool cam_isp_sfe_validate_for_scratch_buf_config(
 static inline bool cam_isp_sfe_validate_for_scratch_buf_config(
 	uint32_t res_idx, struct cam_ife_hw_mgr_ctx  *ctx,
 	uint32_t res_idx, struct cam_ife_hw_mgr_ctx  *ctx,
 	bool default_settings)
 	bool default_settings)
@@ -10267,13 +10287,13 @@ static inline bool cam_isp_sfe_validate_for_scratch_buf_config(
 	uint32_t curr_num_exp;
 	uint32_t curr_num_exp;
 
 
 	/* check for num exposures for static mode but using RDI1-2 without RD1-2 */
 	/* check for num exposures for static mode but using RDI1-2 without RD1-2 */
-	if (res_idx >= ctx->sfe_info.num_fetches)
+	if (res_idx >= ctx->scratch_buf_info.num_fetches)
 		return true;
 		return true;
 
 
 	if (default_settings)
 	if (default_settings)
 		curr_num_exp = ctx->curr_num_exp;
 		curr_num_exp = ctx->curr_num_exp;
 	else
 	else
-		curr_num_exp = ctx->sfe_info.scratch_config->updated_num_exp;
+		curr_num_exp = ctx->scratch_buf_info.sfe_scratch_config->updated_num_exp;
 
 
 	/* check for num exposures for dynamic mode */
 	/* check for num exposures for dynamic mode */
 	if ((ctx->ctx_config &
 	if ((ctx->ctx_config &
@@ -10369,7 +10389,7 @@ static int cam_isp_sfe_add_scratch_buffer_cfg(
 
 
 	io_cfg_used_bytes = 0;
 	io_cfg_used_bytes = 0;
 	CAM_DBG(CAM_ISP, "num_ports: %u",
 	CAM_DBG(CAM_ISP, "num_ports: %u",
-		ctx->sfe_info.scratch_config->num_config);
+		ctx->scratch_buf_info.sfe_scratch_config->num_config);
 
 
 	/* Update RDI WMs */
 	/* Update RDI WMs */
 	for (i = 0; i < CAM_SFE_FE_RDI_NUM_MAX; i++) {
 	for (i = 0; i < CAM_SFE_FE_RDI_NUM_MAX; i++) {
@@ -10401,12 +10421,13 @@ static int cam_isp_sfe_add_scratch_buffer_cfg(
 				continue;
 				continue;
 
 
 			/* check if buffer provided for this RDI is from userspace */
 			/* check if buffer provided for this RDI is from userspace */
-			if (sfe_rdi_cfg_mask & (1 << (res_id - CAM_ISP_SFE_OUT_RES_RDI_0)))
+			if (cam_ife_mgr_validate_for_io_buffers(
+				(res_id - CAM_ISP_SFE_OUT_RES_RDI_0), sfe_rdi_cfg_mask))
 				continue;
 				continue;
 
 
 			cpu_addr = kmd_buf_info->cpu_addr +
 			cpu_addr = kmd_buf_info->cpu_addr +
 				kmd_buf_info->used_bytes / 4 + io_cfg_used_bytes / 4;
 				kmd_buf_info->used_bytes / 4 + io_cfg_used_bytes / 4;
-			buf_info = &ctx->sfe_info.scratch_config->buf_info[
+			buf_info = &ctx->scratch_buf_info.sfe_scratch_config->buf_info[
 				res_id - CAM_ISP_SFE_OUT_RES_RDI_0];
 				res_id - CAM_ISP_SFE_OUT_RES_RDI_0];
 
 
 			/* Check if scratch available for this resource */
 			/* Check if scratch available for this resource */
@@ -10463,13 +10484,14 @@ static int cam_isp_sfe_add_scratch_buffer_cfg(
 				continue;
 				continue;
 
 
 			/* check if buffer provided for this RM is from userspace */
 			/* check if buffer provided for this RM is from userspace */
-			if (sfe_rdi_cfg_mask & (1 << (res_id - CAM_ISP_SFE_IN_RD_0)))
+			if (cam_ife_mgr_validate_for_io_buffers(
+				(res_id - CAM_ISP_SFE_IN_RD_0), sfe_rdi_cfg_mask))
 				continue;
 				continue;
 
 
 			cpu_addr = kmd_buf_info->cpu_addr +
 			cpu_addr = kmd_buf_info->cpu_addr +
 				kmd_buf_info->used_bytes  / 4 +
 				kmd_buf_info->used_bytes  / 4 +
 				io_cfg_used_bytes / 4;
 				io_cfg_used_bytes / 4;
-			buf_info = &ctx->sfe_info.scratch_config->buf_info[
+			buf_info = &ctx->scratch_buf_info.sfe_scratch_config->buf_info[
 				res_id - CAM_ISP_SFE_IN_RD_0];
 				res_id - CAM_ISP_SFE_IN_RD_0];
 
 
 			CAM_DBG(CAM_ISP, "RM res_id: 0x%x idx: %u io_addr: %pK",
 			CAM_DBG(CAM_ISP, "RM res_id: 0x%x idx: %u io_addr: %pK",
@@ -10520,15 +10542,15 @@ static int cam_isp_ife_add_scratch_buffer_cfg(
 	io_cfg_used_bytes = 0;
 	io_cfg_used_bytes = 0;
 
 
 	/* Update scratch buffer for IFE WMs */
 	/* Update scratch buffer for IFE WMs */
-	for (i = 0; i < ctx->sfe_info.ife_scratch_config->num_config; i++) {
+	for (i = 0; i < ctx->scratch_buf_info.ife_scratch_config->num_config; i++) {
 		/*
 		/*
 		 * Configure scratch only if the bit mask is not set for the given port,
 		 * Configure scratch only if the bit mask is not set for the given port,
 		 * this is determined after parsing all the IO config buffers
 		 * this is determined after parsing all the IO config buffers
 		 */
 		 */
-		if ((BIT(i) & scratch_cfg_mask))
+		if (cam_ife_mgr_validate_for_io_buffers(i, scratch_cfg_mask))
 			continue;
 			continue;
 
 
-		res_id = ctx->sfe_info.ife_scratch_config->buf_info[i].res_id & 0xFF;
+		res_id = ctx->scratch_buf_info.ife_scratch_config->buf_info[i].res_id & 0xFF;
 
 
 		hw_mgr_res = &res_list_isp_out[res_id];
 		hw_mgr_res = &res_list_isp_out[res_id];
 		for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
 		for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
@@ -10553,7 +10575,7 @@ static int cam_isp_ife_add_scratch_buffer_cfg(
 
 
 			cpu_addr = kmd_buf_info->cpu_addr +
 			cpu_addr = kmd_buf_info->cpu_addr +
 				kmd_buf_info->used_bytes / 4 + io_cfg_used_bytes / 4;
 				kmd_buf_info->used_bytes / 4 + io_cfg_used_bytes / 4;
-			buf_info = &ctx->sfe_info.ife_scratch_config->buf_info[i];
+			buf_info = &ctx->scratch_buf_info.ife_scratch_config->buf_info[i];
 			CAM_DBG(CAM_ISP, "WM res_id: 0x%x io_addr: %pK",
 			CAM_DBG(CAM_ISP, "WM res_id: 0x%x io_addr: %pK",
 				hw_mgr_res->hw_res[j]->res_id, buf_info->io_addr);
 				hw_mgr_res->hw_res[j]->res_id, buf_info->io_addr);
 
 
@@ -10790,22 +10812,98 @@ static void cam_ife_hw_mgr_check_if_scratch_is_needed(
 
 
 	/* For SFE use number of fetches = number of scratch buffers needed */
 	/* For SFE use number of fetches = number of scratch buffers needed */
 	check_for_scratch->sfe_scratch_res_info.num_active_fe_rdis =
 	check_for_scratch->sfe_scratch_res_info.num_active_fe_rdis =
-		ctx->sfe_info.num_fetches;
+		ctx->scratch_buf_info.num_fetches;
 	check_for_scratch->validate_for_sfe = true;
 	check_for_scratch->validate_for_sfe = true;
 
 
 	/* Check if IFE has any scratch buffer */
 	/* Check if IFE has any scratch buffer */
-	if (ctx->sfe_info.ife_scratch_config->num_config) {
+	if (ctx->scratch_buf_info.ife_scratch_config->num_config) {
 		int i;
 		int i;
 
 
 		check_for_scratch->validate_for_ife = true;
 		check_for_scratch->validate_for_ife = true;
-		for (i = 0; i < ctx->sfe_info.ife_scratch_config->num_config; i++) {
+		for (i = 0; i < ctx->scratch_buf_info.ife_scratch_config->num_config; i++) {
 			check_for_scratch->ife_scratch_res_info.ife_scratch_resources[i] =
 			check_for_scratch->ife_scratch_res_info.ife_scratch_resources[i] =
-				ctx->sfe_info.ife_scratch_config->buf_info[i].res_id;
+				ctx->scratch_buf_info.ife_scratch_config->buf_info[i].res_id;
 			check_for_scratch->ife_scratch_res_info.num_ports++;
 			check_for_scratch->ife_scratch_res_info.num_ports++;
 		}
 		}
 	}
 	}
 }
 }
 
 
+static int cam_ife_hw_mgr_sfe_scratch_buf_update(
+	int32_t                                  opcode_type,
+	uint32_t                                 base_idx,
+	struct cam_kmd_buf_info                 *kmd_buf,
+	struct cam_hw_prepare_update_args       *prepare,
+	struct cam_ife_hw_mgr_ctx               *ctx,
+	struct cam_isp_sfe_scratch_buf_res_info *sfe_res_info)
+{
+	int rc = 0;
+
+	/* If there are no output provided buffers */
+	if ((sfe_res_info->sfe_rdi_cfg_mask) !=
+		((1 << ctx->scratch_buf_info.num_fetches) - 1)) {
+		/* For update packets add scratch buffer */
+		if (opcode_type == CAM_ISP_PACKET_UPDATE_DEV) {
+			CAM_DBG(CAM_ISP,
+				"Adding SFE scratch buffer cfg_mask expected: 0x%x actual: 0x%x",
+				((1 << ctx->scratch_buf_info.num_fetches) - 1),
+				sfe_res_info->sfe_rdi_cfg_mask);
+			rc = cam_isp_sfe_add_scratch_buffer_cfg(
+				ctx->base[base_idx].idx, sfe_res_info->sfe_rdi_cfg_mask,
+				prepare, kmd_buf, ctx->res_list_sfe_out,
+				&ctx->res_list_ife_in_rd, ctx);
+			if (rc)
+				goto end;
+		} else if (opcode_type == CAM_ISP_PACKET_INIT_DEV) {
+			/* For INIT packets update mask which is applied at streamon */
+			ctx->scratch_buf_info.sfe_scratch_config->streamon_buf_mask =
+				sfe_res_info->sfe_rdi_cfg_mask;
+		}
+	} else {
+		/* If buffers are provided for ePCR skip scratch buffer at stream on */
+		if (opcode_type == CAM_ISP_PACKET_INIT_DEV)
+			ctx->scratch_buf_info.sfe_scratch_config->skip_scratch_cfg_streamon = true;
+	}
+
+end:
+	return rc;
+}
+
+static int cam_ife_hw_mgr_ife_scratch_buf_update(
+	int32_t                                  opcode_type,
+	uint32_t                                 base_idx,
+	struct cam_kmd_buf_info                 *kmd_buf,
+	struct cam_hw_prepare_update_args       *prepare,
+	struct cam_ife_hw_mgr_ctx               *ctx,
+	struct cam_isp_ife_scratch_buf_res_info *ife_res_info)
+{
+	int rc = 0;
+
+	if ((ife_res_info->ife_scratch_cfg_mask) !=
+		((1 << ife_res_info->num_ports) - 1)) {
+		if (opcode_type == CAM_ISP_PACKET_UPDATE_DEV) {
+			CAM_DBG(CAM_ISP,
+				"Adding IFE scratch buffer cfg_mask expected: 0x%x actual: 0x%x",
+				((1 << ife_res_info->num_ports) - 1),
+				ife_res_info->ife_scratch_cfg_mask);
+			rc = cam_isp_ife_add_scratch_buffer_cfg(
+				ctx->base[base_idx].idx,
+				ife_res_info->ife_scratch_cfg_mask, prepare,
+				kmd_buf, ctx->res_list_ife_out, ctx);
+			if (rc)
+				goto end;
+		} else if (opcode_type == CAM_ISP_PACKET_INIT_DEV) {
+			ctx->scratch_buf_info.ife_scratch_config->streamon_buf_mask =
+				ife_res_info->ife_scratch_cfg_mask;
+		}
+	} else {
+		if (opcode_type == CAM_ISP_PACKET_INIT_DEV)
+			ctx->scratch_buf_info.ife_scratch_config->skip_scratch_cfg_streamon = true;
+	}
+
+end:
+	return rc;
+}
+
 static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 	void *prepare_hw_update_args)
 	void *prepare_hw_update_args)
 {
 {
@@ -10951,35 +11049,23 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 		}
 		}
 
 
 		/*
 		/*
-		 * Add scratch buffer if there no output buffer for RDI WMs/RMs
+		 * Add scratch buffer if there no output buffer for SFE/IFE clients
 		 * only for UPDATE packets. For INIT we could have ePCR enabled
 		 * only for UPDATE packets. For INIT we could have ePCR enabled
 		 * based on that decide to configure scratch via AHB at
 		 * based on that decide to configure scratch via AHB at
-		 * stream on or not
+		 * stream on or not. It's possible that in ePCR one HW could
+		 * have buffers and the other might not. Handle different
+		 * combinations for different HWs
 		 */
 		 */
 		if ((check_for_scratch.validate_for_sfe) &&
 		if ((check_for_scratch.validate_for_sfe) &&
 			(ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) && (fill_sfe_fence)) {
 			(ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) && (fill_sfe_fence)) {
 			struct cam_isp_sfe_scratch_buf_res_info *sfe_res_info =
 			struct cam_isp_sfe_scratch_buf_res_info *sfe_res_info =
 				&check_for_scratch.sfe_scratch_res_info;
 				&check_for_scratch.sfe_scratch_res_info;
 
 
-			if ((sfe_res_info->sfe_rdi_cfg_mask) !=
-				((1 << ctx->sfe_info.num_fetches) - 1)) {
-				if (prepare_hw_data->packet_opcode_type ==
-					CAM_ISP_PACKET_UPDATE_DEV) {
-					CAM_DBG(CAM_ISP,
-						"Adding SFE scratch buffer cfg_mask expected: 0x%x actual: 0x%x",
-						((1 << ctx->sfe_info.num_fetches) - 1),
-						sfe_res_info->sfe_rdi_cfg_mask);
-					rc = cam_isp_sfe_add_scratch_buffer_cfg(
-						ctx->base[i].idx, sfe_res_info->sfe_rdi_cfg_mask,
-						prepare, &kmd_buf, ctx->res_list_sfe_out,
-						&ctx->res_list_ife_in_rd, ctx);
-					if (rc)
-						goto end;
-				}
-			} else {
-				if (prepare_hw_data->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV)
-					ctx->sfe_info.skip_scratch_cfg_streamon = true;
-			}
+			rc = cam_ife_hw_mgr_sfe_scratch_buf_update(
+				prepare_hw_data->packet_opcode_type,
+				i, &kmd_buf, prepare, ctx, sfe_res_info);
+			if (rc)
+				goto end;
 		}
 		}
 
 
 		if ((check_for_scratch.validate_for_ife) &&
 		if ((check_for_scratch.validate_for_ife) &&
@@ -10987,23 +11073,11 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
 			struct cam_isp_ife_scratch_buf_res_info *ife_res_info =
 			struct cam_isp_ife_scratch_buf_res_info *ife_res_info =
 				&check_for_scratch.ife_scratch_res_info;
 				&check_for_scratch.ife_scratch_res_info;
 
 
-			/* Config IFE scratch only for update packets only */
-			if ((ife_res_info->ife_scratch_cfg_mask) !=
-				((1 << ife_res_info->num_ports) - 1)) {
-				if (prepare_hw_data->packet_opcode_type ==
-					CAM_ISP_PACKET_UPDATE_DEV) {
-					CAM_DBG(CAM_ISP,
-						"Adding IFE scratch buffer cfg_mask expected: 0x%x actual: 0x%x",
-						((1 << ife_res_info->num_ports) - 1),
-						ife_res_info->ife_scratch_cfg_mask);
-					rc = cam_isp_ife_add_scratch_buffer_cfg(
-						ctx->base[i].idx,
-						ife_res_info->ife_scratch_cfg_mask, prepare,
-						&kmd_buf, ctx->res_list_ife_out, ctx);
-					if (rc)
-						goto end;
-				}
-			}
+			rc = cam_ife_hw_mgr_ife_scratch_buf_update(
+				prepare_hw_data->packet_opcode_type,
+				i, &kmd_buf, prepare, ctx, ife_res_info);
+			if (rc)
+				goto end;
 		}
 		}
 
 
 		/* fence map table entries need to fill only once in the loop */
 		/* fence map table entries need to fill only once in the loop */
@@ -11455,6 +11529,7 @@ int cam_isp_config_csid_rup_aup(
 }
 }
 
 
 static int cam_ife_mgr_configure_scratch_for_ife(
 static int cam_ife_mgr_configure_scratch_for_ife(
+	bool is_streamon,
 	struct cam_ife_hw_mgr_ctx *ctx)
 	struct cam_ife_hw_mgr_ctx *ctx)
 {
 {
 	int i, j, rc = 0;
 	int i, j, rc = 0;
@@ -11464,9 +11539,12 @@ static int cam_ife_mgr_configure_scratch_for_ife(
 	struct cam_ife_scratch_buf_cfg      *ife_buf_info;
 	struct cam_ife_scratch_buf_cfg      *ife_buf_info;
 	struct cam_isp_hw_mgr_res           *res_list_ife_out = NULL;
 	struct cam_isp_hw_mgr_res           *res_list_ife_out = NULL;
 
 
-	ife_buf_info = ctx->sfe_info.ife_scratch_config;
+	ife_buf_info = ctx->scratch_buf_info.ife_scratch_config;
 	res_list_ife_out = ctx->res_list_ife_out;
 	res_list_ife_out = ctx->res_list_ife_out;
 
 
+	if (ctx->scratch_buf_info.ife_scratch_config->skip_scratch_cfg_streamon)
+		goto end;
+
 	for (i = 0; i < ife_buf_info->num_config; i++) {
 	for (i = 0; i < ife_buf_info->num_config; i++) {
 		res_id = ife_buf_info->buf_info[i].res_id & 0xFF;
 		res_id = ife_buf_info->buf_info[i].res_id & 0xFF;
 		port_info = &ife_buf_info->buf_info[i];
 		port_info = &ife_buf_info->buf_info[i];
@@ -11477,6 +11555,11 @@ static int cam_ife_mgr_configure_scratch_for_ife(
 			if (!hw_mgr_res->hw_res[j])
 			if (!hw_mgr_res->hw_res[j])
 				continue;
 				continue;
 
 
+			if ((is_streamon) &&
+				cam_ife_mgr_validate_for_io_buffers(
+				i, ctx->scratch_buf_info.ife_scratch_config->streamon_buf_mask))
+				continue;
+
 			CAM_DBG(CAM_ISP,
 			CAM_DBG(CAM_ISP,
 				"Configure scratch for IFE res: 0x%x io_addr %pK",
 				"Configure scratch for IFE res: 0x%x io_addr %pK",
 				ife_buf_info->buf_info[i].res_id, port_info->io_addr);
 				ife_buf_info->buf_info[i].res_id, port_info->io_addr);
@@ -11486,30 +11569,30 @@ static int cam_ife_mgr_configure_scratch_for_ife(
 				hw_mgr_res->hw_res[j], port_info,
 				hw_mgr_res->hw_res[j], port_info,
 				NULL, NULL);
 				NULL, NULL);
 			if (rc)
 			if (rc)
-				return rc;
+				goto end;
 		}
 		}
 	}
 	}
 
 
+end:
 	return rc;
 	return rc;
 }
 }
 
 
-/*
- * Scratch buffer is for sHDR/FS usescases involing SFE RDI0-2
- * There is no possibility of dual in this case, hence
- * using the scratch buffer provided during INIT corresponding
- * to each left RDIs
- */
-static int cam_ife_mgr_prog_default_settings(
-	bool need_rup_aup, struct cam_ife_hw_mgr_ctx *ctx)
+static int cam_ife_mgr_configure_scratch_for_sfe(
+	bool is_streamon, struct cam_ife_hw_mgr_ctx *ctx)
 {
 {
 	int i, j, res_id, rc = 0;
 	int i, j, res_id, rc = 0;
 	struct cam_isp_hw_mgr_res           *hw_mgr_res;
 	struct cam_isp_hw_mgr_res           *hw_mgr_res;
 	struct cam_ife_sfe_scratch_buf_info *buf_info;
 	struct cam_ife_sfe_scratch_buf_info *buf_info;
+	struct cam_sfe_scratch_buf_cfg      *sfe_scratch_config;
 	struct list_head                    *res_list_in_rd = NULL;
 	struct list_head                    *res_list_in_rd = NULL;
 	struct cam_isp_hw_mgr_res           *res_list_sfe_out = NULL;
 	struct cam_isp_hw_mgr_res           *res_list_sfe_out = NULL;
 
 
 	res_list_in_rd = &ctx->res_list_ife_in_rd;
 	res_list_in_rd = &ctx->res_list_ife_in_rd;
 	res_list_sfe_out = ctx->res_list_sfe_out;
 	res_list_sfe_out = ctx->res_list_sfe_out;
+	sfe_scratch_config = ctx->scratch_buf_info.sfe_scratch_config;
+
+	if (sfe_scratch_config->skip_scratch_cfg_streamon)
+		goto end;
 
 
 	for (i = 0; i < CAM_SFE_FE_RDI_NUM_MAX; i++) {
 	for (i = 0; i < CAM_SFE_FE_RDI_NUM_MAX; i++) {
 		hw_mgr_res = &res_list_sfe_out[i];
 		hw_mgr_res = &res_list_sfe_out[i];
@@ -11524,7 +11607,13 @@ static int cam_ife_mgr_prog_default_settings(
 				(res_id - CAM_ISP_SFE_OUT_RES_RDI_0), ctx, true))
 				(res_id - CAM_ISP_SFE_OUT_RES_RDI_0), ctx, true))
 				continue;
 				continue;
 
 
-			buf_info = &ctx->sfe_info.scratch_config->buf_info[
+			if ((is_streamon) &&
+				cam_ife_mgr_validate_for_io_buffers(
+				(res_id - CAM_ISP_SFE_OUT_RES_RDI_0),
+				sfe_scratch_config->streamon_buf_mask))
+				continue;
+
+			buf_info = &sfe_scratch_config->buf_info[
 				res_id - CAM_ISP_SFE_OUT_RES_RDI_0];
 				res_id - CAM_ISP_SFE_OUT_RES_RDI_0];
 
 
 			/* Check if scratch available for this resource */
 			/* Check if scratch available for this resource */
@@ -11532,7 +11621,8 @@ static int cam_ife_mgr_prog_default_settings(
 				CAM_ERR(CAM_ISP,
 				CAM_ERR(CAM_ISP,
 					"No scratch buffer config found for res: %u on ctx: %u",
 					"No scratch buffer config found for res: %u on ctx: %u",
 					res_id, ctx->ctx_index);
 					res_id, ctx->ctx_index);
-				return -EFAULT;
+				rc = -EFAULT;
+				goto end;
 			}
 			}
 
 
 			CAM_DBG(CAM_ISP,
 			CAM_DBG(CAM_ISP,
@@ -11547,7 +11637,7 @@ static int cam_ife_mgr_prog_default_settings(
 				hw_mgr_res->hw_res[j], buf_info,
 				hw_mgr_res->hw_res[j], buf_info,
 				NULL, NULL);
 				NULL, NULL);
 			if (rc)
 			if (rc)
-				return rc;
+				goto end;
 		}
 		}
 	}
 	}
 
 
@@ -11559,10 +11649,16 @@ static int cam_ife_mgr_prog_default_settings(
 			res_id = hw_mgr_res->hw_res[j]->res_id;
 			res_id = hw_mgr_res->hw_res[j]->res_id;
 
 
 			if (cam_isp_sfe_validate_for_scratch_buf_config(
 			if (cam_isp_sfe_validate_for_scratch_buf_config(
-				(res_id - CAM_ISP_SFE_IN_RD_0), ctx, false))
+				(res_id - CAM_ISP_SFE_IN_RD_0), ctx, true))
 				continue;
 				continue;
 
 
-			buf_info = &ctx->sfe_info.scratch_config->buf_info
+			if ((is_streamon) &&
+				cam_ife_mgr_validate_for_io_buffers(
+				(res_id - CAM_ISP_SFE_IN_RD_0),
+				sfe_scratch_config->streamon_buf_mask))
+				continue;
+
+			buf_info = &ctx->scratch_buf_info.sfe_scratch_config->buf_info
 				[res_id - CAM_ISP_SFE_IN_RD_0];
 				[res_id - CAM_ISP_SFE_IN_RD_0];
 			CAM_DBG(CAM_ISP,
 			CAM_DBG(CAM_ISP,
 				"RD res_id 0x%x idx %u io_addr %pK",
 				"RD res_id 0x%x idx %u io_addr %pK",
@@ -11574,25 +11670,47 @@ static int cam_ife_mgr_prog_default_settings(
 				hw_mgr_res->hw_res[j], buf_info,
 				hw_mgr_res->hw_res[j], buf_info,
 				NULL, NULL);
 				NULL, NULL);
 			if (rc)
 			if (rc)
-				return rc;
+				goto end;
 		}
 		}
 	}
 	}
 
 
-	/* Check for IFE scratch buffer */
-	if (ctx->sfe_info.ife_scratch_config->num_config) {
-		rc = cam_ife_mgr_configure_scratch_for_ife(ctx);
+end:
+	return rc;
+}
+
+/*
+ * Scratch buffer is for sHDR/FS usescases involing SFE RDI0-2
+ * There is no possibility of dual in this case, hence
+ * using the scratch buffer provided during INIT corresponding
+ * to each left RDIs
+ */
+static int cam_ife_mgr_prog_default_settings(
+	bool is_streamon, struct cam_ife_hw_mgr_ctx *ctx)
+{
+	int rc = 0;
+
+	/* Check for SFE scratch buffers */
+	rc = cam_ife_mgr_configure_scratch_for_sfe(is_streamon, ctx);
+	if (rc)
+		goto end;
+
+	/* Check for IFE scratch buffers */
+	if (ctx->scratch_buf_info.ife_scratch_config->num_config) {
+		rc = cam_ife_mgr_configure_scratch_for_ife(is_streamon, ctx);
 		if (rc)
 		if (rc)
-			return rc;
+			goto end;
 	}
 	}
 
 
 	/* Program rup & aup only at run time */
 	/* Program rup & aup only at run time */
-	if (need_rup_aup) {
+	if (!is_streamon) {
 		rc = cam_isp_config_csid_rup_aup(ctx);
 		rc = cam_isp_config_csid_rup_aup(ctx);
 		if (rc)
 		if (rc)
 			CAM_ERR(CAM_ISP,
 			CAM_ERR(CAM_ISP,
-				"RUP/AUP update failed for scratch buffers");
+				"RUP/AUP update failed for scratch buffers in ctx: %u",
+				ctx->ctx_index);
 	}
 	}
 
 
+end:
 	return rc;
 	return rc;
 }
 }
 
 
@@ -11667,7 +11785,7 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 				ctx->last_cdm_done_req;
 				ctx->last_cdm_done_req;
 			break;
 			break;
 		case CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG:
 		case CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG:
-			rc = cam_ife_mgr_prog_default_settings(true, ctx);
+			rc = cam_ife_mgr_prog_default_settings(false, ctx);
 			break;
 			break;
 		case CAM_ISP_HW_MGR_GET_SOF_TS:
 		case CAM_ISP_HW_MGR_GET_SOF_TS:
 			rc = cam_ife_mgr_cmd_get_sof_timestamp(ctx,
 			rc = cam_ife_mgr_cmd_get_sof_timestamp(ctx,
@@ -12839,14 +12957,14 @@ static int cam_ife_hw_mgr_check_for_scratch_buf_done(
 
 
 	switch (hw_type) {
 	switch (hw_type) {
 	case CAM_ISP_HW_TYPE_VFE:
 	case CAM_ISP_HW_TYPE_VFE:
-		if (ife_hw_mgr_ctx->sfe_info.ife_scratch_config->num_config)
+		if (ife_hw_mgr_ctx->scratch_buf_info.ife_scratch_config->num_config)
 			rc = cam_ife_hw_mgr_check_ife_scratch_buf_done(
 			rc = cam_ife_hw_mgr_check_ife_scratch_buf_done(
-				ife_hw_mgr_ctx->sfe_info.ife_scratch_config,
+				ife_hw_mgr_ctx->scratch_buf_info.ife_scratch_config,
 				res_id, last_consumed_addr);
 				res_id, last_consumed_addr);
 		break;
 		break;
 	case CAM_ISP_HW_TYPE_SFE:
 	case CAM_ISP_HW_TYPE_SFE:
 		rc = cam_ife_hw_mgr_check_rdi_scratch_buf_done(
 		rc = cam_ife_hw_mgr_check_rdi_scratch_buf_done(
-			ife_hw_mgr_ctx->sfe_info.scratch_config,
+			ife_hw_mgr_ctx->scratch_buf_info.sfe_scratch_config,
 			res_id, last_consumed_addr);
 			res_id, last_consumed_addr);
 		break;
 		break;
 	default:
 	default:

+ 71 - 63
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -119,44 +119,52 @@ struct cam_ife_sfe_scratch_buf_info {
 /**
 /**
  * struct cam_sfe_scratch_buf_cfg - Scratch buf info
  * struct cam_sfe_scratch_buf_cfg - Scratch buf info
  *
  *
- * @num_configs     : Total Number of scratch buffers provided
- * @updated_num_exp : Current num of exposures
- * @buf_info        : Info on each of the buffers
+ * @num_configs: Total Number of scratch buffers provided
+ * @streamon_buf_mask: Mask to indicate which ports have received buffer
+ *                     from userspace, apply scratch for other ports
+ * @updated_num_exp: Current num of exposures
+ * @buf_info: Info on each of the buffers
+ * @skip_scratch_cfg_streamon: Determine if scratch cfg needs to be programmed at stream on
  *
  *
  */
  */
 struct cam_sfe_scratch_buf_cfg {
 struct cam_sfe_scratch_buf_cfg {
 	uint32_t                            num_config;
 	uint32_t                            num_config;
+	uint32_t                            streamon_buf_mask;
 	uint32_t                            updated_num_exp;
 	uint32_t                            updated_num_exp;
 	struct cam_ife_sfe_scratch_buf_info buf_info[
 	struct cam_ife_sfe_scratch_buf_info buf_info[
 		CAM_SFE_FE_RDI_NUM_MAX];
 		CAM_SFE_FE_RDI_NUM_MAX];
+	bool                                skip_scratch_cfg_streamon;
 };
 };
 
 
 /**
 /**
- * struct cam_sfe_scratch_buf_cfg - Scratch buf info
+ * struct cam_ife_scratch_buf_cfg - Scratch buf info
  *
  *
- * @num_ports: Total Number of scratch buffers provided
- * @buf_info : Info on each of the buffers
+ * @num_config: Total Number of scratch buffers provided
+ * @streamon_buf_mask: Mask to indicate which ports have received buffer
+ *                     from userspace, apply scratch for other ports
+ * @buf_info: Info on each of the buffers
+ * @skip_scratch_cfg_streamon: Determine if scratch cfg needs to be programmed at stream on
  *
  *
  */
  */
 struct cam_ife_scratch_buf_cfg {
 struct cam_ife_scratch_buf_cfg {
 	uint32_t                            num_config;
 	uint32_t                            num_config;
+	uint32_t                            streamon_buf_mask;
 	struct cam_ife_sfe_scratch_buf_info buf_info[
 	struct cam_ife_sfe_scratch_buf_info buf_info[
 		CAM_IFE_SCRATCH_NUM_MAX];
 		CAM_IFE_SCRATCH_NUM_MAX];
+	bool                                skip_scratch_cfg_streamon;
 };
 };
 
 
 
 
 /**
 /**
- * struct cam_ife_hw_mgr_sfe_info - SFE info
+ * struct cam_ife_hw_mgr_ctx_scratch_buf_info - Scratch buffer info
  *
  *
- * @skip_scratch_cfg_streamon: Determine if scratch cfg needs to be programmed at stream on
  * @num_fetches:               Indicate number of SFE fetches for this stream
  * @num_fetches:               Indicate number of SFE fetches for this stream
- * @scratch_config:            Scratch buffer config if any for SFE ports
+ * @sfe_scratch_config:        Scratch buffer config if any for SFE ports
  * @ife_scratch_config:        Scratch buffer config if any for IFE ports
  * @ife_scratch_config:        Scratch buffer config if any for IFE ports
  */
  */
-struct cam_ife_hw_mgr_sfe_info {
-	bool                            skip_scratch_cfg_streamon;
+struct cam_ife_hw_mgr_ctx_scratch_buf_info {
 	uint32_t                        num_fetches;
 	uint32_t                        num_fetches;
-	struct cam_sfe_scratch_buf_cfg *scratch_config;
+	struct cam_sfe_scratch_buf_cfg *sfe_scratch_config;
 	struct cam_ife_scratch_buf_cfg *ife_scratch_config;
 	struct cam_ife_scratch_buf_cfg *ife_scratch_config;
 };
 };
 
 
@@ -267,7 +275,7 @@ struct cam_ife_cdm_user_data {
  * @ts                      captured timestamp when the ctx is acquired
  * @ts                      captured timestamp when the ctx is acquired
  * @hw_enabled              Array to indicate active HW
  * @hw_enabled              Array to indicate active HW
  * @buf_done_controller     Buf done controller.
  * @buf_done_controller     Buf done controller.
- * @sfe_info                SFE info pertaining to this stream
+ * @scratch_buf_info        Scratch buf [SFE/IFE] info pertaining to this stream
  * @flags                   Flags pertainting to this ctx
  * @flags                   Flags pertainting to this ctx
  * @bw_config_version       BW Config version
  * @bw_config_version       BW Config version
  * @recovery_id:            Unique ID of the current valid scheduled recovery
  * @recovery_id:            Unique ID of the current valid scheduled recovery
@@ -277,60 +285,60 @@ struct cam_ife_cdm_user_data {
  *
  *
  */
  */
 struct cam_ife_hw_mgr_ctx {
 struct cam_ife_hw_mgr_ctx {
-	struct list_head                   list;
-	struct cam_isp_hw_mgr_ctx          common;
+	struct list_head                          list;
+	struct cam_isp_hw_mgr_ctx                 common;
 
 
-	uint32_t                          ctx_index;
-	uint32_t                          left_hw_idx;
-	uint32_t                          right_hw_idx;
-	struct cam_ife_hw_mgr            *hw_mgr;
+	uint32_t                                  ctx_index;
+	uint32_t                                  left_hw_idx;
+	uint32_t                                  right_hw_idx;
+	struct cam_ife_hw_mgr                    *hw_mgr;
 
 
-	struct cam_isp_hw_mgr_res         res_list_ife_in;
-	struct list_head                  res_list_ife_csid;
-	struct list_head                  res_list_ife_src;
-	struct list_head                  res_list_sfe_src;
-	struct list_head                  res_list_ife_in_rd;
-	struct cam_isp_hw_mgr_res        *res_list_ife_out;
-	struct cam_isp_hw_mgr_res         res_list_sfe_out[
-						CAM_SFE_HW_OUT_RES_MAX];
-	struct list_head                  free_res_list;
-	struct cam_isp_hw_mgr_res         res_pool[CAM_IFE_HW_RES_POOL_MAX];
-	uint32_t                          num_acq_vfe_out;
-	uint32_t                          num_acq_sfe_out;
+	struct cam_isp_hw_mgr_res                  res_list_ife_in;
+	struct list_head                           res_list_ife_csid;
+	struct list_head                           res_list_ife_src;
+	struct list_head                           res_list_sfe_src;
+	struct list_head                           res_list_ife_in_rd;
+	struct cam_isp_hw_mgr_res                 *res_list_ife_out;
+	struct cam_isp_hw_mgr_res                  res_list_sfe_out[
+							CAM_SFE_HW_OUT_RES_MAX];
+	struct list_head                           free_res_list;
+	struct cam_isp_hw_mgr_res                  res_pool[CAM_IFE_HW_RES_POOL_MAX];
+	uint32_t                                   num_acq_vfe_out;
+	uint32_t                                   num_acq_sfe_out;
 
 
-	uint32_t                          irq_status0_mask[CAM_IFE_HW_NUM_MAX];
-	uint32_t                          irq_status1_mask[CAM_IFE_HW_NUM_MAX];
-	struct cam_isp_ctx_base_info      base[CAM_IFE_HW_NUM_MAX +
-						CAM_SFE_HW_NUM_MAX];
-	uint32_t                          num_base;
-	uint32_t                          cdm_handle;
-	struct cam_cdm_utils_ops         *cdm_ops;
-	struct cam_cdm_bl_request        *cdm_cmd;
-	enum cam_cdm_id                   cdm_id;
-	uint32_t                          sof_cnt[CAM_IFE_HW_NUM_MAX];
-	uint32_t                          epoch_cnt[CAM_IFE_HW_NUM_MAX];
-	uint32_t                          eof_cnt[CAM_IFE_HW_NUM_MAX];
-	atomic_t                          overflow_pending;
-	atomic_t                          cdm_done;
-	uint64_t                          last_cdm_done_req;
-	struct completion                 config_done_complete;
-	uint32_t                          hw_version;
-	struct cam_cmd_buf_desc           reg_dump_buf_desc[
+	uint32_t                                   irq_status0_mask[CAM_IFE_HW_NUM_MAX];
+	uint32_t                                   irq_status1_mask[CAM_IFE_HW_NUM_MAX];
+	struct cam_isp_ctx_base_info               base[CAM_IFE_HW_NUM_MAX +
+								CAM_SFE_HW_NUM_MAX];
+	uint32_t                                   num_base;
+	uint32_t                                   cdm_handle;
+	struct cam_cdm_utils_ops                  *cdm_ops;
+	struct cam_cdm_bl_request                 *cdm_cmd;
+	enum cam_cdm_id                            cdm_id;
+	uint32_t                                   sof_cnt[CAM_IFE_HW_NUM_MAX];
+	uint32_t                                   epoch_cnt[CAM_IFE_HW_NUM_MAX];
+	uint32_t                                   eof_cnt[CAM_IFE_HW_NUM_MAX];
+	atomic_t                                   overflow_pending;
+	atomic_t                                   cdm_done;
+	uint64_t                                   last_cdm_done_req;
+	struct completion                          config_done_complete;
+	uint32_t                                   hw_version;
+	struct cam_cmd_buf_desc                    reg_dump_buf_desc[
 						CAM_REG_DUMP_MAX_BUF_ENTRIES];
 						CAM_REG_DUMP_MAX_BUF_ENTRIES];
-	uint32_t                          num_reg_dump_buf;
-	uint64_t                          applied_req_id;
-	enum cam_ife_ctx_master_type      ctx_type;
-	uint32_t                          ctx_config;
-	struct timespec64                 ts;
-	void                             *buf_done_controller;
-	struct cam_ife_hw_mgr_sfe_info    sfe_info;
-	struct cam_ife_hw_mgr_ctx_flags   flags;
-	struct cam_ife_hw_mgr_ctx_pf_info pf_info;
-	struct cam_ife_cdm_user_data      cdm_userdata;
-	uint32_t                          bw_config_version;
-	atomic_t                          recovery_id;
-	uint32_t                          current_mup;
-	uint32_t                          curr_num_exp;
+	uint32_t                                   num_reg_dump_buf;
+	uint64_t                                   applied_req_id;
+	enum cam_ife_ctx_master_type               ctx_type;
+	uint32_t                                   ctx_config;
+	struct timespec64                          ts;
+	void                                      *buf_done_controller;
+	struct cam_ife_hw_mgr_ctx_scratch_buf_info scratch_buf_info;
+	struct cam_ife_hw_mgr_ctx_flags            flags;
+	struct cam_ife_hw_mgr_ctx_pf_info          pf_info;
+	struct cam_ife_cdm_user_data               cdm_userdata;
+	uint32_t                                   bw_config_version;
+	atomic_t                                   recovery_id;
+	uint32_t                                   current_mup;
+	uint32_t                                   curr_num_exp;
 };
 };
 
 
 /**
 /**