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

msm: camera: tfe: Add MUP support for TFE HW

This change add support for MUP in TFE HW. Also enable
interrupt if case of mup mismatch and add error bit in
header file to remove hardcoded values.

CRs-Fixed: 3350436
Change-Id: I5556fa3f8ab47fea16fe92007303eb68a5b80943
Signed-off-by: Ayush Kumar <[email protected]>
Ayush Kumar 2 éve
szülő
commit
7a9cd0d210

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

@@ -12791,7 +12791,7 @@ static int cam_ife_mgr_isp_add_reg_update(struct cam_ife_hw_mgr_ctx *ctx,
 		rc = cam_isp_add_reg_update(prepare,
 		rc = cam_isp_add_reg_update(prepare,
 			&ctx->res_list_ife_src,
 			&ctx->res_list_ife_src,
 			ctx->base[i].idx, kmd_buf,
 			ctx->base[i].idx, kmd_buf,
-			!ctx->flags.internal_cdm);
+			!ctx->flags.internal_cdm, NULL);
 
 
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_ISP,
 			CAM_ERR(CAM_ISP,

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

@@ -2923,7 +2923,7 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv,
 		ctx->last_submit_bl_cmd.cmd[i].input_len = cdm_cmd->cmd[i].len;
 		ctx->last_submit_bl_cmd.cmd[i].input_len = cdm_cmd->cmd[i].len;
 	}
 	}
 
 
-	if (!cfg->init_packet)
+	if (!cfg->init_packet && !hw_update_data->mup_en)
 		goto end;
 		goto end;
 
 
 	for (i = 0; i < CAM_TFE_HW_CONFIG_WAIT_MAX_TRY; i++) {
 	for (i = 0; i < CAM_TFE_HW_CONFIG_WAIT_MAX_TRY; i++) {
@@ -4380,6 +4380,30 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 			CAM_ERR(CAM_ISP, "BW limit update failed for TFE rc: %d", rc);
 			CAM_ERR(CAM_ISP, "BW limit update failed for TFE rc: %d", rc);
 	}
 	}
 		break;
 		break;
+	case CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH: {
+		struct cam_isp_mode_switch_info         *mup_config;
+		struct cam_isp_prepare_hw_update_data   *prepare_hw_data;
+
+		if (blob_size < sizeof(struct cam_isp_mode_switch_info)) {
+			CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+				blob_size,
+				sizeof(struct cam_isp_mode_switch_info));
+			return -EINVAL;
+		}
+
+		mup_config = (struct cam_isp_mode_switch_info *)blob_data;
+		CAM_DBG(CAM_ISP,
+			"Ctx id %d request id %lld csid mup value=%u num_exposures=%d",
+			tfe_mgr_ctx->ctx_index, prepare->packet->header.request_id,
+			mup_config->mup, mup_config->num_expoures);
+
+		prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)prepare->priv;
+
+		prepare_hw_data->mup_en = true;
+		prepare_hw_data->mup_val = mup_config->mup;
+		prepare_hw_data->num_exp = mup_config->num_expoures;
+	}
+		break;
 	default:
 	default:
 		CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
 		CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
 		break;
 		break;
@@ -4678,6 +4702,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 	struct cam_isp_change_base_args          change_base_info = {0};
 	struct cam_isp_change_base_args          change_base_info = {0};
 	struct cam_isp_check_io_cfg_for_scratch  check_for_scratch = {0};
 	struct cam_isp_check_io_cfg_for_scratch  check_for_scratch = {0};
 	struct cam_isp_io_buf_info               io_buf_info = {0};
 	struct cam_isp_io_buf_info               io_buf_info = {0};
+	struct cam_isp_mode_switch_data          mup_config;
 
 
 	if (!hw_mgr_priv || !prepare_hw_update_args) {
 	if (!hw_mgr_priv || !prepare_hw_update_args) {
 		CAM_ERR(CAM_ISP, "Invalid args");
 		CAM_ERR(CAM_ISP, "Invalid args");
@@ -4840,9 +4865,13 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
 			goto end;
 			goto end;
 		}
 		}
 
 
+		mup_config.mup = prepare_hw_data->mup_val;
+		mup_config.num_expoures = prepare_hw_data->num_exp;
+		mup_config.mup_en = prepare_hw_data->mup_en;
+
 		/*Add reg update */
 		/*Add reg update */
 		rc = cam_isp_add_reg_update(prepare, &ctx->res_list_tfe_in,
 		rc = cam_isp_add_reg_update(prepare, &ctx->res_list_tfe_in,
-			ctx->base[i].idx, &prepare_hw_data->kmd_cmd_buff_info, false);
+			ctx->base[i].idx, &prepare_hw_data->kmd_cmd_buff_info, false, &mup_config);
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_ISP,
 			CAM_ERR(CAM_ISP,
 				"Add Reg_update cmd Failed i=%d, idx=%d, rc=%d",
 				"Add Reg_update cmd Failed i=%d, idx=%d, rc=%d",

+ 7 - 4
drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c

@@ -1242,12 +1242,13 @@ int cam_isp_add_reg_update(
 	struct list_head                     *res_list_isp_src,
 	struct list_head                     *res_list_isp_src,
 	uint32_t                              base_idx,
 	uint32_t                              base_idx,
 	struct cam_kmd_buf_info              *kmd_buf_info,
 	struct cam_kmd_buf_info              *kmd_buf_info,
-	bool                                  combine)
+	bool                                  combine,
+	void                                 *priv_data)
 {
 {
 	int rc = -EINVAL;
 	int rc = -EINVAL;
-	struct cam_isp_resource_node         *res;
-	struct cam_isp_hw_mgr_res            *hw_mgr_res;
-	struct cam_isp_hw_get_cmd_update      get_regup;
+	struct cam_isp_resource_node            *res;
+	struct cam_isp_hw_mgr_res               *hw_mgr_res;
+	struct cam_isp_hw_get_cmd_update         get_regup;
 	uint32_t kmd_buf_remain_size, i, reg_update_size;
 	uint32_t kmd_buf_remain_size, i, reg_update_size;
 
 
 	/* Max one hw entries required for each base */
 	/* Max one hw entries required for each base */
@@ -1293,6 +1294,8 @@ int cam_isp_add_reg_update(
 			get_regup.cmd_type = CAM_ISP_HW_CMD_GET_REG_UPDATE;
 			get_regup.cmd_type = CAM_ISP_HW_CMD_GET_REG_UPDATE;
 			get_regup.res = res;
 			get_regup.res = res;
 
 
+			get_regup.data = priv_data;
+
 			rc = res->hw_intf->hw_ops.process_cmd(
 			rc = res->hw_intf->hw_ops.process_cmd(
 				res->hw_intf->hw_priv,
 				res->hw_intf->hw_priv,
 				CAM_ISP_HW_CMD_GET_REG_UPDATE, &get_regup,
 				CAM_ISP_HW_CMD_GET_REG_UPDATE, &get_regup,

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h

@@ -290,6 +290,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info   *io_info);
  * @base_idx:              Base or dev index of the IFE/VFE HW instance
  * @base_idx:              Base or dev index of the IFE/VFE HW instance
  * @kmd_buf_info:          Kmd buffer to store the change base command
  * @kmd_buf_info:          Kmd buffer to store the change base command
  * @combine:               Indicate whether combine with prev update entry
  * @combine:               Indicate whether combine with prev update entry
+ * @priv_data:             private data for HW driver
  * @return:                0 for success
  * @return:                0 for success
  *                         -EINVAL for Fail
  *                         -EINVAL for Fail
  */
  */
@@ -298,7 +299,8 @@ int cam_isp_add_reg_update(
 	struct list_head                     *res_list_isp_src,
 	struct list_head                     *res_list_isp_src,
 	uint32_t                              base_idx,
 	uint32_t                              base_idx,
 	struct cam_kmd_buf_info              *kmd_buf_info,
 	struct cam_kmd_buf_info              *kmd_buf_info,
-	bool                                  combine);
+	bool                                  combine,
+	void                                 *priv_data);
 
 
 /*
 /*
  * cam_isp_add_comp_wait()
  * cam_isp_add_comp_wait()

+ 15 - 0
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -546,6 +546,21 @@ struct cam_isp_lcr_rdi_cfg_args {
 	bool                           is_init;
 	bool                           is_init;
 };
 };
 
 
+
+/**
+ * struct cam_isp_mode_switch_data - isp hardware mode update arguments
+ *
+ * @mup                 Mup value
+ * @num_expoures        Number of exposures
+ * @mup_en              Flag to indicate if mup is enable
+ *
+ */
+struct cam_isp_mode_switch_data {
+	uint32_t                      mup;
+	uint32_t                      num_expoures;
+	bool                          mup_en;
+};
+
 /**
 /**
  * cam_isp_hw_mgr_init()
  * cam_isp_hw_mgr_init()
  *
  *

+ 16 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h

@@ -53,6 +53,22 @@ static struct cam_tfe_top_reg_offset_common  tfe530_top_commong_reg  = {
 	.diag_neq_hbi_shift                     = 14,
 	.diag_neq_hbi_shift                     = 14,
 	.diag_sensor_hbi_mask                   = 0x3FFF,
 	.diag_sensor_hbi_mask                   = 0x3FFF,
 	.serializer_supported                   = false,
 	.serializer_supported                   = false,
+	.pp_camif_violation_bit                 = BIT(0),
+	.pp_violation_bit                       = BIT(1),
+	.rdi0_camif_violation_bit               = BIT(2),
+	.rdi1_camif_violation_bit               = BIT(3),
+	.rdi2_camif_violation_bit               = BIT(4),
+	.diag_violation_bit                     = BIT(5),
+	.pp_frame_drop_bit                      = BIT(8),
+	.rdi0_frame_drop_bit                    = BIT(9),
+	.rdi1_frame_drop_bit                    = BIT(10),
+	.rdi2_frame_drop_bit                    = BIT(11),
+	.pp_overflow_bit                        = BIT(16),
+	.rdi0_overflow_bit                      = BIT(17),
+	.rdi1_overflow_bit                      = BIT(18),
+	.rdi2_overflow_bit                      = BIT(19),
+	.mup_shift_val                          = 0,
+	.mup_supported                          = false,
 };
 };
 
 
 static struct cam_tfe_camif_reg  tfe530_camif_reg = {
 static struct cam_tfe_camif_reg  tfe530_camif_reg = {
@@ -220,7 +236,6 @@ static struct cam_tfe_rdi_reg_data tfe530_rdi2_reg_data = {
 	.enable_diagnostic_hw        = 0x1,
 	.enable_diagnostic_hw        = 0x1,
 	.diag_sensor_sel             = 0x3,
 	.diag_sensor_sel             = 0x3,
 	.diag_sensor_shift           = 0x1,
 	.diag_sensor_shift           = 0x1,
-
 };
 };
 
 
 static struct cam_tfe_clc_hw_status  tfe530_clc_hw_info[CAM_TFE_MAX_CLC] = {
 static struct cam_tfe_clc_hw_status  tfe530_clc_hw_info[CAM_TFE_MAX_CLC] = {

+ 16 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h

@@ -66,6 +66,22 @@ static struct cam_tfe_top_reg_offset_common  tfe640_top_commong_reg  = {
 	.diag_neq_hbi_shift                     = 14,
 	.diag_neq_hbi_shift                     = 14,
 	.diag_sensor_hbi_mask                   = 0x3FFF,
 	.diag_sensor_hbi_mask                   = 0x3FFF,
 	.serializer_supported                   = true,
 	.serializer_supported                   = true,
+	.pp_camif_violation_bit                 = BIT(0),
+	.pp_violation_bit                       = BIT(1),
+	.rdi0_camif_violation_bit               = BIT(2),
+	.rdi1_camif_violation_bit               = BIT(3),
+	.rdi2_camif_violation_bit               = BIT(4),
+	.diag_violation_bit                     = BIT(5),
+	.pp_frame_drop_bit                      = BIT(8),
+	.rdi0_frame_drop_bit                    = BIT(9),
+	.rdi1_frame_drop_bit                    = BIT(10),
+	.rdi2_frame_drop_bit                    = BIT(11),
+	.pp_overflow_bit                        = BIT(16),
+	.rdi0_overflow_bit                      = BIT(17),
+	.rdi1_overflow_bit                      = BIT(18),
+	.rdi2_overflow_bit                      = BIT(19),
+	.mup_shift_val                          = 0,
+	.mup_supported                          = false,
 };
 };
 
 
 static struct cam_tfe_camif_reg  tfe640_camif_reg = {
 static struct cam_tfe_camif_reg  tfe640_camif_reg = {
@@ -235,7 +251,6 @@ static struct cam_tfe_rdi_reg_data tfe640_rdi2_reg_data = {
 	.enable_diagnostic_hw        = 0x1,
 	.enable_diagnostic_hw        = 0x1,
 	.diag_sensor_sel             = 0x3,
 	.diag_sensor_sel             = 0x3,
 	.diag_sensor_shift           = 0x1,
 	.diag_sensor_shift           = 0x1,
-
 };
 };
 
 
 static struct cam_tfe_clc_hw_status  tfe640_clc_hw_info[CAM_TFE_MAX_CLC] = {
 static struct cam_tfe_clc_hw_status  tfe640_clc_hw_info[CAM_TFE_MAX_CLC] = {

+ 97 - 51
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -58,6 +58,7 @@ struct cam_tfe_top_priv {
 	struct timespec64                    eof_ts;
 	struct timespec64                    eof_ts;
 	struct timespec64                    error_ts;
 	struct timespec64                    error_ts;
 	uint32_t                             top_debug;
 	uint32_t                             top_debug;
+	uint32_t                             last_mup_val;
 };
 };
 
 
 struct cam_tfe_camif_data {
 struct cam_tfe_camif_data {
@@ -319,6 +320,7 @@ static void cam_tfe_log_error_irq_status(
 	struct cam_tfe_soc_private           *soc_private;
 	struct cam_tfe_soc_private           *soc_private;
 
 
 	struct cam_tfe_clc_hw_status         *clc_hw_status;
 	struct cam_tfe_clc_hw_status         *clc_hw_status;
+	struct cam_tfe_top_reg_offset_common *common_reg;
 	struct timespec64 ts;
 	struct timespec64 ts;
 	uint32_t  i, val_0, val_1, val_2, val_3;
 	uint32_t  i, val_0, val_1, val_2, val_3;
 
 
@@ -328,6 +330,7 @@ static void cam_tfe_log_error_irq_status(
 	mem_base = top_priv->common_data.soc_info->reg_map[0].mem_base;
 	mem_base = top_priv->common_data.soc_info->reg_map[0].mem_base;
 	soc_info = top_priv->common_data.soc_info;
 	soc_info = top_priv->common_data.soc_info;
 	soc_private = top_priv->common_data.soc_info->soc_private;
 	soc_private = top_priv->common_data.soc_info->soc_private;
+	common_reg = top_priv->common_data.common_reg;
 
 
 	CAM_INFO(CAM_ISP, "current monotonic timestamp:[%lld.%06lld]",
 	CAM_INFO(CAM_ISP, "current monotonic timestamp:[%lld.%06lld]",
 		ts.tv_sec, ts.tv_nsec/1000);
 		ts.tv_sec, ts.tv_nsec/1000);
@@ -346,26 +349,22 @@ static void cam_tfe_log_error_irq_status(
 		evt_payload->irq_reg_val[0], evt_payload->irq_reg_val[1],
 		evt_payload->irq_reg_val[0], evt_payload->irq_reg_val[1],
 		evt_payload->irq_reg_val[2]);
 		evt_payload->irq_reg_val[2]);
 
 
-	for (i = 0; i < top_priv->common_data.common_reg->num_debug_reg; i++) {
+	for (i = 0; i < common_reg->num_debug_reg; i++) {
 		val_0 = cam_io_r(mem_base  +
 		val_0 = cam_io_r(mem_base  +
-			top_priv->common_data.common_reg->debug_reg[i]);
-		CAM_INFO(CAM_ISP, "Top debug [%d]:0x%x", i, val_0);
+			common_reg->debug_reg[i]);
+		CAM_INFO(CAM_ISP, "Top debug [i]:0x%x", i, val_0);
 	}
 	}
 
 
 	cam_cpas_dump_camnoc_buff_fill_info(soc_private->cpas_handle);
 	cam_cpas_dump_camnoc_buff_fill_info(soc_private->cpas_handle);
 
 
-	for (i = 0; i < top_priv->common_data.common_reg->num_perf_cfg; i++) {
-		val_0 = cam_io_r(mem_base  +
-			top_priv->common_data.common_reg->perf_cfg[i].perf_pixel_count);
+	for (i = 0; i < common_reg->num_perf_cfg; i++) {
+		val_0 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_pixel_count);
 
 
-		val_1 = cam_io_r(mem_base  +
-			top_priv->common_data.common_reg->perf_cfg[i].perf_line_count);
+		val_1 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_line_count);
 
 
-		val_2 = cam_io_r(mem_base  +
-			top_priv->common_data.common_reg->perf_cfg[i].perf_stall_count);
+		val_2 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_stall_count);
 
 
-		val_3 = cam_io_r(mem_base  +
-			top_priv->common_data.common_reg->perf_cfg[i].perf_always_count);
+		val_3 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_always_count);
 
 
 		CAM_INFO(CAM_ISP,
 		CAM_INFO(CAM_ISP,
 			"Top perf cnt [%d] pix:0x%x line:0x%x stall:0x%x always:0x%x",
 			"Top perf cnt [%d] pix:0x%x line:0x%x stall:0x%x always:0x%x",
@@ -388,54 +387,65 @@ static void cam_tfe_log_error_irq_status(
 
 
 	/* Check the overflow errors */
 	/* Check the overflow errors */
 	if (evt_payload->irq_reg_val[0] & hw_info->error_irq_mask[0]) {
 	if (evt_payload->irq_reg_val[0] & hw_info->error_irq_mask[0]) {
-		if (evt_payload->irq_reg_val[0] & BIT(8))
-			CAM_INFO(CAM_ISP, "PP_FRAME_DROP");
+		if (evt_payload->irq_reg_val[0] & common_reg->pp_frame_drop_bit)
+			CAM_INFO(CAM_ISP, "TFE %d PP_FRAME_DROP", core_info->core_index);
+
+		if (evt_payload->irq_reg_val[0] & common_reg->rdi0_frame_drop_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI0_FRAME_DROP", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[0] & BIT(9))
-			CAM_INFO(CAM_ISP, "RDI0_FRAME_DROP");
+		if (evt_payload->irq_reg_val[0] & common_reg->rdi1_frame_drop_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI1_FRAME_DROP", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[0] & BIT(10))
-			CAM_INFO(CAM_ISP, "RDI1_FRAME_DROP");
+		if (evt_payload->irq_reg_val[0] & common_reg->rdi2_frame_drop_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI2_FRAME_DROP", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[0] & BIT(11))
-			CAM_INFO(CAM_ISP, "RDI2_FRAME_DROP");
+		if (evt_payload->irq_reg_val[0] & common_reg->pp_overflow_bit)
+			CAM_INFO(CAM_ISP, "TFE %d PP_OVERFLOW", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[0] & BIT(16))
-			CAM_INFO(CAM_ISP, "PP_OVERFLOW");
+		if (evt_payload->irq_reg_val[0] & common_reg->rdi0_overflow_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI0_OVERFLOW", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[0] & BIT(17))
-			CAM_INFO(CAM_ISP, "RDI0_OVERFLOW");
+		if (evt_payload->irq_reg_val[0] & common_reg->rdi1_overflow_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI1_OVERFLOW", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[0] & BIT(18))
-			CAM_INFO(CAM_ISP, "RDI1_OVERFLOW");
+		if (evt_payload->irq_reg_val[0] & common_reg->rdi2_overflow_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI2_OVERFLOW", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[0] & BIT(19))
-			CAM_INFO(CAM_ISP, "RDI2_OVERFLOW");
+		if (evt_payload->irq_reg_val[0] & common_reg->out_of_sync_frame_drop_bit) {
+			CAM_INFO(CAM_ISP,
+				"TFE %d SENSOR_SWITCH_OUT_OF_SYNC_FRAME_DROP mup: last %d curr %d",
+				core_info->core_index, top_priv->last_mup_val,
+				((cam_io_r(mem_base + common_reg->reg_update_cmd) >> 8) & 1));
+		}
 	}
 	}
 
 
 	/* Check the violation errors */
 	/* Check the violation errors */
 	if (evt_payload->irq_reg_val[2] & hw_info->error_irq_mask[2]) {
 	if (evt_payload->irq_reg_val[2] & hw_info->error_irq_mask[2]) {
-		if (evt_payload->irq_reg_val[2] & BIT(0))
-			CAM_INFO(CAM_ISP, "PP_CAMIF_VIOLATION");
+		if (evt_payload->irq_reg_val[2] & common_reg->pp_camif_violation_bit)
+			CAM_INFO(CAM_ISP, "TFE %d PP_CAMIF_VIOLATION", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[2] & BIT(1))
-			CAM_INFO(CAM_ISP, "PP_VIOLATION");
+		if (evt_payload->irq_reg_val[2] & common_reg->pp_violation_bit)
+			CAM_INFO(CAM_ISP, "TFE %d PP_VIOLATION", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[2] & BIT(2))
-			CAM_INFO(CAM_ISP, "RDI0_CAMIF_VIOLATION");
+		if (evt_payload->irq_reg_val[2] & common_reg->rdi0_camif_violation_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI0_CAMIF_VIOLATION", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[2] & BIT(3))
-			CAM_INFO(CAM_ISP, "RDI1_CAMIF_VIOLATION");
+		if (evt_payload->irq_reg_val[2] & common_reg->rdi1_camif_violation_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI1_CAMIF_VIOLATION", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[2] & BIT(4))
-			CAM_INFO(CAM_ISP, "RDI2_CAMIF_VIOLATION");
+		if (evt_payload->irq_reg_val[2] & common_reg->rdi2_camif_violation_bit)
+			CAM_INFO(CAM_ISP, "TFE %d RDI2_CAMIF_VIOLATION", core_info->core_index);
 
 
-		if (evt_payload->irq_reg_val[2] & BIT(5))
-			CAM_INFO(CAM_ISP, "DIAG_VIOLATION");
+		if (evt_payload->irq_reg_val[2] & common_reg->diag_violation_bit)
+			CAM_INFO(CAM_ISP, "TFE %d DIAG_VIOLATION", core_info->core_index);
 
 
-		val_0 = cam_io_r(mem_base  +
-		top_priv->common_data.common_reg->violation_status);
-		CAM_INFO(CAM_ISP, "TOP Violation status:0x%x", val_0);
+		if (evt_payload->irq_reg_val[2] & common_reg->dyamanic_switch_violation_bit)
+			CAM_INFO(CAM_ISP,
+				"TFE %d DYNAMIC_SHDR_MODE_SWITCH_VIOLATION mup val %d",
+				core_info->core_index, top_priv->last_mup_val);
+
+		val_0 = cam_io_r(mem_base + common_reg->violation_status);
+		CAM_INFO(CAM_ISP, "TFE %d TOP Violation status:0x%x", core_info->core_index, val_0);
 	}
 	}
 
 
 	core_info->tfe_bus->bottom_half_handler(
 	core_info->tfe_bus->bottom_half_handler(
@@ -1256,24 +1266,46 @@ static int cam_tfe_top_get_base(struct cam_tfe_top_priv *top_priv,
 	return 0;
 	return 0;
 }
 }
 
 
+static int cam_tfe_top_update_mup(
+	struct cam_tfe_top_priv *top_priv,
+	struct cam_isp_mode_switch_data *mup_config)
+{
+	uint32_t mup_val = 0, final_mup = 0;
+	struct cam_tfe_top_reg_offset_common *common_reg;
+
+	mup_val = mup_config->mup;
+	common_reg = top_priv->common_data.common_reg;
+
+	if (mup_config->mup_en) {
+		final_mup = (mup_val << common_reg->mup_shift_val);
+		top_priv->last_mup_val = mup_val;
+	} else {
+		final_mup = (top_priv->last_mup_val << common_reg->mup_shift_val);
+	}
+
+	return final_mup;
+}
+
 static int cam_tfe_top_get_reg_update(
 static int cam_tfe_top_get_reg_update(
 	struct cam_tfe_top_priv *top_priv,
 	struct cam_tfe_top_priv *top_priv,
 	void *cmd_args, uint32_t arg_size)
 	void *cmd_args, uint32_t arg_size)
 {
 {
-	uint32_t                          size = 0;
-	uint32_t                          reg_val_pair[2];
-	struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
-	struct cam_cdm_utils_ops         *cdm_util_ops = NULL;
-	struct cam_tfe_camif_data        *camif_rsrc_data = NULL;
-	struct cam_tfe_rdi_data          *rdi_rsrc_data = NULL;
-	struct cam_isp_resource_node     *in_res;
+	uint32_t                             size = 0;
+	uint32_t                             reg_val_pair[2];
+	struct cam_isp_hw_get_cmd_update     *cdm_args = cmd_args;
+	struct cam_cdm_utils_ops             *cdm_util_ops = NULL;
+	struct cam_tfe_camif_data            *camif_rsrc_data = NULL;
+	struct cam_tfe_rdi_data              *rdi_rsrc_data = NULL;
+	struct cam_isp_resource_node         *in_res;
+	struct cam_isp_mode_switch_data      *mup_config = NULL;
+	struct cam_tfe_top_reg_offset_common *common_reg;
 
 
 	if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
 	if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
 		CAM_ERR(CAM_ISP, "Invalid cmd size");
 		CAM_ERR(CAM_ISP, "Invalid cmd size");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (!cdm_args || !cdm_args->res) {
+	if (!cdm_args || !cdm_args->res || !top_priv) {
 		CAM_ERR(CAM_ISP, "Invalid args");
 		CAM_ERR(CAM_ISP, "Invalid args");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -1306,6 +1338,19 @@ static int cam_tfe_top_get_reg_update(
 		reg_val_pair[1] = rdi_rsrc_data->reg_data->reg_update_cmd_data;
 		reg_val_pair[1] = rdi_rsrc_data->reg_data->reg_update_cmd_data;
 	}
 	}
 
 
+	common_reg = top_priv->common_data.common_reg;
+	if (common_reg->mup_supported) {
+		if (!cdm_args->data) {
+			CAM_ERR(CAM_ISP, "invalid data (NULL), TFE: %d mup_supported :%d",
+					top_priv->common_data.hw_intf->hw_idx , cdm_args->data);
+			return -EINVAL;
+		}
+		mup_config = (struct cam_isp_mode_switch_data *) cdm_args->data;
+		reg_val_pair[1] |= cam_tfe_top_update_mup(top_priv, mup_config);
+		CAM_DBG(CAM_ISP, "MUP supported, TFE: %d final reg_up cmd: 0x%x",
+				top_priv->common_data.hw_intf->hw_idx, reg_val_pair[1]);
+	}
+
 	cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr,
 	cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr,
 		1, reg_val_pair);
 		1, reg_val_pair);
 
 
@@ -2190,6 +2235,7 @@ int cam_tfe_top_start(struct cam_tfe_hw_core_info *core_info,
 		goto end;
 		goto end;
 	}
 	}
 
 
+	top_priv->last_mup_val = 0;
 	rc = cam_tfe_top_set_hw_clk_rate(top_priv);
 	rc = cam_tfe_top_set_hw_clk_rate(top_priv);
 	if (rc) {
 	if (rc) {
 		CAM_ERR(CAM_ISP, "TFE:%d set_hw_clk_rate failed, rc=%d",
 		CAM_ERR(CAM_ISP, "TFE:%d set_hw_clk_rate failed, rc=%d",

+ 21 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
  */
 
 
 
 
@@ -107,9 +108,29 @@ struct cam_tfe_top_reg_offset_common {
 	uint32_t diag_min_hbi_error_shift;
 	uint32_t diag_min_hbi_error_shift;
 	uint32_t diag_neq_hbi_shift;
 	uint32_t diag_neq_hbi_shift;
 	uint32_t diag_sensor_hbi_mask;
 	uint32_t diag_sensor_hbi_mask;
+	uint32_t mup_shift_val;
+
+	/* error bit data */
+	uint32_t pp_camif_violation_bit;
+	uint32_t pp_violation_bit;
+	uint32_t rdi0_camif_violation_bit;
+	uint32_t rdi1_camif_violation_bit;
+	uint32_t rdi2_camif_violation_bit;
+	uint32_t diag_violation_bit;
+	uint32_t dyamanic_switch_violation_bit;
+	uint32_t pp_frame_drop_bit;
+	uint32_t rdi0_frame_drop_bit;
+	uint32_t rdi1_frame_drop_bit;
+	uint32_t rdi2_frame_drop_bit;
+	uint32_t pp_overflow_bit;
+	uint32_t rdi0_overflow_bit;
+	uint32_t rdi1_overflow_bit;
+	uint32_t rdi2_overflow_bit;
+	uint32_t out_of_sync_frame_drop_bit;
 
 
 	/* configuration */
 	/* configuration */
 	bool serializer_supported;
 	bool serializer_supported;
+	bool mup_supported;
 };
 };
 
 
 struct cam_tfe_camif_reg {
 struct cam_tfe_camif_reg {

+ 1 - 0
include/uapi/camera/media/cam_tfe.h

@@ -73,6 +73,7 @@
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2        2
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2        2
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG   3
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG   3
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG      16
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG      16
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH 15
 
 
 /* DSP mode */
 /* DSP mode */
 #define CAM_ISP_TFE_DSP_MODE_NONE                   0
 #define CAM_ISP_TFE_DSP_MODE_NONE                   0