瀏覽代碼

Merge "msm: camera: isp: Enable format measurement in CSID" into camera-kernel.lnx.4.0

Camera Software Integration 5 年之前
父節點
當前提交
811d02c493

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

@@ -36,7 +36,7 @@
 	(CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON + 1)
 
 #define CAM_ISP_GENERIC_BLOB_TYPE_MAX               \
-	(CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 + 1)
+	(CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG + 1)
 
 static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = {
 	CAM_ISP_HW_CMD_GET_HFR_UPDATE,
@@ -5538,6 +5538,76 @@ static int cam_isp_blob_clock_update(
 	return rc;
 }
 
+static int cam_isp_blob_sensor_config(
+	uint32_t                               blob_type,
+	struct cam_isp_generic_blob_info      *blob_info,
+	struct cam_isp_sensor_config          *dim_config,
+	struct cam_isp_hw_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_sensor_dimension_update_args  update_args;
+	int                                          rc = -EINVAL, found = 0;
+	uint32_t                                     i, j;
+	struct cam_isp_sensor_dimension             *path_config;
+
+	ctx = prepare->ctxt_to_hw_map;
+
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+			found = 1;
+			hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+			if (hw_intf && hw_intf->hw_ops.process_cmd) {
+				path_config = &(dim_config->ipp_path);
+				update_args.ipp_path.width =
+					path_config->width;
+				update_args.ipp_path.height =
+					path_config->height;
+				update_args.ipp_path.measure_enabled =
+					path_config->measure_enabled;
+				path_config = &(dim_config->ppp_path);
+				update_args.ppp_path.width =
+					path_config->width;
+				update_args.ppp_path.height =
+					path_config->height;
+				update_args.ppp_path.measure_enabled =
+					path_config->measure_enabled;
+				for (j = 0; j < CAM_IFE_RDI_NUM_MAX; j++) {
+					path_config =
+						&(dim_config->rdi_path[j]);
+					update_args.rdi_path[j].width =
+						path_config->width;
+					update_args.rdi_path[j].height =
+						path_config->height;
+				update_args.rdi_path[j].measure_enabled =
+						path_config->measure_enabled;
+				}
+				rc = hw_intf->hw_ops.process_cmd(
+					hw_intf->hw_priv,
+					CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
+					&update_args,
+					sizeof(
+					struct
+					cam_ife_sensor_dimension_update_args)
+					);
+				if (rc) {
+					CAM_ERR(CAM_ISP,
+						"Dimension Update failed");
+					break;
+				}
+			} else
+				CAM_ERR(CAM_ISP, "hw_intf is NULL");
+		}
+		if (found)
+			break;
+	}
+
+	return rc;
+}
+
 static int cam_isp_blob_vfe_out_update(
 	uint32_t                               blob_type,
 	struct cam_isp_generic_blob_info      *blob_info,
@@ -6162,6 +6232,26 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
 			CAM_ERR(CAM_ISP, "CSID Config failed rc: %d", rc);
 	}
 		break;
+	case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG: {
+		struct cam_isp_sensor_config *csid_dim_config;
+
+		if (blob_size < sizeof(struct cam_isp_sensor_config)) {
+			CAM_ERR(CAM_ISP, "Invalid blob size %zu expected %zu",
+				blob_size,
+				sizeof(struct cam_isp_sensor_config));
+			return -EINVAL;
+		}
+
+		csid_dim_config =
+			(struct cam_isp_sensor_config *)blob_data;
+
+		rc = cam_isp_blob_sensor_config(blob_type, blob_info,
+			csid_dim_config, prepare);
+		if (rc)
+			CAM_ERR(CAM_ISP,
+				"Sensor Dimension Update Failed rc: %d", rc);
+	}
+		break;
 	default:
 		CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
 		break;

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_IFE_CSID_170_H_
@@ -286,6 +286,10 @@ static struct cam_ife_csid_common_reg_offset
 	.ppp_irq_mask_all                             = 0x0,
 	.measure_en_hbi_vbi_cnt_mask                  = 0xC,
 	.format_measure_en_val                        = 1,
+	.format_measure_height_mask_val               = 0xFFFF,
+	.format_measure_height_shift_val              = 0x10,
+	.format_measure_width_mask_val                = 0xFFFF,
+	.format_measure_width_shift_val               = 0x0,
 };
 
 static struct cam_ife_csid_reg_offset cam_ife_csid_170_reg_offset = {

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170_200.h

@@ -349,6 +349,10 @@ static struct cam_ife_csid_common_reg_offset
 	.ppp_irq_mask_all                             = 0xFFFF,
 	.measure_en_hbi_vbi_cnt_mask                  = 0xC,
 	.format_measure_en_val                        = 1,
+	.format_measure_height_mask_val               = 0xFFFF,
+	.format_measure_height_shift_val              = 0x10,
+	.format_measure_width_mask_val                = 0xFFFF,
+	.format_measure_width_shift_val               = 0x0,
 };
 
 static struct cam_ife_csid_reg_offset cam_ife_csid_170_200_reg_offset = {

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_IFE_CSID_175_H_
@@ -327,6 +327,10 @@ static struct cam_ife_csid_common_reg_offset
 	.ppp_irq_mask_all                             = 0xFFFF,
 	.measure_en_hbi_vbi_cnt_mask                  = 0xC,
 	.format_measure_en_val                        = 1,
+	.format_measure_height_mask_val               = 0xFFFF,
+	.format_measure_height_shift_val              = 0x10,
+	.format_measure_width_mask_val                = 0xFFFF,
+	.format_measure_width_shift_val               = 0x0,
 };
 
 static struct cam_ife_csid_reg_offset cam_ife_csid_175_reg_offset = {

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_IFE_CSID_175_200_H_
@@ -345,6 +345,10 @@ static struct cam_ife_csid_common_reg_offset
 	.ppp_irq_mask_all                             = 0xFFFF,
 	.measure_en_hbi_vbi_cnt_mask                  = 0xC,
 	.format_measure_en_val                        = 1,
+	.format_measure_height_mask_val               = 0xFFFF,
+	.format_measure_height_shift_val              = 0x10,
+	.format_measure_width_mask_val                = 0xFFFF,
+	.format_measure_width_shift_val               = 0x0,
 };
 
 static struct cam_ife_csid_reg_offset cam_ife_csid_175_200_reg_offset = {

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid480.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_IFE_CSID_480_H_
@@ -365,6 +365,10 @@ static struct cam_ife_csid_common_reg_offset
 	.ppp_irq_mask_all                             = 0xFFFF,
 	.measure_en_hbi_vbi_cnt_mask                  = 0xC,
 	.format_measure_en_val                        = 1,
+	.format_measure_height_mask_val               = 0xFFFF,
+	.format_measure_height_shift_val              = 0x10,
+	.format_measure_width_mask_val                = 0xFFFF,
+	.format_measure_width_shift_val               = 0x0,
 };
 
 static struct cam_ife_csid_reg_offset cam_ife_csid_480_reg_offset = {

+ 212 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c

@@ -82,7 +82,7 @@ static int cam_ife_csid_is_ipp_ppp_format_supported(
 
 static int cam_ife_csid_get_format_rdi(
 	uint32_t in_format, uint32_t out_format, uint32_t *decode_fmt,
-	uint32_t *plain_fmt, uint32_t *packing_fmt, bool rpp)
+	uint32_t *plain_fmt, uint32_t *packing_fmt, bool rpp, uint32_t *in_bpp)
 {
 	int rc = 0;
 
@@ -104,6 +104,7 @@ static int cam_ife_csid_get_format_rdi(
 			rc = -EINVAL;
 			break;
 		}
+		*in_bpp = 6;
 		break;
 	case CAM_FORMAT_MIPI_RAW_8:
 		switch (out_format) {
@@ -123,6 +124,7 @@ static int cam_ife_csid_get_format_rdi(
 			rc = -EINVAL;
 			break;
 		}
+		*in_bpp = 8;
 		break;
 	case CAM_FORMAT_MIPI_RAW_10:
 		switch (out_format) {
@@ -142,6 +144,7 @@ static int cam_ife_csid_get_format_rdi(
 			rc = -EINVAL;
 			break;
 		}
+		*in_bpp = 10;
 		break;
 	case CAM_FORMAT_MIPI_RAW_12:
 		switch (out_format) {
@@ -160,6 +163,7 @@ static int cam_ife_csid_get_format_rdi(
 			rc = -EINVAL;
 			break;
 		}
+		*in_bpp = 12;
 		break;
 	case CAM_FORMAT_MIPI_RAW_14:
 		switch (out_format) {
@@ -178,6 +182,7 @@ static int cam_ife_csid_get_format_rdi(
 			rc = -EINVAL;
 			break;
 		}
+		*in_bpp = 14;
 		break;
 	case CAM_FORMAT_MIPI_RAW_16:
 		switch (out_format) {
@@ -196,6 +201,7 @@ static int cam_ife_csid_get_format_rdi(
 			rc = -EINVAL;
 			break;
 		}
+		*in_bpp = 16;
 		break;
 	case CAM_FORMAT_MIPI_RAW_20:
 		switch (out_format) {
@@ -214,6 +220,7 @@ static int cam_ife_csid_get_format_rdi(
 			rc = -EINVAL;
 			break;
 		}
+		*in_bpp = 20;
 		break;
 	case CAM_FORMAT_DPCM_10_6_10:
 		*decode_fmt  = 0x7;
@@ -1330,6 +1337,7 @@ err:
 static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
 {
 	int rc = -EINVAL;
+	uint32_t i;
 	struct cam_hw_soc_info                   *soc_info;
 	const struct cam_ife_csid_reg_offset     *csid_reg;
 	unsigned long                             flags;
@@ -1370,6 +1378,12 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
 	spin_lock_irqsave(&csid_hw->lock_state, flags);
 	csid_hw->device_enabled = 0;
 	spin_unlock_irqrestore(&csid_hw->lock_state, flags);
+
+	csid_hw->ipp_path_config.measure_enabled = 0;
+	csid_hw->ppp_path_config.measure_enabled = 0;
+	for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++)
+		csid_hw->rdi_path_config[i].measure_enabled = 0;
+
 	csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
 	csid_hw->error_irq_count = 0;
 	csid_hw->prev_boot_timestamp = 0;
@@ -1742,6 +1756,7 @@ static int cam_ife_csid_init_config_pxl_path(
 	bool                                      is_ipp;
 	uint32_t decode_format = 0, plain_format = 0, val = 0;
 	uint32_t camera_hw_version;
+	struct cam_isp_sensor_dimension  *path_config;
 
 	path_data = (struct cam_ife_csid_path_cfg  *) res->res_priv;
 	csid_reg = csid_hw->csid_info->csid_reg;
@@ -1750,9 +1765,11 @@ static int cam_ife_csid_init_config_pxl_path(
 	if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
 		is_ipp = true;
 		pxl_reg = csid_reg->ipp_reg;
+		path_config = &(csid_hw->ipp_path_config);
 	} else {
 		is_ipp = false;
 		pxl_reg = csid_reg->ppp_reg;
+		path_config = &(csid_hw->ppp_path_config);
 	}
 
 	if (!pxl_reg) {
@@ -1868,6 +1885,25 @@ static int cam_ife_csid_init_config_pxl_path(
 		pxl_reg->csid_pxl_irq_subsample_period_addr);
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_irq_subsample_pattern_addr);
+
+	/* configure pixel format measure */
+	if (path_config->measure_enabled) {
+		val = (((path_config->height  &
+			csid_reg->cmn_reg->format_measure_height_mask_val) <<
+			csid_reg->cmn_reg->format_measure_height_shift_val) |
+			(path_config->width &
+			csid_reg->cmn_reg->format_measure_width_mask_val));
+		CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x",
+			csid_hw->hw_intf->hw_idx, val);
+
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			pxl_reg->csid_pxl_format_measure_cfg1_addr);
+
+		/* enable pixel and line counter */
+		cam_io_w_mb(3, soc_info->reg_map[0].mem_base +
+			pxl_reg->csid_pxl_format_measure_cfg0_addr);
+	}
+
 	/* set pxl drop pattern to 0 and period to 1 */
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_pix_drop_pattern_addr);
@@ -2017,6 +2053,7 @@ static int cam_ife_csid_enable_pxl_path(
 	const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL;
 	bool                                      is_ipp;
 	uint32_t                                  val = 0;
+	struct cam_isp_sensor_dimension          *path_config;
 
 	path_data = (struct cam_ife_csid_path_cfg   *) res->res_priv;
 	csid_reg = csid_hw->csid_info->csid_reg;
@@ -2025,9 +2062,11 @@ static int cam_ife_csid_enable_pxl_path(
 	if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
 		is_ipp = true;
 		pxl_reg = csid_reg->ipp_reg;
+		path_config = &(csid_hw->ipp_path_config);
 	} else {
 		is_ipp = false;
 		pxl_reg = csid_reg->ppp_reg;
+		path_config = &(csid_hw->ppp_path_config);
 	}
 
 	if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
@@ -2096,6 +2135,10 @@ static int cam_ife_csid_enable_pxl_path(
 	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
 		val |= CSID_PATH_INFO_INPUT_EOF;
 
+	if (path_config->measure_enabled)
+		val |= (CSID_PATH_ERROR_PIX_COUNT |
+			CSID_PATH_ERROR_LINE_COUNT);
+
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_irq_mask_addr);
 
@@ -2209,7 +2252,8 @@ static int cam_ife_csid_init_config_rdi_path(
 	const struct cam_ife_csid_reg_offset   *csid_reg;
 	struct cam_hw_soc_info                 *soc_info;
 	uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
-	uint32_t format_measure_addr, camera_hw_version, packing_fmt = 0;
+	uint32_t format_measure_addr, camera_hw_version;
+	uint32_t packing_fmt = 0, in_bpp = 0;
 
 	path_data = (struct cam_ife_csid_path_cfg   *) res->res_priv;
 	csid_reg = csid_hw->csid_info->csid_reg;
@@ -2224,7 +2268,7 @@ static int cam_ife_csid_init_config_rdi_path(
 
 	rc = cam_ife_csid_get_format_rdi(path_data->in_format,
 		path_data->out_format, &path_format, &plain_fmt, &packing_fmt,
-		path_data->crop_enable || path_data->drop_enable);
+		path_data->crop_enable || path_data->drop_enable, &in_bpp);
 	if (rc)
 		return rc;
 
@@ -2306,6 +2350,35 @@ static int cam_ife_csid_init_config_rdi_path(
 			csid_reg->rdi_reg[id]->csid_rdi_err_recovery_cfg0_addr);
 	}
 
+	/* configure pixel format measure */
+	if (csid_hw->rdi_path_config[id].measure_enabled) {
+		val = ((csid_hw->rdi_path_config[id].height &
+		csid_reg->cmn_reg->format_measure_height_mask_val) <<
+		csid_reg->cmn_reg->format_measure_height_shift_val);
+
+		if (path_format == 0xF)
+			val |= (__KERNEL_DIV_ROUND_UP(
+				(csid_hw->rdi_path_config[id].width *
+				in_bpp), 8) &
+			csid_reg->cmn_reg->format_measure_width_mask_val);
+		else
+			val |= (csid_hw->rdi_path_config[id].width &
+			csid_reg->cmn_reg->format_measure_width_mask_val);
+
+		CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x",
+			csid_hw->hw_intf->hw_idx, val);
+		CAM_DBG(CAM_ISP, "format measure width : 0x%x height : 0x%x",
+			csid_hw->rdi_path_config[id].width,
+			csid_hw->rdi_path_config[id].height);
+
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+		csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr);
+
+		/* enable pixel and line counter */
+		cam_io_w_mb(3, soc_info->reg_map[0].mem_base +
+		csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr);
+	}
+
 	/* set frame drop pattern to 0 and period to 1 */
 	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
 		csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
@@ -2403,7 +2476,7 @@ static int cam_ife_csid_init_config_udi_path(
 	const struct cam_ife_csid_reg_offset   *csid_reg;
 	struct cam_hw_soc_info                 *soc_info;
 	uint32_t path_format = 0, plain_fmt = 0, val = 0, val1, id;
-	uint32_t format_measure_addr, packing_fmt = 0;
+	uint32_t format_measure_addr, packing_fmt = 0, in_bpp = 0;
 
 	path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
 	csid_reg = csid_hw->csid_info->csid_reg;
@@ -2418,7 +2491,7 @@ static int cam_ife_csid_init_config_udi_path(
 
 	rc = cam_ife_csid_get_format_rdi(path_data->in_format,
 		path_data->out_format, &path_format, &plain_fmt, &packing_fmt,
-		path_data->crop_enable || path_data->drop_enable);
+		path_data->crop_enable || path_data->drop_enable, &in_bpp);
 	if (rc) {
 		CAM_ERR(CAM_ISP,
 			"Failed to get format in_format: %u out_format: %u rc: %d",
@@ -2682,9 +2755,14 @@ static int cam_ife_csid_enable_rdi_path(
 
 	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
 		val |= CSID_PATH_INFO_INPUT_SOF;
+
 	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
 		val |= CSID_PATH_INFO_INPUT_EOF;
 
+	if (csid_hw->rdi_path_config[id].measure_enabled)
+		val |= (CSID_PATH_ERROR_PIX_COUNT |
+			CSID_PATH_ERROR_LINE_COUNT);
+
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 		csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
 
@@ -3308,6 +3386,13 @@ int cam_ife_csid_release(void *hw_priv,
 		break;
 	case CAM_ISP_RESOURCE_PIX_PATH:
 		res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
+		if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
+			csid_hw->ipp_path_config.measure_enabled = 0;
+		else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP)
+			csid_hw->ppp_path_config.measure_enabled = 0;
+		else
+			csid_hw->rdi_path_config[res->res_id].measure_enabled
+				= 0;
 		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
@@ -3858,6 +3943,58 @@ static int cam_ife_csid_set_csid_clock(
 	return 0;
 }
 
+static int cam_ife_csid_set_sensor_dimension(
+	struct cam_ife_csid_hw *csid_hw, void *cmd_args)
+{
+	struct cam_ife_sensor_dimension_update_args *dimension_update = NULL;
+	uint32_t i;
+
+	if (!csid_hw)
+		return -EINVAL;
+
+	dimension_update =
+		(struct cam_ife_sensor_dimension_update_args *)cmd_args;
+	csid_hw->ipp_path_config.measure_enabled =
+		dimension_update->ipp_path.measure_enabled;
+	if (dimension_update->ipp_path.measure_enabled) {
+		csid_hw->ipp_path_config.width  =
+			dimension_update->ipp_path.width;
+		csid_hw->ipp_path_config.height =
+			dimension_update->ipp_path.height;
+		CAM_DBG(CAM_ISP, "CSID ipp path width %d height %d",
+			csid_hw->ipp_path_config.width,
+			csid_hw->ipp_path_config.height);
+	}
+	csid_hw->ppp_path_config.measure_enabled =
+		dimension_update->ppp_path.measure_enabled;
+	if (dimension_update->ppp_path.measure_enabled) {
+		csid_hw->ppp_path_config.width  =
+			dimension_update->ppp_path.width;
+		csid_hw->ppp_path_config.height =
+			dimension_update->ppp_path.height;
+		CAM_DBG(CAM_ISP, "CSID ppp path width %d height %d",
+			csid_hw->ppp_path_config.width,
+			csid_hw->ppp_path_config.height);
+	}
+	for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) {
+		csid_hw->rdi_path_config[i].measure_enabled
+			= dimension_update->rdi_path[i].measure_enabled;
+		if (csid_hw->rdi_path_config[i].measure_enabled) {
+			csid_hw->rdi_path_config[i].width =
+				dimension_update->rdi_path[i].width;
+			csid_hw->rdi_path_config[i].height =
+				dimension_update->rdi_path[i].height;
+			if (csid_hw->rdi_path_config[i].height == 1)
+				csid_hw->rdi_path_config[i].measure_enabled = 0;
+			CAM_DBG(CAM_ISP,
+				"CSID rdi path[%d] width %d height %d",
+				i, csid_hw->rdi_path_config[i].width,
+				csid_hw->rdi_path_config[i].height);
+		}
+	}
+	return 0;
+}
+
 static int cam_ife_csid_set_csid_qcfa(
 	struct cam_ife_csid_hw *csid_hw, void *cmd_args)
 {
@@ -3998,6 +4135,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
 	case CAM_ISP_HW_CMD_DUMP_HW:
 		rc = cam_ife_csid_dump_hw(csid_hw, cmd_args);
 		break;
+	case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG:
+		rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);
@@ -4018,7 +4158,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 	uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
 	uint32_t irq_status_rdi[CAM_IFE_CSID_RDI_MAX] = {0, 0, 0, 0};
 	uint32_t irq_status_udi[CAM_IFE_CSID_UDI_MAX] = {0, 0, 0};
-	uint32_t val, irq_status_ppp = 0;
+	uint32_t val, val2, irq_status_ppp = 0;
 	bool fatal_err_detected = false;
 	uint32_t sof_irq_debug_en = 0;
 	unsigned long flags;
@@ -4345,6 +4485,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 				soc_info->reg_map[0].mem_base +
 				csid_reg->ipp_reg->csid_pxl_ctrl_addr);
 		}
+
+		if ((irq_status_ipp & CSID_PATH_ERROR_PIX_COUNT) ||
+			(irq_status_ipp & CSID_PATH_ERROR_LINE_COUNT)) {
+			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			csid_reg->ipp_reg->csid_pxl_format_measure0_addr);
+
+			CAM_ERR(CAM_ISP,
+				"CSID:%d irq_status_ipp:0x%x",
+				csid_hw->hw_intf->hw_idx, irq_status_ipp);
+			CAM_ERR(CAM_ISP,
+			"Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x",
+			csid_hw->ipp_path_config.height,
+			csid_hw->ipp_path_config.width,
+			((val >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			val &
+			csid_reg->cmn_reg->format_measure_width_mask_val);
+		}
 	}
 
 	/*read PPP errors */
@@ -4388,6 +4547,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 				soc_info->reg_map[0].mem_base +
 				csid_reg->ppp_reg->csid_pxl_ctrl_addr);
 		}
+
+		if ((irq_status_ppp & CSID_PATH_ERROR_PIX_COUNT) ||
+			(irq_status_ppp & CSID_PATH_ERROR_LINE_COUNT)) {
+			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			csid_reg->ppp_reg->csid_pxl_format_measure0_addr);
+
+			CAM_ERR(CAM_ISP,
+				"CSID:%d irq_status_ppp:0x%x",
+				csid_hw->hw_intf->hw_idx, irq_status_ppp);
+			CAM_ERR(CAM_ISP,
+			"Expected:: h:  0x%x w: 0x%x actual:: h: 0x%x w: 0x%x",
+			csid_hw->ppp_path_config.height,
+			csid_hw->ppp_path_config.width,
+			((val >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			val &
+			csid_reg->cmn_reg->format_measure_width_mask_val);
+		}
 	}
 
 	for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
@@ -4428,6 +4606,30 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 				soc_info->reg_map[0].mem_base +
 				csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
 		}
+
+		if ((irq_status_rdi[i] & CSID_PATH_ERROR_PIX_COUNT) ||
+			(irq_status_rdi[i] & CSID_PATH_ERROR_LINE_COUNT)) {
+			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			csid_reg->rdi_reg[i]->csid_rdi_format_measure0_addr);
+			val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			csid_reg->rdi_reg[i]->csid_rdi_format_measure_cfg1_addr
+			);
+			CAM_ERR(CAM_ISP,
+				"CSID:%d irq_status_rdi[%d]:0x%x",
+				csid_hw->hw_intf->hw_idx, i, irq_status_rdi[i]);
+			CAM_ERR(CAM_ISP,
+			"Expected:: h: 0x%x w: 0x%x actual:: h: 0x%x w: 0x%x",
+			((val2 >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			val2 &
+			csid_reg->cmn_reg->format_measure_width_mask_val,
+			((val >>
+			csid_reg->cmn_reg->format_measure_height_shift_val) &
+			csid_reg->cmn_reg->format_measure_height_mask_val),
+			val &
+			csid_reg->cmn_reg->format_measure_width_mask_val);
+		}
 	}
 
 	for (i = 0; i < csid_reg->cmn_reg->num_udis; i++) {
@@ -4641,6 +4843,10 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf  *csid_hw_intf,
 
 	ife_csid_hw->csid_debug = 0;
 	ife_csid_hw->error_irq_count = 0;
+	ife_csid_hw->ipp_path_config.measure_enabled = 0;
+	ife_csid_hw->ppp_path_config.measure_enabled = 0;
+	for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++)
+		ife_csid_hw->rdi_path_config[i].measure_enabled = 0;
 
 	return 0;
 err:

+ 9 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h

@@ -373,6 +373,10 @@ struct cam_ife_csid_common_reg_offset {
 	uint32_t measure_en_hbi_vbi_cnt_mask;
 	uint32_t format_measure_en_val;
 	uint32_t num_bytes_out_shift_val;
+	uint32_t format_measure_width_shift_val;
+	uint32_t format_measure_width_mask_val;
+	uint32_t format_measure_height_shift_val;
+	uint32_t format_measure_height_mask_val;
 };
 
 /**
@@ -582,6 +586,11 @@ struct cam_ife_csid_hw {
 	struct completion    csid_udin_complete[CAM_IFE_CSID_UDI_MAX];
 	uint64_t                         csid_debug;
 	uint64_t                         clk_rate;
+	struct cam_isp_sensor_dimension  ipp_path_config;
+	struct cam_isp_sensor_dimension  ppp_path_config;
+	struct cam_isp_sensor_dimension  rdi_path_config[CAM_IFE_CSID_RDI_MAX];
+	uint32_t                         hbi;
+	uint32_t                         vbi;
 	bool                             sof_irq_triggered;
 	bool                             is_resetting;
 	uint32_t                         irq_debug_cnt;

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

@@ -207,6 +207,7 @@ enum cam_ife_csid_cmd_type {
 	CAM_IFE_CSID_SET_CSID_DEBUG,
 	CAM_IFE_CSID_SOF_IRQ_DEBUG,
 	CAM_IFE_CSID_SET_CONFIG,
+	CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
 	CAM_IFE_CSID_CMD_MAX,
 };
 
@@ -248,4 +249,17 @@ struct cam_ife_csid_epd_update_args {
 	uint32_t                           epd_supported;
 };
 
+/*
+ * struct cam_ife_sensor_dim_update_args:
+ *
+ * @ppp_path:             expected ppp path configuration
+ * @ipp_path:             expected ipp path configuration
+ * @rdi_path:             expected rdi path configuration
+ */
+struct cam_ife_sensor_dimension_update_args {
+	struct cam_isp_sensor_dimension  ppp_path;
+	struct cam_isp_sensor_dimension  ipp_path;
+	struct cam_isp_sensor_dimension  rdi_path[CAM_IFE_CSID_RDI_MAX];
+};
+
 #endif /* _CAM_CSID_HW_INTF_H_ */

+ 46 - 12
include/uapi/camera/media/cam_isp.h

@@ -94,18 +94,19 @@
 #define CAM_ISP_DSP_MODE_ROUND                  2
 
 /* ISP Generic Cmd Buffer Blob types */
-#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG          0
-#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG        1
-#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG           2
-#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG         3
-#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG   4
-#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG           5
-#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2      6
-#define CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG     7
-#define CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG      8
-#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2        9
-#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CONFIG         10
-#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG    12
+#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG                0
+#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG              1
+#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG                 2
+#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG               3
+#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG         4
+#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG                 5
+#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG_V2            6
+#define CAM_ISP_GENERIC_BLOB_TYPE_IFE_CORE_CONFIG           7
+#define CAM_ISP_GENERIC_BLOB_TYPE_VFE_OUT_CONFIG            8
+#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2              9
+#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CONFIG               10
+#define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG   11
+#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG          12
 
 #define CAM_ISP_VC_DT_CFG    4
 
@@ -137,6 +138,8 @@
 #define CAM_ISP_ACQ_CUSTOM_PRIMARY    1
 #define CAM_ISP_ACQ_CUSTOM_SECONDARY  2
 
+#define CAM_IFE_CSID_RDI_MAX          4
+
 /* Query devices */
 /**
  * struct cam_isp_dev_cap_info - A cap info for particular hw type
@@ -599,6 +602,37 @@ struct cam_fe_config {
 	__u32    latency_buf_size;
 } __attribute__((packed));
 
+
+/**
+ * struct cam_isp_sensor_path_dimension
+ *
+ * @width             expected width
+ * @height            expected height
+ * @measure_enabled   flag to indicate if pixel measurement is to be enabled
+ */
+struct cam_isp_sensor_dimension {
+	__u32 width;
+	__u32 height;
+	__u32 measure_enabled;
+} __attribute__((packed));
+
+/**
+ * struct cam_isp_sensor_config - Sensor Dimension configuration
+ *
+ * @ppp_path:                   expected ppp path configuration
+ * @ipp_path:                   expected ipp path configuration
+ * @rdi_path:                   expected rdi path configuration
+ * @hbi:                        HBI value
+ * @vbi:                        VBI value
+ */
+struct cam_isp_sensor_config {
+	struct cam_isp_sensor_dimension  ppp_path;
+	struct cam_isp_sensor_dimension  ipp_path;
+	struct cam_isp_sensor_dimension  rdi_path[CAM_IFE_CSID_RDI_MAX];
+	__u32                   hbi;
+	__u32                   vbi;
+} __attribute__((packed));
+
 /**
  * struct cam_isp_core_config - ISP core registers configuration
  *