Sfoglia il codice sorgente

msm: camera: isp: Add support for new CSID

Add CSID640 support. The following features support are added:
  - QCFA binning and BAYER binning support
  - Format measure support
  - Multi VC DT support
  - Add core_cfg support in in_port structure

CRs-Fixed: 2887030
Change-Id: Idd7d081c985f3ef21e0fee7ce4c1b8db96ddd3c3
Signed-off-by: Wyes Karny <[email protected]>
Wyes Karny 4 anni fa
parent
commit
4e535ac459

+ 1 - 1
Kbuild

@@ -264,7 +264,7 @@ camera-$(CONFIG_SPECTRA_TFE) += \
 	drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_dev.o \
 	drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_soc.o \
 	drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.o \
-	drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.o \
+	drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid.o \
 	drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.o
 
 camera-y += drivers/camera_main.o

+ 406 - 115
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -835,13 +835,13 @@ static int cam_tfe_mgr_process_base_info(
 }
 
 static int cam_tfe_hw_mgr_acquire_res_tfe_out_rdi(
-	struct cam_tfe_hw_mgr_ctx         *tfe_ctx,
-	struct cam_isp_hw_mgr_res         *tfe_in_res,
-	struct cam_isp_tfe_in_port_info   *in_port)
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_hw_mgr_res               *tfe_in_res,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
 {
 	int rc = -EINVAL;
-	struct cam_tfe_acquire_args              tfe_acquire;
-	struct cam_isp_tfe_out_port_info         *out_port = NULL;
+	struct cam_tfe_acquire_args               tfe_acquire;
+	struct cam_isp_tfe_out_port_generic_info *out_port = NULL;
 	struct cam_isp_hw_mgr_res                *tfe_out_res;
 	struct cam_hw_intf                       *hw_intf;
 	uint32_t  i, tfe_out_res_id, tfe_in_res_id;
@@ -917,14 +917,14 @@ err:
 }
 
 static int cam_tfe_hw_mgr_acquire_res_tfe_out_pixel(
-	struct cam_tfe_hw_mgr_ctx           *tfe_ctx,
-	struct cam_isp_hw_mgr_res           *tfe_in_res,
-	struct cam_isp_tfe_in_port_info     *in_port)
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_hw_mgr_res               *tfe_in_res,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
 {
 	int rc = -EINVAL;
 	uint32_t  i, j, k;
 	struct cam_tfe_acquire_args               tfe_acquire;
-	struct cam_isp_tfe_out_port_info          *out_port;
+	struct cam_isp_tfe_out_port_generic_info *out_port;
 	struct cam_isp_hw_mgr_res                *tfe_out_res;
 	struct cam_hw_intf                       *hw_intf;
 
@@ -1002,8 +1002,8 @@ err:
 }
 
 static int cam_tfe_hw_mgr_acquire_res_tfe_out(
-	struct cam_tfe_hw_mgr_ctx         *tfe_ctx,
-	struct cam_isp_tfe_in_port_info   *in_port)
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
 {
 	int rc = -EINVAL;
 	struct cam_isp_hw_mgr_res       *tfe_in_res;
@@ -1039,8 +1039,8 @@ err:
 }
 
 static int cam_tfe_hw_mgr_acquire_res_tfe_in(
-	struct cam_tfe_hw_mgr_ctx         *tfe_ctx,
-	struct cam_isp_tfe_in_port_info   *in_port,
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_tfe_in_port_generic_info *in_port,
 	uint32_t                          *pdaf_enable)
 {
 	int rc                = -EINVAL;
@@ -1156,8 +1156,8 @@ err:
 }
 
 static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
-	struct cam_tfe_hw_mgr_ctx              *tfe_ctx,
-	struct cam_isp_tfe_in_port_info        *in_port)
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
 {
 	int rc = -EINVAL;
 	int i, j;
@@ -1168,7 +1168,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
 	struct cam_tfe_csid_hw_reserve_resource_args  csid_acquire;
 	enum cam_tfe_csid_path_res_id                 path_res_id;
 	struct cam_isp_hw_mgr_res        *csid_res_temp, *csid_res_iterator;
-	struct cam_isp_tfe_out_port_info        *out_port = NULL;
+	struct cam_isp_tfe_out_port_generic_info     *out_port = NULL;
 
 	tfe_hw_mgr = tfe_ctx->hw_mgr;
 	/* get csid resource */
@@ -1398,9 +1398,9 @@ end:
 }
 
 static int cam_tfe_hw_mgr_acquire_tpg(
-	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
-	struct cam_isp_tfe_in_port_info        **in_port,
-	uint32_t                                 num_inport)
+	struct cam_tfe_hw_mgr_ctx                *tfe_ctx,
+	struct cam_isp_tfe_in_port_generic_info  *in_port,
+	uint32_t                                  num_inport)
 {
 	int rc = -EINVAL;
 	uint32_t i, j = 0;
@@ -1418,7 +1418,7 @@ static int cam_tfe_hw_mgr_acquire_tpg(
 		tpg_reserve.num_inport = num_inport;
 		tpg_reserve.node_res = NULL;
 		for (j = 0; j < num_inport; j++)
-			tpg_reserve.in_port[j] = in_port[j];
+			tpg_reserve.in_port[j] = &in_port[j];
 
 		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
 			&tpg_reserve, sizeof(tpg_reserve));
@@ -1469,19 +1469,19 @@ static enum cam_tfe_csid_path_res_id
 }
 
 static int cam_tfe_hw_mgr_acquire_res_tfe_csid_rdi(
-	struct cam_tfe_hw_mgr_ctx         *tfe_ctx,
-	struct cam_isp_tfe_in_port_info   *in_port)
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
 {
 	int rc = -EINVAL;
 	int i, j;
 
-	struct cam_tfe_hw_mgr               *tfe_hw_mgr;
-	struct cam_isp_hw_mgr_res           *csid_res;
-	struct cam_hw_intf                  *hw_intf;
-	struct cam_isp_tfe_out_port_info    *out_port;
-	struct cam_tfe_csid_hw_reserve_resource_args  csid_acquire;
-	struct cam_isp_hw_mgr_res             *csid_res_iterator;
-	enum cam_tfe_csid_path_res_id        path_res_id;
+	struct cam_tfe_hw_mgr                       *tfe_hw_mgr;
+	struct cam_isp_hw_mgr_res                   *csid_res;
+	struct cam_hw_intf                          *hw_intf;
+	struct cam_isp_tfe_out_port_generic_info    *out_port;
+	struct cam_tfe_csid_hw_reserve_resource_args csid_acquire;
+	struct cam_isp_hw_mgr_res                   *csid_res_iterator;
+	enum cam_tfe_csid_path_res_id                path_res_id;
 
 	tfe_hw_mgr = tfe_ctx->hw_mgr;
 
@@ -1639,8 +1639,8 @@ end:
 }
 
 static int cam_tfe_hw_mgr_preprocess_port(
-	struct cam_tfe_hw_mgr_ctx       *tfe_ctx,
-	struct cam_isp_tfe_in_port_info *in_port,
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_tfe_in_port_generic_info *in_port,
 	int                             *ipp_count,
 	int                             *rdi_count,
 	int                             *pdaf_enable)
@@ -1649,9 +1649,9 @@ static int cam_tfe_hw_mgr_preprocess_port(
 	int rdi_num        = 0;
 	bool rdi2_enable   = false;
 	uint32_t i;
-	struct cam_isp_tfe_out_port_info      *out_port;
-	struct cam_tfe_hw_mgr                 *tfe_hw_mgr;
-	struct cam_hw_intf                    *tfe_device;
+	struct cam_isp_tfe_out_port_generic_info *out_port;
+	struct cam_tfe_hw_mgr                    *tfe_hw_mgr;
+	struct cam_hw_intf                       *tfe_device;
 	bool pdaf_rdi2_mux_en = false;
 
 	tfe_hw_mgr = tfe_ctx->hw_mgr;
@@ -1693,8 +1693,8 @@ static int cam_tfe_hw_mgr_preprocess_port(
 }
 
 static int cam_tfe_mgr_acquire_hw_for_ctx(
-	struct cam_tfe_hw_mgr_ctx              *tfe_ctx,
-	struct cam_isp_tfe_in_port_info        *in_port,
+	struct cam_tfe_hw_mgr_ctx               *tfe_ctx,
+	struct cam_isp_tfe_in_port_generic_info *in_port,
 	uint32_t *num_pix_port, uint32_t  *num_rdi_port,
 	uint32_t *pdaf_enable)
 {
@@ -1834,6 +1834,226 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata,
 	}
 }
 
+static int cam_tfe_mgr_acquire_get_unified_structure_v1(
+	struct cam_isp_tfe_acquire_hw_info *acquire_hw_info,
+	uint32_t offset, uint32_t *input_size,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
+{
+	struct cam_isp_tfe_in_port_info *in = NULL;
+	uint32_t in_port_length = 0;
+	int32_t rc = 0, i;
+
+	in = (struct cam_isp_tfe_in_port_info *)
+		((uint8_t *)&acquire_hw_info->data +
+		 acquire_hw_info->input_info_offset + *input_size);
+
+	in_port_length = sizeof(struct cam_isp_tfe_in_port_info) +
+		(in->num_out_res - 1) *
+		sizeof(struct cam_isp_tfe_out_port_info);
+
+	*input_size += in_port_length;
+
+	if (!in_port || ((*input_size) > acquire_hw_info->input_info_size)) {
+		CAM_ERR(CAM_ISP, "Input is not proper");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	in_port->major_ver       =
+		(acquire_hw_info->input_info_version >> 16) & 0xFFFF;
+	in_port->minor_ver       =
+		acquire_hw_info->input_info_version & 0xFFFF;
+	in_port->res_id          =  in->res_id;
+	in_port->lane_type       =  in->lane_type;
+	in_port->lane_num        =  in->lane_num;
+	in_port->lane_cfg        =  in->lane_cfg;
+	in_port->vc[0]           =  in->vc;
+	in_port->dt[0]           =  in->dt;
+	in_port->num_valid_vc_dt = 1;
+	in_port->format          =  in->format;
+	in_port->pix_pattern     =  in->pix_pattern;
+	in_port->usage_type      =  in->usage_type;
+	in_port->left_start      =  in->left_start;
+	in_port->left_end        =  in->left_end;
+	in_port->left_width      =  in->left_width;
+	in_port->right_start     =  in->right_start;
+	in_port->right_end       =  in->right_end;
+	in_port->right_width     =  in->right_width;
+	in_port->line_start      =  in->line_start;
+	in_port->line_end        =  in->line_end;
+	in_port->height          =  in->height;
+	in_port->batch_size      =  in->batch_size;
+	in_port->dsp_mode        =  in->dsp_mode;
+	in_port->sensor_width    =  in->sensor_width;
+	in_port->sensor_height   =  in->sensor_height;
+	in_port->sensor_hbi      =  in->sensor_hbi;
+	in_port->sensor_vbi      =  in->sensor_vbi;
+	in_port->sensor_fps      =  in->sensor_fps;
+	in_port->init_frame_drop =  in->init_frame_drop;
+	in_port->num_out_res     =  in->num_out_res;
+
+	in_port->data = kcalloc(in->num_out_res,
+		sizeof(struct cam_isp_tfe_out_port_generic_info),
+		GFP_KERNEL);
+
+	if (in_port->data == NULL) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < in->num_out_res; i++) {
+		in_port->data[i].res_id       = in->data[i].res_id;
+		in_port->data[i].format       = in->data[i].format;
+		in_port->data[i].width        = in->data[i].width;
+		in_port->data[i].height       = in->data[i].height;
+		in_port->data[i].stride       = in->data[i].stride;
+		in_port->data[i].comp_grp_id  = in->data[i].comp_grp_id;
+		in_port->data[i].secure_mode  = in->data[i].secure_mode;
+		in_port->data[i].wm_mode      = in->data[i].wm_mode;
+		in_port->data[i].reserved     = in->data[i].reserved;
+	}
+
+	return 0;
+err:
+	return rc;
+}
+
+static int cam_tfe_mgr_acquire_get_unified_structure_v2(
+	struct cam_isp_tfe_acquire_hw_info *acquire_hw_info,
+	uint32_t offset, uint32_t *input_size,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
+{
+	struct cam_isp_tfe_in_port_info_v2 *in = NULL;
+	uint32_t in_port_length = 0;
+	int32_t rc = 0, i;
+
+	in = (struct cam_isp_tfe_in_port_info_v2 *)
+		((uint8_t *)&acquire_hw_info->data +
+		 acquire_hw_info->input_info_offset + *input_size);
+
+	in_port_length = sizeof(struct cam_isp_tfe_in_port_info_v2) +
+		(in->num_out_res - 1) *
+		sizeof(struct cam_isp_tfe_out_port_info);
+
+	*input_size += in_port_length;
+
+	if (!in_port || ((*input_size) > acquire_hw_info->input_info_size)) {
+		CAM_ERR(CAM_ISP, "Input is not proper");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	in_port->major_ver       =
+		(acquire_hw_info->input_info_version >> 16) & 0xFFFF;
+	in_port->minor_ver       =
+		acquire_hw_info->input_info_version & 0xFFFF;
+	in_port->res_id          =  in->res_id;
+	in_port->lane_type       =  in->lane_type;
+	in_port->lane_num        =  in->lane_num;
+	in_port->lane_cfg        =  in->lane_cfg;
+	in_port->num_valid_vc_dt =  in->num_valid_vc_dt;
+
+	if (in_port->num_valid_vc_dt == 0 ||
+		in_port->num_valid_vc_dt >= CAM_ISP_TFE_VC_DT_CFG) {
+		CAM_ERR(CAM_ISP, "Invalid i/p arg invalid vc-dt: %d",
+			in->num_valid_vc_dt);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	for (i = 0; i < in_port->num_valid_vc_dt; i++) {
+		in_port->vc[i]        =  in->vc[i];
+		in_port->dt[i]        =  in->dt[i];
+	}
+
+	in_port->format          =  in->format;
+	in_port->pix_pattern     =  in->pix_pattern;
+	in_port->usage_type      =  in->usage_type;
+	in_port->left_start      =  in->left_start;
+	in_port->left_end        =  in->left_end;
+	in_port->left_width      =  in->left_width;
+	in_port->right_start     =  in->right_start;
+	in_port->right_end       =  in->right_end;
+	in_port->right_width     =  in->right_width;
+	in_port->line_start      =  in->line_start;
+	in_port->line_end        =  in->line_end;
+	in_port->height          =  in->height;
+	in_port->batch_size      =  in->batch_size;
+	in_port->dsp_mode        =  in->dsp_mode;
+	in_port->sensor_width    =  in->sensor_width;
+	in_port->sensor_height   =  in->sensor_height;
+	in_port->sensor_hbi      =  in->sensor_hbi;
+	in_port->sensor_vbi      =  in->sensor_vbi;
+	in_port->sensor_fps      =  in->sensor_fps;
+	in_port->init_frame_drop =  in->init_frame_drop;
+	in_port->bayer_bin       =  in->feature_flag &
+					CAM_ISP_TFE_FLAG_BAYER_BIN;
+	in_port->qcfa_bin        =  in->feature_flag &
+					CAM_ISP_TFE_FLAG_QCFA_BIN;
+
+	if (in_port->bayer_bin && in_port->qcfa_bin) {
+		CAM_ERR(CAM_ISP,
+			"Bayer and QCFA binning not supported together!");
+		rc = -EINVAL;
+		goto err;
+	}
+
+	in_port->core_cfg        =  in->core_cfg;
+	in_port->num_out_res     =  in->num_out_res;
+
+	in_port->data = kcalloc(in->num_out_res,
+		sizeof(struct cam_isp_tfe_out_port_generic_info),
+		GFP_KERNEL);
+
+	if (in_port->data == NULL) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < in->num_out_res; i++) {
+		in_port->data[i].res_id       = in->data[i].res_id;
+		in_port->data[i].format       = in->data[i].format;
+		in_port->data[i].width        = in->data[i].width;
+		in_port->data[i].height       = in->data[i].height;
+		in_port->data[i].stride       = in->data[i].stride;
+		in_port->data[i].comp_grp_id  = in->data[i].comp_grp_id;
+		in_port->data[i].secure_mode  = in->data[i].secure_mode;
+		in_port->data[i].wm_mode      = in->data[i].wm_mode;
+		in_port->data[i].reserved     = in->data[i].reserved;
+	}
+
+	return 0;
+err:
+	return rc;
+}
+static int cam_tfe_mgr_acquire_get_unified_structure(
+	struct cam_isp_tfe_acquire_hw_info *acquire_hw_info,
+	uint32_t offset, uint32_t *input_size,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
+{
+	uint32_t major_ver = 0, minor_ver = 0;
+
+	if (acquire_hw_info == NULL || input_size == NULL)
+		return -EINVAL;
+
+	major_ver = (acquire_hw_info->common_info_version >> 12) & 0xF;
+	minor_ver = (acquire_hw_info->common_info_version) & 0xFFF;
+
+	switch (major_ver) {
+	case 1:
+		return cam_tfe_mgr_acquire_get_unified_structure_v1(
+			acquire_hw_info, offset, input_size, in_port);
+	case 2:
+		return cam_tfe_mgr_acquire_get_unified_structure_v2(
+			acquire_hw_info, offset, input_size, in_port);
+	default:
+		CAM_ERR(CAM_ISP, "Invalid ver of i/p port info from user");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /* entry function: acquire_hw */
 static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 {
@@ -1842,18 +2062,15 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 	int rc                                       = -EINVAL;
 	int i, j;
 	struct cam_tfe_hw_mgr_ctx          *tfe_ctx;
-	struct cam_isp_tfe_in_port_info    *in_port = NULL;
+	struct cam_isp_tfe_in_port_generic_info *in_port = NULL;
 	struct cam_cdm_acquire_data         cdm_acquire;
 	uint32_t                            num_pix_port_per_in = 0;
 	uint32_t                            num_rdi_port_per_in = 0;
 	uint32_t                            pdaf_enable = 0;
 	uint32_t                            total_pix_port = 0;
 	uint32_t                            total_rdi_port = 0;
-	uint32_t                            in_port_length = 0;
-	uint32_t                            total_in_port_length = 0;
 	struct cam_isp_tfe_acquire_hw_info *acquire_hw_info = NULL;
-	struct cam_isp_tfe_in_port_info
-		*tpg_inport[CAM_TOP_TPG_MAX_SUPPORTED_DT] = {0, 0, 0, 0};
+	uint32_t                            input_size = 0;
 
 	CAM_DBG(CAM_ISP, "Enter...");
 
@@ -1905,42 +2122,34 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 
 	acquire_hw_info = (struct cam_isp_tfe_acquire_hw_info *)
 		acquire_args->acquire_info;
-	in_port = (struct cam_isp_tfe_in_port_info *)
-		((uint8_t *)&acquire_hw_info->data +
-		 acquire_hw_info->input_info_offset);
+	in_port = kcalloc(acquire_hw_info->num_inputs,
+			sizeof(struct cam_isp_tfe_in_port_generic_info),
+			GFP_KERNEL);
 
-	/* Check any inport has dual tfe usage  */
-	tfe_ctx->is_dual = false;
+	if (!in_port) {
+		CAM_ERR(CAM_ISP, "No memory available");
+		rc = -ENOMEM;
+		goto free_cdm;
+	}
+
+	/* Update in_port structure */
 	for (i = 0; i < acquire_hw_info->num_inputs; i++) {
-		if (in_port->usage_type)
-			tfe_ctx->is_dual = true;
+		rc = cam_tfe_mgr_acquire_get_unified_structure(acquire_hw_info,
+			i, &input_size, &in_port[i]);
 
-		in_port_length =
-			sizeof(struct cam_isp_tfe_in_port_info) +
-			(in_port->num_out_res - 1) *
-			sizeof(struct cam_isp_tfe_out_port_info);
-		total_in_port_length += in_port_length;
-		if (total_in_port_length >
-			acquire_hw_info->input_info_size) {
-			CAM_ERR(CAM_ISP,
-				"buffer size is not enough %d %d",
-				total_in_port_length,
-				acquire_hw_info->input_info_size);
-			rc = -EINVAL;
+		if (rc < 0) {
+			CAM_ERR(CAM_ISP, "Failed in parsing: %d", rc);
 			goto free_cdm;
 		}
-
-		in_port = (struct cam_isp_tfe_in_port_info *)
-			((uint8_t *)in_port + in_port_length);
 	}
 
-	in_port_length = 0;
-	total_in_port_length = 0;
-	in_port = (struct cam_isp_tfe_in_port_info *)
-		((uint8_t *)&acquire_hw_info->data +
-		 acquire_hw_info->input_info_offset);
+	/* Check any inport has dual tfe usage  */
+	tfe_ctx->is_dual = false;
+	for (i = 0; i < acquire_hw_info->num_inputs; i++)
+		if (in_port[i].usage_type)
+			tfe_ctx->is_dual = true;
 
-	if (in_port->res_id == CAM_ISP_TFE_IN_RES_TPG) {
+	if (in_port[0].res_id == CAM_ISP_TFE_IN_RES_TPG) {
 		if (acquire_hw_info->num_inputs >
 			CAM_TOP_TPG_MAX_SUPPORTED_DT) {
 			CAM_ERR(CAM_ISP, "too many number inport:%d for TPG ",
@@ -1949,35 +2158,17 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 			goto free_cdm;
 		}
 
-		for (i = 0; i < acquire_hw_info->num_inputs; i++) {
-			if (in_port->res_id != CAM_ISP_TFE_IN_RES_TPG) {
+		for (i = 1; i < acquire_hw_info->num_inputs; i++) {
+			if (in_port[i].res_id != CAM_ISP_TFE_IN_RES_TPG) {
 				CAM_ERR(CAM_ISP, "Inval :%d inport res id:0x%x",
-					i, in_port->res_id);
+					i, in_port[i].res_id);
 				rc = -EINVAL;
 				goto free_cdm;
 			}
 
-			tpg_inport[i] = in_port;
-			in_port_length =
-				sizeof(struct cam_isp_tfe_in_port_info) +
-				(in_port->num_out_res - 1) *
-				sizeof(struct cam_isp_tfe_out_port_info);
-			total_in_port_length += in_port_length;
-			if (total_in_port_length >
-				acquire_hw_info->input_info_size) {
-				CAM_ERR(CAM_ISP,
-					"buffer size is not enough %d %d",
-					total_in_port_length,
-					acquire_hw_info->input_info_size);
-				rc = -EINVAL;
-				goto free_cdm;
-			}
-
-			in_port = (struct cam_isp_tfe_in_port_info *)
-				((uint8_t *)in_port + in_port_length);
 		}
 
-		rc = cam_tfe_hw_mgr_acquire_tpg(tfe_ctx, tpg_inport,
+		rc = cam_tfe_hw_mgr_acquire_tpg(tfe_ctx, in_port,
 			acquire_hw_info->num_inputs);
 		if (rc)
 			goto free_cdm;
@@ -1985,34 +2176,18 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		tfe_ctx->is_tpg = true;
 	}
 
-	in_port = (struct cam_isp_tfe_in_port_info *)
-		((uint8_t *)&acquire_hw_info->data +
-		 acquire_hw_info->input_info_offset);
-	in_port_length = 0;
-	total_in_port_length = 0;
-
 	/* acquire HW resources */
 	for (i = 0; i < acquire_hw_info->num_inputs; i++) {
 
-		if (in_port->num_out_res > CAM_TFE_HW_OUT_RES_MAX) {
+		if (in_port[i].num_out_res > CAM_TFE_HW_OUT_RES_MAX) {
 			CAM_ERR(CAM_ISP, "too many output res %d",
-				in_port->num_out_res);
+				in_port[i].num_out_res);
 			rc = -EINVAL;
-			goto free_res;
+			goto free_cdm;
 		}
 
-		in_port_length = sizeof(struct cam_isp_tfe_in_port_info) +
-			(in_port->num_out_res - 1) *
-			sizeof(struct cam_isp_tfe_out_port_info);
-		total_in_port_length += in_port_length;
-
-		if (total_in_port_length > acquire_hw_info->input_info_size) {
-			CAM_ERR(CAM_ISP, "buffer size is not enough");
-			rc = -EINVAL;
-			goto free_res;
-		}
-		CAM_DBG(CAM_ISP, "in_res_id %x", in_port->res_id);
-		rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx, in_port,
+		CAM_DBG(CAM_ISP, "in_res_id %x", in_port[i].res_id);
+		rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx, &in_port[i],
 			&num_pix_port_per_in, &num_rdi_port_per_in,
 			&pdaf_enable);
 		total_pix_port += num_pix_port_per_in;
@@ -2022,8 +2197,6 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 			CAM_ERR(CAM_ISP, "can not acquire resource");
 			goto free_res;
 		}
-		in_port = (struct cam_isp_tfe_in_port_info *)
-			((uint8_t *)in_port + in_port_length);
 	}
 
 	/* Check whether context has only RDI resource */
@@ -2044,6 +2217,16 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 	tfe_ctx->ctx_in_use = 1;
 	tfe_ctx->num_reg_dump_buf = 0;
 
+	if (in_port) {
+		for (i = 0; i < acquire_hw_info->num_inputs; i++) {
+			kfree(in_port[i].data);
+			in_port[i].data = NULL;
+		}
+
+		kfree(in_port);
+		in_port = NULL;
+	}
+
 	if (g_tfe_hw_mgr.support_consumed_addr)
 		acquire_args->op_flags |=
 			 CAM_IFE_CTX_CONSUME_ADDR_EN;
@@ -2067,6 +2250,15 @@ free_cdm:
 	cam_cdm_release(tfe_ctx->cdm_handle);
 free_ctx:
 	cam_tfe_hw_mgr_put_ctx(&tfe_hw_mgr->free_ctx_list, &tfe_ctx);
+	if (in_port) {
+		for (i = 0; i < acquire_hw_info->num_inputs; i++) {
+			kfree(in_port[i].data);
+			in_port[i].data = NULL;
+		}
+
+		kfree(in_port);
+		in_port = NULL;
+	}
 err:
 	/* Dump all the current acquired HW */
 	cam_tfe_hw_mgr_dump_all_ctx();
@@ -2075,6 +2267,67 @@ err:
 	return rc;
 }
 
+int cam_tfe_mgr_acquire_get_unified_dev_str(
+	struct cam_isp_tfe_in_port_info   *in,
+	struct cam_isp_tfe_in_port_generic_info *in_port)
+{
+	int i, rc = 0;
+
+	in_port->res_id          =  in->res_id;
+	in_port->lane_type       =  in->lane_type;
+	in_port->lane_num        =  in->lane_num;
+	in_port->lane_cfg        =  in->lane_cfg;
+	in_port->vc[0]           =  in->vc;
+	in_port->dt[0]           =  in->dt;
+	in_port->num_valid_vc_dt = 1;
+	in_port->format          =  in->format;
+	in_port->pix_pattern     =  in->pix_pattern;
+	in_port->usage_type      =  in->usage_type;
+	in_port->left_start      =  in->left_start;
+	in_port->left_end        =  in->left_end;
+	in_port->left_width      =  in->left_width;
+	in_port->right_start     =  in->right_start;
+	in_port->right_end       =  in->right_end;
+	in_port->right_width     =  in->right_width;
+	in_port->line_start      =  in->line_start;
+	in_port->line_end        =  in->line_end;
+	in_port->height          =  in->height;
+	in_port->batch_size      =  in->batch_size;
+	in_port->dsp_mode        =  in->dsp_mode;
+	in_port->sensor_width    =  in->sensor_width;
+	in_port->sensor_height   =  in->sensor_height;
+	in_port->sensor_hbi      =  in->sensor_hbi;
+	in_port->sensor_vbi      =  in->sensor_vbi;
+	in_port->sensor_fps      =  in->sensor_fps;
+	in_port->init_frame_drop =  in->init_frame_drop;
+	in_port->num_out_res     =  in->num_out_res;
+
+	in_port->data = kcalloc(in->num_out_res,
+		sizeof(struct cam_isp_tfe_out_port_generic_info),
+		GFP_KERNEL);
+
+	if (in_port->data == NULL) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < in->num_out_res; i++) {
+		in_port->data[i].res_id       = in->data[i].res_id;
+		in_port->data[i].format       = in->data[i].format;
+		in_port->data[i].width        = in->data[i].width;
+		in_port->data[i].height       = in->data[i].height;
+		in_port->data[i].stride       = in->data[i].stride;
+		in_port->data[i].comp_grp_id  = in->data[i].comp_grp_id;
+		in_port->data[i].secure_mode  = in->data[i].secure_mode;
+		in_port->data[i].wm_mode      = in->data[i].wm_mode;
+		in_port->data[i].reserved     = in->data[i].reserved;
+	}
+
+	return 0;
+err:
+	return rc;
+}
+
 /* entry function: acquire_hw */
 static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 {
@@ -2084,6 +2337,7 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 	int i, j;
 	struct cam_tfe_hw_mgr_ctx         *tfe_ctx;
 	struct cam_isp_tfe_in_port_info   *in_port = NULL;
+	struct cam_isp_tfe_in_port_generic_info *gen_in_port = NULL;
 	struct cam_isp_resource           *isp_resource = NULL;
 	struct cam_cdm_acquire_data        cdm_acquire;
 	uint32_t                           num_pix_port_per_in = 0;
@@ -2143,6 +2397,16 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 
 	isp_resource = (struct cam_isp_resource *)acquire_args->acquire_info;
 
+	gen_in_port = kcalloc(acquire_args->num_acq,
+			sizeof(struct cam_isp_tfe_in_port_generic_info),
+			GFP_KERNEL);
+
+	if (!gen_in_port) {
+		CAM_ERR(CAM_ISP, "No memory available");
+		rc = -ENOMEM;
+		goto free_cdm;
+	}
+
 	/* acquire HW resources */
 	for (i = 0; i < acquire_args->num_acq; i++) {
 		if (isp_resource[i].resource_id != CAM_ISP_RES_ID_PORT)
@@ -2186,13 +2450,25 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 				goto free_res;
 			}
 
-			rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx, in_port,
+			rc = cam_tfe_mgr_acquire_get_unified_dev_str(in_port,
+				&gen_in_port[i]);
+
+			if (rc) {
+				CAM_ERR(CAM_ISP,
+					"Cannot get in_port structure, rc: %d",
+					rc);
+				goto free_res;
+			}
+
+			rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx,
+				&gen_in_port[i],
 				&num_pix_port_per_in, &num_rdi_port_per_in,
 				&pdad_enable);
 			total_pix_port += num_pix_port_per_in;
 			total_rdi_port += num_rdi_port_per_in;
 
 			kfree(in_port);
+			in_port = NULL;
 			if (rc) {
 				CAM_ERR(CAM_ISP, "can not acquire resource");
 				goto free_res;
@@ -2220,6 +2496,15 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 		goto free_res;
 	}
 
+	if (gen_in_port) {
+		for (i = 0; i < acquire_args->num_acq; i++) {
+			kfree(gen_in_port[i].data);
+			gen_in_port[i].data = NULL;
+		}
+		kfree(gen_in_port);
+		gen_in_port = NULL;
+	}
+
 	acquire_args->ctxt_to_hw_map = tfe_ctx;
 	tfe_ctx->ctx_in_use = 1;
 
@@ -2230,7 +2515,13 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 	return 0;
 free_res:
 	cam_tfe_hw_mgr_release_hw_for_ctx(tfe_ctx);
+free_cdm:
 	cam_cdm_release(tfe_ctx->cdm_handle);
+	if (gen_in_port) {
+		for (i = 0; i < acquire_args->num_acq; i++)
+			kfree(gen_in_port[i].data);
+		kfree(gen_in_port);
+	}
 free_ctx:
 	cam_tfe_hw_mgr_put_ctx(&tfe_hw_mgr->free_ctx_list, &tfe_ctx);
 err:

+ 56 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_TFE_CSID_HW_INTF_H_
@@ -8,6 +8,7 @@
 
 #include "cam_isp_hw.h"
 #include "cam_hw_intf.h"
+#include "cam_tfe.h"
 
 /* MAX TFE CSID instance */
 #define CAM_TFE_CSID_HW_NUM_MAX                        3
@@ -37,6 +38,58 @@ enum cam_tfe_csid_irq_reg {
 	TFE_CSID_IRQ_REG_MAX,
 };
 
+struct cam_isp_tfe_out_port_generic_info {
+	uint32_t                res_id;
+	uint32_t                format;
+	uint32_t                width;
+	uint32_t                height;
+	uint32_t                stride;
+	uint32_t                comp_grp_id;
+	uint32_t                secure_mode;
+	uint32_t                wm_mode;
+	uint32_t                reserved;
+};
+
+struct cam_isp_tfe_in_port_generic_info {
+	uint32_t                        major_ver;
+	uint32_t                        minor_ver;
+	uint32_t                        res_id;
+	uint32_t                        lane_type;
+	uint32_t                        lane_num;
+	uint32_t                        lane_cfg;
+	uint32_t                        vc[CAM_ISP_TFE_VC_DT_CFG];
+	uint32_t                        dt[CAM_ISP_TFE_VC_DT_CFG];
+	uint32_t                        num_valid_vc_dt;
+	uint32_t                        format;
+	uint32_t                        pix_pattern;
+	uint32_t                        usage_type;
+	uint32_t                        left_start;
+	uint32_t                        left_end;
+	uint32_t                        left_width;
+	uint32_t                        right_start;
+	uint32_t                        right_end;
+	uint32_t                        right_width;
+	uint32_t                        line_start;
+	uint32_t                        line_end;
+	uint32_t                        height;
+	uint32_t                        batch_size;
+	uint32_t                        dsp_mode;
+	uint32_t                        sensor_width;
+	uint32_t                        sensor_height;
+	uint32_t                        sensor_hbi;
+	uint32_t                        sensor_vbi;
+	uint32_t                        sensor_fps;
+	uint32_t                        init_frame_drop;
+	uint32_t                        num_out_res;
+	uint32_t                        bayer_bin;
+	uint32_t                        qcfa_bin;
+	uint32_t                        core_cfg;
+	uint32_t                        num_bytes_out;
+	uint32_t                        ipp_count;
+	uint32_t                        rdi_count;
+	uint32_t                        secure_mode;
+	struct cam_isp_tfe_out_port_generic_info    *data;
+};
 
 /**
  * struct cam_tfe_csid_hw_caps- get the CSID hw capability
@@ -75,8 +128,8 @@ struct cam_tfe_csid_hw_caps {
 struct cam_tfe_csid_hw_reserve_resource_args {
 	enum cam_isp_resource_type                res_type;
 	uint32_t                                  res_id;
-	struct cam_isp_tfe_in_port_info          *in_port;
-	struct cam_isp_tfe_out_port_info         *out_port;
+	struct cam_isp_tfe_in_port_generic_info  *in_port;
+	struct cam_isp_tfe_out_port_generic_info *out_port;
 	enum cam_isp_hw_sync_mode                 sync_mode;
 	uint32_t                                  master_idx;
 	uint32_t                                  phy_sel;

+ 16 - 16
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_TFE_HW_INTF_H_
@@ -94,14 +94,14 @@ struct cam_tfe_hw_get_hw_cap {
  * @ctx:                     Context data
  */
 struct cam_tfe_hw_tfe_out_acquire_args {
-	struct cam_isp_resource_node      *rsrc_node;
-	struct cam_isp_tfe_out_port_info  *out_port_info;
-	uint32_t                           unique_id;
-	uint32_t                           is_dual;
-	enum cam_isp_hw_split_id           split_id;
-	uint32_t                           is_master;
-	struct cam_cdm_utils_ops          *cdm_ops;
-	void                              *ctx;
+	struct cam_isp_resource_node             *rsrc_node;
+	struct cam_isp_tfe_out_port_generic_info *out_port_info;
+	uint32_t                                  unique_id;
+	uint32_t                                  is_dual;
+	enum cam_isp_hw_split_id                  split_id;
+	uint32_t                                  is_master;
+	struct cam_cdm_utils_ops                 *cdm_ops;
+	void                                     *ctx;
 };
 
 /*
@@ -119,13 +119,13 @@ struct cam_tfe_hw_tfe_out_acquire_args {
  * @dual_tfe_sync_sel_idx    Dual tfe master hardware index
  */
 struct cam_tfe_hw_tfe_in_acquire_args {
-	struct cam_isp_resource_node         *rsrc_node;
-	struct cam_isp_tfe_in_port_info      *in_port;
-	uint32_t                              res_id;
-	void                                 *cdm_ops;
-	enum cam_isp_hw_sync_mode             sync_mode;
-	bool                                  camif_pd_enable;
-	uint32_t                              dual_tfe_sync_sel_idx;
+	struct cam_isp_resource_node            *rsrc_node;
+	struct cam_isp_tfe_in_port_generic_info *in_port;
+	uint32_t                                 res_id;
+	void                                    *cdm_ops;
+	enum cam_isp_hw_sync_mode                sync_mode;
+	bool                                     camif_pd_enable;
+	uint32_t                                 dual_tfe_sync_sel_idx;
 };
 
 /*

+ 4 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h

@@ -9,6 +9,7 @@
 #include "cam_isp_hw.h"
 #include "cam_hw_intf.h"
 #include "cam_ife_csid_hw_intf.h"
+#include "cam_tfe_csid_hw_intf.h"
 
 /* Max top tpg instance */
 #define CAM_TOP_TPG_HW_NUM_MAX                        3
@@ -52,9 +53,9 @@ struct cam_top_tpg_hw_caps {
  *
  */
 struct cam_top_tpg_ver1_reserve_args {
-	uint32_t                          num_inport;
-	struct cam_isp_tfe_in_port_info  *in_port[CAM_TOP_TPG_MAX_SUPPORTED_DT];
-	struct cam_isp_resource_node     *node_res;
+	uint32_t                                 num_inport;
+	struct cam_isp_tfe_in_port_generic_info *in_port[CAM_TOP_TPG_MAX_SUPPORTED_DT];
+	struct cam_isp_resource_node            *node_res;
 };
 
 /**

+ 51 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid.c

@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+
+#include <linux/module.h>
+#include "cam_tfe_csid_core.h"
+#include "cam_tfe_csid530.h"
+#include "cam_tfe_csid640.h"
+#include "cam_tfe_csid_dev.h"
+#include "camera_main.h"
+
+#define CAM_TFE_CSID_DRV_NAME                    "tfe_csid"
+
+static const struct of_device_id cam_tfe_csid_dt_match[] = {
+	{
+		.compatible = "qcom,csid530",
+		.data = &cam_tfe_csid530_hw_info,
+	},
+	{
+		.compatible = "qcom,csid640",
+		.data = &cam_tfe_csid640_hw_info,
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, cam_tfe_csid_dt_match);
+
+struct platform_driver cam_tfe_csid_driver = {
+	.probe = cam_tfe_csid_probe,
+	.remove = cam_tfe_csid_remove,
+	.driver = {
+		.name = CAM_TFE_CSID_DRV_NAME,
+		.of_match_table = cam_tfe_csid_dt_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+int cam_tfe_csid_init_module(void)
+{
+	return platform_driver_register(&cam_tfe_csid_driver);
+}
+
+void cam_tfe_csid_exit_module(void)
+{
+	platform_driver_unregister(&cam_tfe_csid_driver);
+}
+
+MODULE_DESCRIPTION("CAM TFE_CSID driver");
+MODULE_LICENSE("GPL v2");

+ 13 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid.h

@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CAM_TFE_CSID_H_
+#define _CAM_TFE_CSID_H_
+
+int cam_tfe_csid_init_module(void);
+void cam_tfe_csid_exit_module(void);
+
+#endif /*_CAM_TFE_CSID_H_ */
+

+ 0 - 52
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.c

@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
- */
-
-
-#include <linux/module.h>
-#include "cam_tfe_csid_core.h"
-#include "cam_tfe_csid530.h"
-#include "cam_tfe_csid_dev.h"
-#include "camera_main.h"
-
-#define CAM_TFE_CSID_DRV_NAME                    "csid_530"
-#define CAM_TFE_CSID_VERSION_V530                 0x50030000
-
-static struct cam_tfe_csid_hw_info cam_tfe_csid530_hw_info = {
-	.csid_reg = &cam_tfe_csid_530_reg_offset,
-	.hw_dts_version = CAM_TFE_CSID_VERSION_V530,
-};
-
-static const struct of_device_id cam_tfe_csid530_dt_match[] = {
-	{
-		.compatible = "qcom,csid530",
-		.data = &cam_tfe_csid530_hw_info,
-	},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, cam_tfe_csid530_dt_match);
-
-struct platform_driver cam_tfe_csid530_driver = {
-	.probe = cam_tfe_csid_probe,
-	.remove = cam_tfe_csid_remove,
-	.driver = {
-		.name = CAM_TFE_CSID_DRV_NAME,
-		.of_match_table = cam_tfe_csid530_dt_match,
-		.suppress_bind_attrs = true,
-	},
-};
-
-int cam_tfe_csid530_init_module(void)
-{
-	return platform_driver_register(&cam_tfe_csid530_driver);
-}
-
-void cam_tfe_csid530_exit_module(void)
-{
-	platform_driver_unregister(&cam_tfe_csid530_driver);
-}
-
-MODULE_DESCRIPTION("CAM TFE_CSID530 driver");
-MODULE_LICENSE("GPL v2");

+ 16 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_TFE_CSID_530_H_
@@ -8,6 +8,8 @@
 
 #include "cam_tfe_csid_core.h"
 
+#define CAM_TFE_CSID_VERSION_V530                 0x50030000
+
 static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_530_ipp_reg_offset = {
 	.csid_pxl_irq_status_addr            = 0x30,
 	.csid_pxl_irq_mask_addr              = 0x34,
@@ -40,6 +42,8 @@ static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_530_ipp_reg_offset = {
 	.halt_mode_shift                     = 2,
 	.halt_master_sel_master_val          = 3,
 	.halt_master_sel_slave_val           = 0,
+	.binning_supported                   = 0,
+	.is_multi_vc_dt_supported            = false,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_530_rdi_0_reg_offset = {
@@ -68,6 +72,8 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_530_rdi_0_reg_offset = {
 	.csid_rdi_err_recovery_cfg2_addr          = 0x3b8,
 	.csid_rdi_byte_cntr_ping_addr             = 0x3e0,
 	.csid_rdi_byte_cntr_pong_addr             = 0x3e4,
+	/* configurations */
+	.is_multi_vc_dt_supported                 = false,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_530_rdi_1_reg_offset = {
@@ -96,6 +102,8 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_530_rdi_1_reg_offset = {
 	.csid_rdi_err_recovery_cfg2_addr          = 0x4b8,
 	.csid_rdi_byte_cntr_ping_addr             = 0x4e0,
 	.csid_rdi_byte_cntr_pong_addr             = 0x4e4,
+	/* configurations */
+	.is_multi_vc_dt_supported                 = false,
 };
 
 static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_530_rdi_2_reg_offset = {
@@ -124,6 +132,8 @@ static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_530_rdi_2_reg_offset = {
 	.csid_rdi_err_recovery_cfg2_addr          = 0x5b8,
 	.csid_rdi_byte_cntr_ping_addr             = 0x5e0,
 	.csid_rdi_byte_cntr_pong_addr             = 0x5e4,
+	/* configurations */
+	.is_multi_vc_dt_supported                 = false,
 };
 
 static struct cam_tfe_csid_csi2_rx_reg_offset
@@ -207,6 +217,7 @@ static struct cam_tfe_csid_common_reg_offset
 	.rdi_irq_mask_all                             = 0x3FFFF,
 	.top_tfe2_pix_pipe_fuse_reg                   = 0xFE4,
 	.top_tfe2_fuse_reg                            = 0xFE8,
+	.format_measure_support                       = false,
 };
 
 static struct cam_tfe_csid_reg_offset cam_tfe_csid_530_reg_offset = {
@@ -220,7 +231,9 @@ static struct cam_tfe_csid_reg_offset cam_tfe_csid_530_reg_offset = {
 		},
 };
 
-int cam_tfe_csid530_init_module(void);
-void cam_tfe_csid530_exit_module(void);
+static struct cam_tfe_csid_hw_info cam_tfe_csid530_hw_info = {
+	.csid_reg = &cam_tfe_csid_530_reg_offset,
+	.hw_dts_version = CAM_TFE_CSID_VERSION_V530,
+};
 
 #endif /*_CAM_TFE_CSID_530_H_ */

+ 283 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid640.h

@@ -0,0 +1,283 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CAM_TFE_CSID_640_H_
+#define _CAM_TFE_CSID_640_H_
+
+#include "cam_tfe_csid_core.h"
+
+#define CAM_TFE_CSID_VERSION_V640                 0x60040000
+
+static struct cam_tfe_csid_pxl_reg_offset  cam_tfe_csid_640_ipp_reg_offset = {
+	.csid_pxl_irq_status_addr            = 0x30,
+	.csid_pxl_irq_mask_addr              = 0x34,
+	.csid_pxl_irq_clear_addr             = 0x38,
+	.csid_pxl_irq_set_addr               = 0x3c,
+
+	.csid_pxl_cfg0_addr                  = 0x200,
+	.csid_pxl_cfg1_addr                  = 0x204,
+	.csid_pxl_ctrl_addr                  = 0x208,
+	.csid_pxl_hcrop_addr                 = 0x21c,
+	.csid_pxl_vcrop_addr                 = 0x220,
+	.csid_pxl_rst_strobes_addr           = 0x240,
+	.csid_pxl_status_addr                = 0x254,
+	.csid_pxl_misr_val_addr              = 0x258,
+	.csid_pxl_timestamp_curr0_sof_addr   = 0x290,
+	.csid_pxl_timestamp_curr1_sof_addr   = 0x294,
+	.csid_pxl_timestamp_perv0_sof_addr   = 0x298,
+	.csid_pxl_timestamp_perv1_sof_addr   = 0x29c,
+	.csid_pxl_timestamp_curr0_eof_addr   = 0x2a0,
+	.csid_pxl_timestamp_curr1_eof_addr   = 0x2a4,
+	.csid_pxl_timestamp_perv0_eof_addr   = 0x2a8,
+	.csid_pxl_timestamp_perv1_eof_addr   = 0x2ac,
+	.csid_pxl_err_recovery_cfg0_addr     = 0x2d0,
+	.csid_pxl_err_recovery_cfg1_addr     = 0x2d4,
+	.csid_pxl_err_recovery_cfg2_addr     = 0x2d8,
+	.csid_pxl_multi_vcdt_cfg0_addr       = 0x2dc,
+	.csid_pxl_format_measure_cfg0_addr   = 0x270,
+	.csid_pxl_format_measure_cfg1_addr   = 0x274,
+	.csid_pxl_format_measure0_addr       = 0x278,
+	.csid_pxl_format_measure1_addr       = 0x27c,
+	.csid_pxl_format_measure2_addr       = 0x280,
+
+	/* configurations */
+	.pix_store_en_shift_val              = 7,
+	.early_eof_en_shift_val              = 29,
+	.halt_master_sel_shift               = 4,
+	.halt_mode_shift                     = 2,
+	.halt_master_sel_master_val          = 3,
+	.halt_master_sel_slave_val           = 0,
+	.binning_supported                   = 3,
+	.bin_qcfa_en_shift_val               = 30,
+	.bin_en_shift_val                    = 2,
+	.is_multi_vc_dt_supported            = true,
+	.format_measure_en_shift_val         = 0,
+	.measure_en_hbi_vbi_cnt_val          = 0xc,
+};
+
+static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_640_rdi_0_reg_offset = {
+	.csid_rdi_irq_status_addr                 = 0x40,
+	.csid_rdi_irq_mask_addr                   = 0x44,
+	.csid_rdi_irq_clear_addr                  = 0x48,
+	.csid_rdi_irq_set_addr                    = 0x4c,
+
+	.csid_rdi_cfg0_addr                       = 0x300,
+	.csid_rdi_cfg1_addr                       = 0x304,
+	.csid_rdi_ctrl_addr                       = 0x308,
+	.csid_rdi_rst_strobes_addr                = 0x340,
+	.csid_rdi_status_addr                     = 0x350,
+	.csid_rdi_misr_val0_addr                  = 0x354,
+	.csid_rdi_misr_val1_addr                  = 0x358,
+	.csid_rdi_timestamp_curr0_sof_addr        = 0x390,
+	.csid_rdi_timestamp_curr1_sof_addr        = 0x394,
+	.csid_rdi_timestamp_prev0_sof_addr        = 0x398,
+	.csid_rdi_timestamp_prev1_sof_addr        = 0x39c,
+	.csid_rdi_timestamp_curr0_eof_addr        = 0x3a0,
+	.csid_rdi_timestamp_curr1_eof_addr        = 0x3a4,
+	.csid_rdi_timestamp_prev0_eof_addr        = 0x3a8,
+	.csid_rdi_timestamp_prev1_eof_addr        = 0x3ac,
+	.csid_rdi_err_recovery_cfg0_addr          = 0x3b0,
+	.csid_rdi_err_recovery_cfg1_addr          = 0x3b4,
+	.csid_rdi_err_recovery_cfg2_addr          = 0x3b8,
+	.csid_rdi_byte_cntr_ping_addr             = 0x3e0,
+	.csid_rdi_byte_cntr_pong_addr             = 0x3e4,
+	.csid_rdi_multi_vcdt_cfg0_addr            = 0x3bc,
+	.csid_rdi_format_measure_cfg0_addr        = 0x370,
+	.csid_rdi_format_measure_cfg1_addr        = 0x374,
+	.csid_rdi_format_measure0_addr            = 0x378,
+	.csid_rdi_format_measure1_addr            = 0x37c,
+	.csid_rdi_format_measure2_addr            = 0x380,
+
+	/* configurations */
+	.is_multi_vc_dt_supported                 = true,
+	.format_measure_en_shift_val              = 0,
+	.measure_en_hbi_vbi_cnt_val               = 0xc,
+};
+
+static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_640_rdi_1_reg_offset = {
+	.csid_rdi_irq_status_addr                 = 0x50,
+	.csid_rdi_irq_mask_addr                   = 0x54,
+	.csid_rdi_irq_clear_addr                  = 0x58,
+	.csid_rdi_irq_set_addr                    = 0x5c,
+
+	.csid_rdi_cfg0_addr                       = 0x400,
+	.csid_rdi_cfg1_addr                       = 0x404,
+	.csid_rdi_ctrl_addr                       = 0x408,
+	.csid_rdi_rst_strobes_addr                = 0x440,
+	.csid_rdi_status_addr                     = 0x450,
+	.csid_rdi_misr_val0_addr                  = 0x454,
+	.csid_rdi_misr_val1_addr                  = 0x458,
+	.csid_rdi_timestamp_curr0_sof_addr        = 0x490,
+	.csid_rdi_timestamp_curr1_sof_addr        = 0x494,
+	.csid_rdi_timestamp_prev0_sof_addr        = 0x498,
+	.csid_rdi_timestamp_prev1_sof_addr        = 0x49c,
+	.csid_rdi_timestamp_curr0_eof_addr        = 0x4a0,
+	.csid_rdi_timestamp_curr1_eof_addr        = 0x4a4,
+	.csid_rdi_timestamp_prev0_eof_addr        = 0x4a8,
+	.csid_rdi_timestamp_prev1_eof_addr        = 0x4ac,
+	.csid_rdi_err_recovery_cfg0_addr          = 0x4b0,
+	.csid_rdi_err_recovery_cfg1_addr          = 0x4b4,
+	.csid_rdi_err_recovery_cfg2_addr          = 0x4b8,
+	.csid_rdi_byte_cntr_ping_addr             = 0x4e0,
+	.csid_rdi_byte_cntr_pong_addr             = 0x4e4,
+	.csid_rdi_multi_vcdt_cfg0_addr            = 0x4bc,
+	.csid_rdi_format_measure_cfg0_addr        = 0x470,
+	.csid_rdi_format_measure_cfg1_addr        = 0x474,
+	.csid_rdi_format_measure0_addr            = 0x478,
+	.csid_rdi_format_measure1_addr            = 0x47c,
+	.csid_rdi_format_measure2_addr            = 0x480,
+
+	/* configurations */
+	.is_multi_vc_dt_supported                 = true,
+	.format_measure_en_shift_val              = 0,
+	.measure_en_hbi_vbi_cnt_val               = 0xc,
+};
+
+static struct cam_tfe_csid_rdi_reg_offset cam_tfe_csid_640_rdi_2_reg_offset = {
+	.csid_rdi_irq_status_addr                 = 0x60,
+	.csid_rdi_irq_mask_addr                   = 0x64,
+	.csid_rdi_irq_clear_addr                  = 0x68,
+	.csid_rdi_irq_set_addr                    = 0x6c,
+
+	.csid_rdi_cfg0_addr                       = 0x500,
+	.csid_rdi_cfg1_addr                       = 0x504,
+	.csid_rdi_ctrl_addr                       = 0x508,
+	.csid_rdi_rst_strobes_addr                = 0x540,
+	.csid_rdi_status_addr                     = 0x550,
+	.csid_rdi_misr_val0_addr                  = 0x554,
+	.csid_rdi_misr_val1_addr                  = 0x558,
+	.csid_rdi_timestamp_curr0_sof_addr        = 0x590,
+	.csid_rdi_timestamp_curr1_sof_addr        = 0x594,
+	.csid_rdi_timestamp_prev0_sof_addr        = 0x598,
+	.csid_rdi_timestamp_prev1_sof_addr        = 0x59c,
+	.csid_rdi_timestamp_curr0_eof_addr        = 0x5a0,
+	.csid_rdi_timestamp_curr1_eof_addr        = 0x5a4,
+	.csid_rdi_timestamp_prev0_eof_addr        = 0x5a8,
+	.csid_rdi_timestamp_prev1_eof_addr        = 0x5ac,
+	.csid_rdi_err_recovery_cfg0_addr          = 0x5b0,
+	.csid_rdi_err_recovery_cfg1_addr          = 0x5b4,
+	.csid_rdi_err_recovery_cfg2_addr          = 0x5b8,
+	.csid_rdi_byte_cntr_ping_addr             = 0x5e0,
+	.csid_rdi_byte_cntr_pong_addr             = 0x5e4,
+	.csid_rdi_multi_vcdt_cfg0_addr            = 0x5bc,
+	.csid_rdi_format_measure_cfg0_addr        = 0x570,
+	.csid_rdi_format_measure_cfg1_addr        = 0x574,
+	.csid_rdi_format_measure0_addr            = 0x578,
+	.csid_rdi_format_measure1_addr            = 0x57c,
+	.csid_rdi_format_measure2_addr            = 0x580,
+
+	/* configurations */
+	.is_multi_vc_dt_supported                 = true,
+	.format_measure_en_shift_val              = 0,
+	.measure_en_hbi_vbi_cnt_val               = 0xc,
+};
+
+static struct cam_tfe_csid_csi2_rx_reg_offset
+	cam_tfe_csid_640_csi2_reg_offset = {
+	.csid_csi2_rx_irq_status_addr                 = 0x20,
+	.csid_csi2_rx_irq_mask_addr                   = 0x24,
+	.csid_csi2_rx_irq_clear_addr                  = 0x28,
+	.csid_csi2_rx_irq_set_addr                    = 0x2c,
+
+	/*CSI2 rx control */
+	.csid_csi2_rx_cfg0_addr                       = 0x100,
+	.csid_csi2_rx_cfg1_addr                       = 0x104,
+	.csid_csi2_rx_capture_ctrl_addr               = 0x108,
+	.csid_csi2_rx_rst_strobes_addr                = 0x110,
+	.csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr   = 0x120,
+	.csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr   = 0x124,
+	.csid_csi2_rx_captured_short_pkt_0_addr       = 0x128,
+	.csid_csi2_rx_captured_short_pkt_1_addr       = 0x12c,
+	.csid_csi2_rx_captured_long_pkt_0_addr        = 0x130,
+	.csid_csi2_rx_captured_long_pkt_1_addr        = 0x134,
+	.csid_csi2_rx_captured_long_pkt_ftr_addr      = 0x138,
+	.csid_csi2_rx_captured_cphy_pkt_hdr_addr      = 0x13c,
+	.csid_csi2_rx_total_pkts_rcvd_addr            = 0x160,
+	.csid_csi2_rx_stats_ecc_addr                  = 0x164,
+	.csid_csi2_rx_total_crc_err_addr              = 0x168,
+
+	.csi2_rst_srb_all                             = 0x3FFF,
+	.csi2_rst_done_shift_val                      = 27,
+	.csi2_irq_mask_all                            = 0xFFFFFFF,
+	.csi2_misr_enable_shift_val                   = 6,
+	.csi2_capture_long_pkt_en_shift               = 0,
+	.csi2_capture_short_pkt_en_shift              = 1,
+	.csi2_capture_cphy_pkt_en_shift               = 2,
+	.csi2_capture_long_pkt_dt_shift               = 4,
+	.csi2_capture_long_pkt_vc_shift               = 10,
+	.csi2_capture_short_pkt_vc_shift              = 12,
+	.csi2_capture_cphy_pkt_dt_shift               = 14,
+	.csi2_capture_cphy_pkt_vc_shift               = 20,
+	.csi2_rx_phy_num_mask                         = 0x7,
+	.csi2_rx_long_pkt_hdr_rst_stb_shift           = 0x1,
+	.csi2_rx_short_pkt_hdr_rst_stb_shift          = 0x2,
+	.csi2_rx_cphy_pkt_hdr_rst_stb_shift           = 0x3,
+};
+
+static struct cam_tfe_csid_common_reg_offset
+	cam_tfe_csid_640_cmn_reg_offset = {
+	.csid_hw_version_addr                         = 0x0,
+	.csid_cfg0_addr                               = 0x4,
+	.csid_ctrl_addr                               = 0x8,
+	.csid_rst_strobes_addr                        = 0x10,
+
+	.csid_test_bus_ctrl_addr                      = 0x14,
+	.csid_top_irq_status_addr                     = 0x70,
+	.csid_top_irq_mask_addr                       = 0x74,
+	.csid_top_irq_clear_addr                      = 0x78,
+	.csid_top_irq_set_addr                        = 0x7c,
+	.csid_irq_cmd_addr                            = 0x80,
+
+	/*configurations */
+	.major_version                                = 5,
+	.minor_version                                = 3,
+	.version_incr                                 = 0,
+	.num_rdis                                     = 3,
+	.num_pix                                      = 1,
+	.csid_reg_rst_stb                             = 1,
+	.csid_rst_stb                                 = 0x1e,
+	.csid_rst_stb_sw_all                          = 0x1f,
+	.ipp_path_rst_stb_all                         = 0x17,
+	.rdi_path_rst_stb_all                         = 0x97,
+	.path_rst_done_shift_val                      = 1,
+	.path_en_shift_val                            = 31,
+	.dt_id_shift_val                              = 27,
+	.vc_shift_val                                 = 22,
+	.dt_shift_val                                 = 16,
+	.vc1_shift_val                                = 2,
+	.dt1_shift_val                                = 7,
+	.multi_vc_dt_en_shift_val                     = 0,
+	.fmt_shift_val                                = 12,
+	.plain_fmt_shit_val                           = 10,
+	.crop_v_en_shift_val                          = 6,
+	.crop_h_en_shift_val                          = 5,
+	.crop_shift                                   = 16,
+	.ipp_irq_mask_all                             = 0x3FFFF,
+	.rdi_irq_mask_all                             = 0x3FFFF,
+	.top_tfe2_pix_pipe_fuse_reg                   = 0xFE4,
+	.top_tfe2_fuse_reg                            = 0xFE8,
+	.format_measure_support                       = true,
+	.format_measure_height_shift_val              = 16,
+	.format_measure_height_mask_val               = 0xe,
+	.format_measure_width_mask_val                = 0x10,
+};
+
+static struct cam_tfe_csid_reg_offset cam_tfe_csid_640_reg_offset = {
+	.cmn_reg          = &cam_tfe_csid_640_cmn_reg_offset,
+	.csi2_reg         = &cam_tfe_csid_640_csi2_reg_offset,
+	.ipp_reg          = &cam_tfe_csid_640_ipp_reg_offset,
+	.rdi_reg = {
+		&cam_tfe_csid_640_rdi_0_reg_offset,
+		&cam_tfe_csid_640_rdi_1_reg_offset,
+		&cam_tfe_csid_640_rdi_2_reg_offset,
+		},
+};
+
+static struct cam_tfe_csid_hw_info cam_tfe_csid640_hw_info = {
+	.csid_reg = &cam_tfe_csid_640_reg_offset,
+	.hw_dts_version = CAM_TFE_CSID_VERSION_V640,
+};
+
+#endif /*_CAM_TFE_CSID_640_H_ */

+ 255 - 54
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c

@@ -20,6 +20,7 @@
 #include "cam_subdev.h"
 #include "cam_tasklet_util.h"
 #include "cam_common_util.h"
+#include "cam_tfe_csid_hw_intf.h"
 
 /* Timeout value in msec */
 #define TFE_CSID_TIMEOUT                               1000
@@ -204,16 +205,36 @@ static int cam_tfe_csid_get_format_ipp(
 	return rc;
 }
 
+static int cam_tfe_match_vc_dt_pair(int32_t *vc, uint32_t *dt,
+	uint32_t num_valid_vc_dt, struct cam_tfe_csid_cid_data *cid_data)
+{
+	int i;
+
+	if (num_valid_vc_dt == 0 || num_valid_vc_dt > CAM_ISP_TFE_VC_DT_CFG) {
+		CAM_ERR(CAM_ISP, "invalid num_valid_vc_dt: %d",
+			num_valid_vc_dt);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_valid_vc_dt; i++) {
+		if (vc[i] != cid_data->vc_dt[i].vc ||
+			dt[i] != cid_data->vc_dt[i].dt)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int cam_tfe_csid_cid_get(struct cam_tfe_csid_hw *csid_hw,
-	int32_t vc, uint32_t dt, uint32_t *cid)
+	int32_t *vc, uint32_t *dt, uint32_t num_valid_vc_dt,  uint32_t *cid)
 {
-	uint32_t  i = 0;
+	uint32_t  i = 0, j = 0;
 
 	/* Return already reserved CID if the VC/DT matches */
 	for (i = 0; i < CAM_TFE_CSID_CID_MAX; i++) {
 		if (csid_hw->cid_res[i].cnt >= 1) {
-			if (csid_hw->cid_res[i].vc == vc &&
-				csid_hw->cid_res[i].dt == dt) {
+			if (!cam_tfe_match_vc_dt_pair(vc, dt, num_valid_vc_dt,
+				&csid_hw->cid_res[i])) {
 				csid_hw->cid_res[i].cnt++;
 				*cid = i;
 				CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
@@ -225,9 +246,12 @@ static int cam_tfe_csid_cid_get(struct cam_tfe_csid_hw *csid_hw,
 
 	for (i = 0; i < CAM_TFE_CSID_CID_MAX; i++) {
 		if (!csid_hw->cid_res[i].cnt) {
-			csid_hw->cid_res[i].vc  = vc;
-			csid_hw->cid_res[i].dt  = dt;
-			csid_hw->cid_res[i].cnt = 1;
+			for (j = 0; j < num_valid_vc_dt; j++) {
+				csid_hw->cid_res[i].vc_dt[j].vc  = vc[j];
+				csid_hw->cid_res[i].vc_dt[j].dt  = dt[j];
+				csid_hw->cid_res[i].num_valid_vc_dt++;
+				csid_hw->cid_res[i].cnt++;
+			}
 			*cid = i;
 			CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
 				csid_hw->hw_intf->hw_idx, i);
@@ -240,8 +264,10 @@ static int cam_tfe_csid_cid_get(struct cam_tfe_csid_hw *csid_hw,
 	/* Dump CID values */
 	for (i = 0; i < CAM_TFE_CSID_CID_MAX; i++) {
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CID:%d vc:%d dt:%d cnt:%d",
-			csid_hw->hw_intf->hw_idx, i, csid_hw->cid_res[i].vc,
-			csid_hw->cid_res[i].dt, csid_hw->cid_res[i].cnt);
+			csid_hw->hw_intf->hw_idx, i,
+			csid_hw->cid_res[i].vc_dt[0].vc,
+			csid_hw->cid_res[i].vc_dt[0].dt,
+			csid_hw->cid_res[i].cnt);
 	}
 	return -EINVAL;
 }
@@ -450,7 +476,7 @@ static int cam_tfe_csid_cid_reserve(struct cam_tfe_csid_hw *csid_hw,
 	struct cam_tfe_csid_hw_reserve_resource_args  *cid_reserv,
 	uint32_t  *cid_value)
 {
-	int rc = 0;
+	int i,  rc = 0;
 
 	CAM_DBG(CAM_ISP,
 		"CSID:%d res_id:0x%x Lane type:%d lane_num:%d dt:%d vc:%d",
@@ -458,8 +484,8 @@ static int cam_tfe_csid_cid_reserve(struct cam_tfe_csid_hw *csid_hw,
 		cid_reserv->in_port->res_id,
 		cid_reserv->in_port->lane_type,
 		cid_reserv->in_port->lane_num,
-		cid_reserv->in_port->dt,
-		cid_reserv->in_port->vc);
+		cid_reserv->in_port->dt[0],
+		cid_reserv->in_port->vc[0]);
 
 	if (cid_reserv->in_port->res_id >= CAM_ISP_TFE_IN_RES_MAX) {
 		CAM_ERR(CAM_ISP, "CSID:%d  Invalid phy sel %d",
@@ -497,13 +523,16 @@ static int cam_tfe_csid_cid_reserve(struct cam_tfe_csid_hw *csid_hw,
 	}
 
 	/* CSID  CSI2 v1.1 supports 4 vc  */
-	if (cid_reserv->in_port->dt > 0x3f ||
-		cid_reserv->in_port->vc > 0x3) {
-		CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
-			csid_hw->hw_intf->hw_idx,
-			cid_reserv->in_port->vc, cid_reserv->in_port->dt);
-		rc = -EINVAL;
-		goto end;
+	for (i = 0; i < cid_reserv->in_port->num_valid_vc_dt; i++) {
+		if (cid_reserv->in_port->dt[i] > 0x3f ||
+			cid_reserv->in_port->vc[i] > 0x3) {
+			CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
+				csid_hw->hw_intf->hw_idx,
+				cid_reserv->in_port->vc[i],
+				cid_reserv->in_port->dt[i]);
+			rc = -EINVAL;
+			goto end;
+		}
 	}
 
 	if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
@@ -537,6 +566,7 @@ static int cam_tfe_csid_cid_reserve(struct cam_tfe_csid_hw *csid_hw,
 	rc = cam_tfe_csid_cid_get(csid_hw,
 		cid_reserv->in_port->vc,
 		cid_reserv->in_port->dt,
+		cid_reserv->in_port->num_valid_vc_dt,
 		cid_value);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "CSID:%d CID Reserve failed res_id %d",
@@ -575,20 +605,24 @@ end:
 static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
 	struct cam_tfe_csid_hw_reserve_resource_args  *reserve)
 {
-	int rc = 0;
+	int i, rc = 0;
 	struct cam_tfe_csid_path_cfg    *path_data;
 	struct cam_isp_resource_node    *res;
 	uint32_t          cid_value;
 
 	/* CSID  CSI2 v2.0 supports 4 vc */
-	if (reserve->in_port->dt > 0x3f || reserve->in_port->vc > 0x3 ||
-		(reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
-		CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
-			 csid_hw->hw_intf->hw_idx,
-			reserve->in_port->vc, reserve->in_port->dt,
-			reserve->sync_mode);
-		rc = -EINVAL;
-		goto end;
+	for (i = 0; i < reserve->in_port->num_valid_vc_dt; i++) {
+		if (reserve->in_port->dt[i] > 0x3f ||
+			reserve->in_port->vc[i] > 0x3 ||
+			(reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
+			CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
+				csid_hw->hw_intf->hw_idx,
+				reserve->in_port->vc[i],
+				reserve->in_port->dt[i],
+				reserve->sync_mode);
+			rc = -EINVAL;
+			goto end;
+		}
 	}
 
 	switch (reserve->res_id) {
@@ -679,6 +713,9 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
 	path_data->start_line = reserve->in_port->line_start;
 	path_data->end_line = reserve->in_port->line_end;
 
+	path_data->bayer_bin = reserve->in_port->bayer_bin;
+	path_data->qcfa_bin = reserve->in_port->qcfa_bin;
+
 	csid_hw->event_cb = reserve->event_cb;
 	csid_hw->event_cb_priv = reserve->event_cb_prv;
 
@@ -692,8 +729,13 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
 		reserve->in_port->line_start, reserve->in_port->line_end,
 		path_data->crop_enable);
 
-	path_data->dt = reserve->in_port->dt;
-	path_data->vc = reserve->in_port->vc;
+	path_data->num_valid_vc_dt = 0;
+
+	for (i = 0; i < reserve->in_port->num_valid_vc_dt; i++) {
+		path_data->vc_dt[i].vc = reserve->in_port->vc[i];
+		path_data->vc_dt[i].dt = reserve->in_port->dt[i];
+		path_data->num_valid_vc_dt++;
+	}
 
 	if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
 		path_data->start_pixel = reserve->in_port->left_start;
@@ -1048,8 +1090,8 @@ static int cam_tfe_csid_init_config_pxl_path(
 	 * configure Pxl path and enable the time stamp capture.
 	 * enable the HW measrurement blocks
 	 */
-	val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
-		(path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
+	val = (path_data->vc_dt[0].vc << csid_reg->cmn_reg->vc_shift_val) |
+		(path_data->vc_dt[0].dt << csid_reg->cmn_reg->dt_shift_val) |
 		(path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
 		(decode_format << csid_reg->cmn_reg->fmt_shift_val) |
 		(path_data->crop_enable <<
@@ -1058,10 +1100,64 @@ static int cam_tfe_csid_init_config_pxl_path(
 		csid_reg->cmn_reg->crop_v_en_shift_val) |
 		(1 << 1);
 
+	if (pxl_reg->binning_supported && (path_data->qcfa_bin ||
+		path_data->bayer_bin)) {
+
+		CAM_DBG(CAM_ISP,
+			"Set Binning mode, binning_supported: %d, qcfa_bin: %d, bayer_bin: %d",
+			pxl_reg->binning_supported, path_data->qcfa_bin,
+			path_data->bayer_bin);
+
+		if (path_data->bayer_bin && !(pxl_reg->binning_supported &
+			CAM_TFE_CSID_BIN_BAYER)) {
+			CAM_ERR(CAM_ISP,
+				"Bayer bin is not supported! binning_supported: %d",
+				pxl_reg->binning_supported);
+			return -EINVAL;
+		}
+
+		if (path_data->qcfa_bin && !(pxl_reg->binning_supported &
+			CAM_TFE_CSID_BIN_QCFA)) {
+			CAM_ERR(CAM_ISP,
+				"QCFA bin is not supported! binning_supported: %d",
+				pxl_reg->binning_supported);
+			return -EINVAL;
+		}
+
+		if (path_data->qcfa_bin && path_data->bayer_bin) {
+			CAM_ERR(CAM_ISP,
+				"Bayer bin and QCFA bin could not be enabled together!");
+			return -EINVAL;
+		}
+
+		if (path_data->bayer_bin)
+			val |= 1 << pxl_reg->bin_en_shift_val;
+
+		if (path_data->qcfa_bin) {
+			val |= 1 << pxl_reg->bin_qcfa_en_shift_val;
+			val |= 1 << pxl_reg->bin_en_shift_val;
+		}
+	}
+
+	if (csid_reg->cmn_reg->format_measure_support &&
+		(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO))
+		val |= (1 << pxl_reg->format_measure_en_shift_val);
+
 	val |= (1 << pxl_reg->pix_store_en_shift_val);
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_cfg0_addr);
 
+	if (pxl_reg->is_multi_vc_dt_supported &&
+		(path_data->num_valid_vc_dt > 1)) {
+		val = ((path_data->vc_dt[1].vc <<
+			csid_reg->cmn_reg->vc1_shift_val) |
+			(path_data->vc_dt[1].dt <<
+			csid_reg->cmn_reg->dt1_shift_val) |
+			1 << csid_reg->cmn_reg->multi_vc_dt_en_shift_val);
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			pxl_reg->csid_pxl_multi_vcdt_cfg0_addr);
+	}
+
 	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_cfg1_addr);
 
@@ -1097,6 +1193,15 @@ static int cam_tfe_csid_init_config_pxl_path(
 		}
 	}
 
+	if (csid_reg->cmn_reg->format_measure_support &&
+		(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO)) {
+		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			pxl_reg->csid_pxl_format_measure_cfg0_addr);
+		val |= pxl_reg->measure_en_hbi_vbi_cnt_val;
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			pxl_reg->csid_pxl_format_measure_cfg0_addr);
+	}
+
 	/* Enable the Pxl path */
 	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_cfg0_addr);
@@ -1115,23 +1220,23 @@ static int cam_tfe_csid_init_config_pxl_path(
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
 		val = ((1 <<
 			csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
-			(path_data->vc <<
+			(path_data->vc_dt[0].vc <<
 			csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
 
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
 		val |= ((1 <<
 			csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
-			(path_data->dt <<
+			(path_data->vc_dt[0].dt <<
 			csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
-			(path_data->vc <<
+			(path_data->vc_dt[0].vc <<
 			csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
 
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
 		val |= ((1 <<
 			csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
-			(path_data->dt <<
+			(path_data->vc_dt[0].dt <<
 			csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
-			(path_data->vc <<
+			(path_data->vc_dt[0].vc <<
 			csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
 
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
@@ -1245,6 +1350,11 @@ static int cam_tfe_csid_enable_pxl_path(
 		TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION |
 		TFE_CSID_PATH_IPP_OVERFLOW_IRQ;
 
+	if (csid_reg->cmn_reg->format_measure_support) {
+		val |= TFE_CSID_PATH_ERROR_PIX_COUNT |
+			TFE_CSID_PATH_ERROR_LINE_COUNT;
+	}
+
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)
 		val |= TFE_CSID_PATH_INFO_INPUT_SOF;
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)
@@ -1392,9 +1502,10 @@ static int cam_tfe_csid_init_config_rdi_path(
 	struct cam_isp_resource_node    *res)
 {
 	int rc = 0;
-	struct cam_tfe_csid_path_cfg           *path_data;
-	const struct cam_tfe_csid_reg_offset   *csid_reg;
-	struct cam_hw_soc_info                 *soc_info;
+	struct cam_tfe_csid_path_cfg             *path_data;
+	const struct cam_tfe_csid_reg_offset     *csid_reg;
+	const struct cam_tfe_csid_rdi_reg_offset *rdi_reg;
+	struct cam_hw_soc_info                   *soc_info;
 	uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
 
 	path_data = (struct cam_tfe_csid_path_cfg   *) res->res_priv;
@@ -1408,6 +1519,7 @@ static int cam_tfe_csid_init_config_rdi_path(
 		return -EINVAL;
 	}
 
+	rdi_reg = csid_reg->rdi_reg[id];
 	rc = cam_tfe_csid_get_format_rdi(path_data->in_format,
 		path_data->out_format, &path_format, &plain_fmt);
 	if (rc)
@@ -1417,16 +1529,31 @@ static int cam_tfe_csid_init_config_rdi_path(
 	 * RDI path config and enable the time stamp capture
 	 * Enable the measurement blocks
 	 */
-	val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
-		(path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
+	val = (path_data->vc_dt[0].vc << csid_reg->cmn_reg->vc_shift_val) |
+		(path_data->vc_dt[0].dt << csid_reg->cmn_reg->dt_shift_val) |
 		(path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
 		(path_format << csid_reg->cmn_reg->fmt_shift_val) |
 		(plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) |
 		(1 << 2) | 1;
 
+	if (csid_reg->cmn_reg->format_measure_support &&
+		(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO))
+		val |= (1 << rdi_reg->format_measure_en_shift_val);
+
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 			csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
 
+	if (csid_reg->rdi_reg[id]->is_multi_vc_dt_supported &&
+		(path_data->num_valid_vc_dt > 1)) {
+		val = ((path_data->vc_dt[1].vc <<
+			csid_reg->cmn_reg->vc1_shift_val) |
+			(path_data->vc_dt[1].dt <<
+			csid_reg->cmn_reg->dt1_shift_val) |
+			(1 << csid_reg->cmn_reg->multi_vc_dt_en_shift_val));
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			csid_reg->rdi_reg[id]->csid_rdi_multi_vcdt_cfg0_addr);
+	}
+
 	/* select the post irq sub sample strobe for time stamp capture */
 	cam_io_w_mb(TFE_CSID_TIMESTAMP_STB_POST_IRQ,
 		soc_info->reg_map[0].mem_base +
@@ -1441,6 +1568,15 @@ static int cam_tfe_csid_init_config_rdi_path(
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 			csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
 
+	if (csid_reg->cmn_reg->format_measure_support &&
+		(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO)) {
+		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+			rdi_reg->csid_rdi_format_measure_cfg0_addr);
+		val |= rdi_reg->measure_en_hbi_vbi_cnt_val;
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			rdi_reg->csid_rdi_format_measure_cfg0_addr);
+	}
+
 	/* Enable the RPP path */
 	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
 		csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
@@ -1453,23 +1589,23 @@ static int cam_tfe_csid_init_config_rdi_path(
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
 		val = ((1 <<
 			csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
-			(path_data->vc <<
+			(path_data->vc_dt[0].vc <<
 			csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
 
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
 		val |= ((1 <<
 			csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
-			(path_data->dt <<
+			(path_data->vc_dt[0].dt <<
 			csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
-			(path_data->vc <<
+			(path_data->vc_dt[0].vc <<
 			csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
 
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
 		val |= ((1 <<
 			csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
-			(path_data->dt <<
+			(path_data->vc_dt[0].dt <<
 			csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
-			(path_data->vc <<
+			(path_data->vc_dt[0].vc <<
 			csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
@@ -1541,6 +1677,11 @@ static int cam_tfe_csid_enable_rdi_path(
 		TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION |
 		TFE_CSID_PATH_RDI_OVERFLOW_IRQ;
 
+	if (csid_reg->cmn_reg->format_measure_support) {
+		val |= TFE_CSID_PATH_ERROR_PIX_COUNT |
+			TFE_CSID_PATH_ERROR_LINE_COUNT;
+	}
+
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)
 		val |= TFE_CSID_PATH_INFO_INPUT_SOF;
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)
@@ -2420,7 +2561,7 @@ static int cam_tfe_csid_get_regdump(struct cam_tfe_csid_hw *csid_hw,
 	struct cam_isp_resource_node      *res;
 	struct cam_tfe_csid_path_cfg      *path_data;
 	uint32_t id;
-	int val;
+	int i, val;
 
 	csid_reg = (struct cam_tfe_csid_reg_offset   *)
 			csid_hw->csid_info->csid_reg;
@@ -2489,10 +2630,14 @@ static int cam_tfe_csid_get_regdump(struct cam_tfe_csid_hw *csid_hw,
 		path_data->start_line, path_data->end_line,
 		path_data->width, path_data->height);
 	CAM_INFO(CAM_ISP,
-		"clock:%d crop_enable:%d vc:%d dt:%d informat:%d outformat:%d",
+		"clock:%d crop_enable:%d num of vc_dt:%d informat:%d outformat:%d",
 		path_data->clk_rate, path_data->crop_enable,
-		path_data->vc, path_data->dt,
+		path_data->num_valid_vc_dt,
 		path_data->in_format, path_data->out_format);
+	for (i = 0; i < path_data->num_valid_vc_dt; i++) {
+		CAM_INFO(CAM_ISP, "vc[%d]: %d, dt[%d]: %d",
+			i, path_data->vc_dt[i].vc, i, path_data->vc_dt[i].dt);
+	}
 
 	return 0;
 }
@@ -2884,12 +3029,15 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
 	struct cam_tfe_csid_hw                         *csid_hw;
 	struct cam_hw_soc_info                         *soc_info;
 	const struct cam_tfe_csid_reg_offset           *csid_reg;
+	const struct cam_tfe_csid_pxl_reg_offset       *ipp_reg;
+	const struct cam_tfe_csid_rdi_reg_offset       *rdi_reg;
+	const struct cam_tfe_csid_common_reg_offset    *cmn_reg;
 	const struct cam_tfe_csid_csi2_rx_reg_offset   *csi2_reg;
 	uint32_t                   irq_status[TFE_CSID_IRQ_REG_MAX];
 	bool fatal_err_detected = false, is_error_irq = false;
 	uint32_t sof_irq_debug_en = 0, log_en = 0;
 	unsigned long flags;
-	uint32_t i, val;
+	uint32_t i, val, val1;
 
 	if (!data) {
 		CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
@@ -3213,6 +3361,32 @@ handle_fatal_error:
 			TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION)
 			is_error_irq = true;
 
+		if ((irq_status[TFE_CSID_IRQ_REG_IPP] &
+			TFE_CSID_PATH_ERROR_PIX_COUNT) ||
+			(irq_status[TFE_CSID_IRQ_REG_IPP] &
+			TFE_CSID_PATH_ERROR_LINE_COUNT)) {
+			ipp_reg = csid_reg->ipp_reg;
+			cmn_reg = csid_reg->cmn_reg;
+			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+				ipp_reg->csid_pxl_format_measure0_addr);
+			val1 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+				ipp_reg->csid_pxl_format_measure_cfg1_addr);
+
+			CAM_ERR(CAM_ISP,
+				"Pix/Line count error for CSID: %d IPP path, Expected:: height: %d, width: %d and  Actual:: height: %d width %d",
+				csid_hw->hw_intf->hw_idx,
+				((val1 >>
+				cmn_reg->format_measure_height_shift_val) &
+				cmn_reg->format_measure_height_mask_val),
+				val1 &
+				cmn_reg->format_measure_width_mask_val,
+				((val >>
+				cmn_reg->format_measure_height_shift_val) &
+				cmn_reg->format_measure_height_mask_val),
+				val &
+				cmn_reg->format_measure_width_mask_val);
+		}
+
 	}
 
 	for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
@@ -3264,6 +3438,30 @@ handle_fatal_error:
 			(irq_status[i] &
 				 TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION))
 			is_error_irq = true;
+
+		if ((irq_status[i] & TFE_CSID_PATH_ERROR_PIX_COUNT) ||
+			(irq_status[i] & TFE_CSID_PATH_ERROR_LINE_COUNT)) {
+			rdi_reg = csid_reg->rdi_reg[i];
+			cmn_reg = csid_reg->cmn_reg;
+			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+				rdi_reg->csid_rdi_format_measure0_addr);
+			val1 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+				rdi_reg->csid_rdi_format_measure_cfg1_addr);
+
+			CAM_ERR(CAM_ISP,
+				"Pix/Line count error for CSID:%d RDI:%d path, Expected:: height: %d, width: %d and  Actual:: height: %d width %d",
+				csid_hw->hw_intf->hw_idx, i,
+				((val1 >>
+				cmn_reg->format_measure_height_shift_val) &
+				cmn_reg->format_measure_height_mask_val),
+				val1 &
+				cmn_reg->format_measure_width_mask_val,
+				((val >>
+				cmn_reg->format_measure_height_shift_val) &
+				cmn_reg->format_measure_height_mask_val),
+				val &
+				cmn_reg->format_measure_width_mask_val);
+		}
 	}
 
 	if (is_error_irq || log_en)
@@ -3283,7 +3481,7 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf  *csid_hw_intf,
 	uint32_t csid_idx)
 {
 	int rc = -EINVAL;
-	uint32_t i, val, clk_lvl;
+	uint32_t i, j, val, clk_lvl;
 	struct cam_tfe_csid_path_cfg         *path_data;
 	struct cam_hw_info                   *csid_hw_info;
 	struct cam_tfe_csid_hw               *tfe_csid_hw = NULL;
@@ -3350,8 +3548,11 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf  *csid_hw_intf,
 
 	/* reset the cid values */
 	for (i = 0; i < CAM_TFE_CSID_CID_MAX; i++) {
-		tfe_csid_hw->cid_res[i].vc  = 0;
-		tfe_csid_hw->cid_res[i].dt  = 0;
+		for (j = 0; j < CAM_ISP_TFE_VC_DT_CFG ; j++) {
+			tfe_csid_hw->cid_res[i].vc_dt[j].vc  = 0;
+			tfe_csid_hw->cid_res[i].vc_dt[j].dt  = 0;
+		}
+		tfe_csid_hw->cid_res[i].num_valid_vc_dt = 0;
 		tfe_csid_hw->cid_res[i].cnt = 0;
 	}
 

+ 88 - 33
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_TFE_CSID_HW_H_
@@ -52,6 +52,8 @@
 #define TFE_CSID_PATH_INFO_INPUT_EOL                  BIT(10)
 #define TFE_CSID_PATH_INFO_INPUT_SOL                  BIT(11)
 #define TFE_CSID_PATH_INFO_INPUT_SOF                  BIT(12)
+#define TFE_CSID_PATH_ERROR_PIX_COUNT                 BIT(13)
+#define TFE_CSID_PATH_ERROR_LINE_COUNT                BIT(14)
 #define TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION        BIT(15)
 #define TFE_CSID_PATH_IPP_OVERFLOW_IRQ                BIT(16)
 #define TFE_CSID_PATH_IPP_FRAME_DROP                  BIT(17)
@@ -76,6 +78,14 @@
 
 #define CAM_CSID_EVT_PAYLOAD_MAX                  10
 
+/* Binning supported masks. Binning support changes for specific paths
+ * and also for targets. With the mask, we handle the supported features
+ * in reg files and handle in code accordingly.
+ */
+
+#define CAM_TFE_CSID_BIN_BAYER                        BIT(0)
+#define CAM_TFE_CSID_BIN_QCFA                         BIT(1)
+
 /* enum cam_csid_path_halt_mode select the path halt mode control */
 enum cam_tfe_csid_path_halt_mode {
 	TFE_CSID_HALT_MODE_INTERNAL,
@@ -121,6 +131,12 @@ struct cam_tfe_csid_pxl_reg_offset {
 	uint32_t csid_pxl_err_recovery_cfg0_addr;
 	uint32_t csid_pxl_err_recovery_cfg1_addr;
 	uint32_t csid_pxl_err_recovery_cfg2_addr;
+	uint32_t csid_pxl_multi_vcdt_cfg0_addr;
+	uint32_t csid_pxl_format_measure_cfg0_addr;
+	uint32_t csid_pxl_format_measure_cfg1_addr;
+	uint32_t csid_pxl_format_measure0_addr;
+	uint32_t csid_pxl_format_measure1_addr;
+	uint32_t csid_pxl_format_measure2_addr;
 
 	/* configuration */
 	uint32_t pix_store_en_shift_val;
@@ -129,6 +145,12 @@ struct cam_tfe_csid_pxl_reg_offset {
 	uint32_t halt_mode_shift;
 	uint32_t halt_master_sel_master_val;
 	uint32_t halt_master_sel_slave_val;
+	uint32_t binning_supported;
+	uint32_t bin_qcfa_en_shift_val;
+	uint32_t bin_en_shift_val;
+	uint32_t format_measure_en_shift_val;
+	uint32_t measure_en_hbi_vbi_cnt_val;
+	bool     is_multi_vc_dt_supported;
 };
 
 struct cam_tfe_csid_rdi_reg_offset {
@@ -158,9 +180,18 @@ struct cam_tfe_csid_rdi_reg_offset {
 	uint32_t csid_rdi_err_recovery_cfg2_addr;
 	uint32_t csid_rdi_byte_cntr_ping_addr;
 	uint32_t csid_rdi_byte_cntr_pong_addr;
+	uint32_t csid_rdi_multi_vcdt_cfg0_addr;
+	uint32_t csid_rdi_format_measure_cfg0_addr;
+	uint32_t csid_rdi_format_measure_cfg1_addr;
+	uint32_t csid_rdi_format_measure0_addr;
+	uint32_t csid_rdi_format_measure1_addr;
+	uint32_t csid_rdi_format_measure2_addr;
 
 	/* configuration */
 	uint32_t packing_format;
+	uint32_t format_measure_en_shift_val;
+	uint32_t measure_en_hbi_vbi_cnt_val;
+	bool     is_multi_vc_dt_supported;
 };
 
 struct cam_tfe_csid_csi2_rx_reg_offset {
@@ -234,6 +265,9 @@ struct cam_tfe_csid_common_reg_offset {
 	uint32_t dt_id_shift_val;
 	uint32_t vc_shift_val;
 	uint32_t dt_shift_val;
+	uint32_t vc1_shift_val;
+	uint32_t dt1_shift_val;
+	uint32_t multi_vc_dt_en_shift_val;
 	uint32_t fmt_shift_val;
 	uint32_t plain_fmt_shit_val;
 	uint32_t crop_v_en_shift_val;
@@ -243,6 +277,10 @@ struct cam_tfe_csid_common_reg_offset {
 	uint32_t rdi_irq_mask_all;
 	uint32_t top_tfe2_pix_pipe_fuse_reg;
 	uint32_t top_tfe2_fuse_reg;
+	uint32_t format_measure_height_shift_val;
+	uint32_t format_measure_height_mask_val;
+	uint32_t format_measure_width_mask_val;
+	bool     format_measure_support;
 };
 
 /**
@@ -291,52 +329,67 @@ struct cam_tfe_csid_csi2_rx_cfg  {
 };
 
 /**
- * struct cam_tfe_csid_cid_data- cid configuration private data
+ * struct vc_dt_data- VC DT data
  *
- * @vc:          Virtual channel
- * @dt:          Data type
- * @cnt:         Cid resource reference count.
+ * @vc:          VC data
+ * @dt:          DT data
  *
  */
-struct cam_tfe_csid_cid_data {
+struct vc_dt_data {
 	uint32_t                     vc;
 	uint32_t                     dt;
+};
+
+/**
+ * struct cam_tfe_csid_cid_data- cid configuration private data
+ *
+ * @vc_dt:              VC DT data
+ * @num_valid_vc_dt:    Number of VC-DTs
+ * @cnt:                Cid resource reference count.
+ *
+ */
+struct cam_tfe_csid_cid_data {
+	struct vc_dt_data            vc_dt[CAM_ISP_TFE_VC_DT_CFG];
+	uint32_t                     num_valid_vc_dt;
 	uint32_t                     cnt;
 };
 
 /**
  * struct cam_tfe_csid_path_cfg- csid path configuration details. It is stored
  *                          as private data for IPP/ RDI paths
- * @vc :            Virtual channel number
- * @dt :            Data type number
- * @cid             cid number, it is same as DT_ID number in HW
- * @in_format:      input decode format
- * @out_format:     output format
- * @crop_enable:    crop is enable or disabled, if enabled
- *                  then remaining parameters are valid.
- * @start_pixel:    start pixel
- * @end_pixel:      end_pixel
- * @width:          width
- * @start_line:     start line
- * @end_line:       end_line
- * @height:         heigth
- * @sync_mode:      Applicable for IPP/RDI path reservation
- *                  Reserving the path for master IPP or slave IPP
- *                  master (set value 1), Slave ( set value 2)
- *                  for RDI, set  mode to none
- * @master_idx:     For Slave reservation, Give master TFE instance Index.
- *                  Slave will synchronize with master Start and stop operations
- * @clk_rate        Clock rate
- * @sensor_width    Sensor width in pixel
- * @sensor_height   Sensor height in pixel
- * @sensor_fps      Sensor fps
- * @sensor_hbi      Sensor horizontal blanking interval
- * @sensor_vbi      Sensor vertical blanking interval
+ * @vc_dt :             VC DT data
+ * @num_valid_vc_dt:    Number of valid VC-DTs
+ * @cid                 cid number, it is same as DT_ID number in HW
+ * @in_format:          input decode format
+ * @out_format:         output format
+ * @crop_enable:        crop is enable or disabled, if enabled
+ *                      then remaining parameters are valid.
+ * @start_pixel:        start pixel
+ * @end_pixel:          end_pixel
+ * @width:              width
+ * @start_line:         start line
+ * @end_line:           end_line
+ * @height:             heigth
+ * @sync_mode:          Applicable for IPP/RDI path reservation
+ *                      Reserving the path for master IPP or slave IPP
+ *                      master (set value 1), Slave ( set value 2)
+ *                      for RDI, set  mode to none
+ * @master_idx:         For Slave reservation, Give master TFE instance Index.
+ *                      Slave will synchronize with master Start and stop
+ *                      operations
+ * @clk_rate:           Clock rate
+ * @sensor_width:       Sensor width in pixel
+ * @sensor_height:      Sensor height in pixel
+ * @sensor_fps:         Sensor fps
+ * @sensor_hbi:         Sensor horizontal blanking interval
+ * @sensor_vbi:         Sensor vertical blanking interval
+ * @bayer_bin:          Bayer binning
+ * @qcfa_bin:           Quad-CFA binning
  *
  */
 struct cam_tfe_csid_path_cfg {
-	uint32_t                        vc;
-	uint32_t                        dt;
+	struct vc_dt_data               vc_dt[CAM_ISP_TFE_VC_DT_CFG];
+	uint32_t                        num_valid_vc_dt;
 	uint32_t                        cid;
 	uint32_t                        in_format;
 	uint32_t                        out_format;
@@ -355,6 +408,8 @@ struct cam_tfe_csid_path_cfg {
 	uint32_t                        sensor_fps;
 	uint32_t                        sensor_hbi;
 	uint32_t                        sensor_vbi;
+	uint32_t                        bayer_bin;
+	uint32_t                        qcfa_bin;
 };
 
 /**

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

@@ -51,6 +51,7 @@ static struct cam_tfe_top_reg_offset_common  tfe530_top_commong_reg  = {
 	.diag_min_hbi_error_shift               = 15,
 	.diag_neq_hbi_shift                     = 14,
 	.diag_sensor_hbi_mask                   = 0x3FFF,
+	.serializer_supported                   = false,
 };
 
 static struct cam_tfe_camif_reg  tfe530_camif_reg = {

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h

@@ -64,6 +64,7 @@ static struct cam_tfe_top_reg_offset_common  tfe640_top_commong_reg  = {
 	.diag_min_hbi_error_shift               = 15,
 	.diag_neq_hbi_shift                     = 14,
 	.diag_sensor_hbi_mask                   = 0x3FFF,
+	.serializer_supported                   = true,
 };
 
 static struct cam_tfe_camif_reg  tfe640_camif_reg = {
@@ -119,6 +120,9 @@ static struct cam_tfe_camif_reg_data tfe640_camif_reg_data = {
 	.perf_client_sel_shift        = 8,
 	.perf_window_start_shift      = 16,
 	.perf_window_end_shift        = 20,
+	.ai_c_srl_en_shift            = 11,
+	.ds16_c_srl_en_shift          = 10,
+	.ds4_c_srl_en_shift           = 9,
 };
 
 static struct cam_tfe_rdi_reg  tfe640_rdi0_reg = {

+ 19 - 18
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c

@@ -20,6 +20,7 @@
 #include "cam_tfe_soc.h"
 #include "cam_debug_util.h"
 #include "cam_cpas_api.h"
+#include "cam_tfe_csid_hw_intf.h"
 
 
 static const char drv_name[] = "tfe_bus";
@@ -680,15 +681,15 @@ static int cam_tfe_bus_acquire_rdi_wm(
 }
 
 static int cam_tfe_bus_acquire_wm(
-	struct cam_tfe_bus_priv               *bus_priv,
-	struct cam_isp_tfe_out_port_info      *out_port_info,
-	struct cam_isp_resource_node         **wm_res,
-	void                                  *tasklet,
-	enum cam_tfe_bus_tfe_out_id            tfe_out_res_id,
-	enum cam_tfe_bus_plane_type            plane,
-	uint32_t                              *client_done_mask,
-	uint32_t                               is_dual,
-	enum cam_tfe_bus_comp_grp_id          *comp_grp_id)
+	struct cam_tfe_bus_priv                  *bus_priv,
+	struct cam_isp_tfe_out_port_generic_info *out_port_info,
+	struct cam_isp_resource_node            **wm_res,
+	void                                     *tasklet,
+	enum cam_tfe_bus_tfe_out_id               tfe_out_res_id,
+	enum cam_tfe_bus_plane_type               plane,
+	uint32_t                                 *client_done_mask,
+	uint32_t                                  is_dual,
+	enum cam_tfe_bus_comp_grp_id             *comp_grp_id)
 {
 	struct cam_isp_resource_node         *wm_res_local = NULL;
 	struct cam_tfe_bus_wm_resource_data  *rsrc_data = NULL;
@@ -985,15 +986,15 @@ static bool cam_tfe_bus_match_comp_grp(
 }
 
 static int cam_tfe_bus_acquire_comp_grp(
-	struct cam_tfe_bus_priv             *bus_priv,
-	struct cam_isp_tfe_out_port_info    *out_port_info,
-	void                                *tasklet,
-	uint32_t                             is_dual,
-	uint32_t                             is_master,
-	struct cam_isp_resource_node       **comp_grp,
-	enum cam_tfe_bus_comp_grp_id         comp_grp_id,
-	struct cam_isp_resource_node        *out_rsrc,
-	uint32_t                             source_group)
+	struct cam_tfe_bus_priv                  *bus_priv,
+	struct cam_isp_tfe_out_port_generic_info *out_port_info,
+	void                                     *tasklet,
+	uint32_t                                  is_dual,
+	uint32_t                                  is_master,
+	struct cam_isp_resource_node            **comp_grp,
+	enum cam_tfe_bus_comp_grp_id              comp_grp_id,
+	struct cam_isp_resource_node             *out_rsrc,
+	uint32_t                                  source_group)
 {
 	int rc = 0;
 	struct cam_isp_resource_node      *comp_grp_local = NULL;

+ 25 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -20,6 +20,7 @@
 #include "cam_cpas_api.h"
 #include "cam_compat.h"
 #include "cam_common_util.h"
+#include "cam_tfe_csid_hw_intf.h"
 
 static const char drv_name[] = "tfe";
 
@@ -85,6 +86,9 @@ struct cam_tfe_camif_data {
 	uint32_t                           dual_tfe_sync_sel;
 	uint32_t                           hbi_value;
 	uint32_t                           vbi_value;
+	uint32_t                           qcfa_bin;
+	uint32_t                           bayer_bin;
+	uint32_t                           core_cfg;
 };
 
 struct cam_tfe_rdi_data {
@@ -1887,6 +1891,12 @@ int cam_tfe_top_reserve(void *device_priv,
 				camif_data->sync_mode = acquire_args->sync_mode;
 				camif_data->event_cb = args->event_cb;
 				camif_data->priv = args->priv;
+				camif_data->qcfa_bin =
+					acquire_args->in_port->qcfa_bin;
+				camif_data->bayer_bin =
+					acquire_args->in_port->bayer_bin;
+				camif_data->core_cfg =
+					acquire_args->in_port->core_cfg;
 
 				CAM_DBG(CAM_ISP,
 					"TFE:%d pix_pattern:%d dsp_mode=%d",
@@ -2017,6 +2027,18 @@ static int cam_tfe_camif_resource_start(
 	/* enables the Delay Line CLC in the pixel pipeline */
 	val |= BIT(rsrc_data->reg_data->delay_line_en_shift);
 
+	if (rsrc_data->common_reg->serializer_supported) {
+		val |= rsrc_data->core_cfg &
+			(1 << rsrc_data->reg_data->ai_c_srl_en_shift);
+
+		val |= rsrc_data->core_cfg &
+			(1 << rsrc_data->reg_data->ds16_c_srl_en_shift);
+
+		val |= rsrc_data->core_cfg &
+			(1 << rsrc_data->reg_data->ds4_c_srl_en_shift);
+	}
+
+
 	cam_io_w_mb(val, rsrc_data->mem_base +
 		rsrc_data->common_reg->core_cfg_0);
 
@@ -2043,6 +2065,9 @@ static int cam_tfe_camif_resource_start(
 		epoch0_irq_mask = (rsrc_data->last_line -
 					rsrc_data->first_line);
 
+	if (rsrc_data->bayer_bin || rsrc_data->qcfa_bin)
+		epoch0_irq_mask >>= 1;
+
 	epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg &
 			0xFFFF;
 	computed_epoch_line_cfg = (epoch0_irq_mask << 16) |

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

@@ -107,6 +107,9 @@ struct cam_tfe_top_reg_offset_common {
 	uint32_t diag_min_hbi_error_shift;
 	uint32_t diag_neq_hbi_shift;
 	uint32_t diag_sensor_hbi_mask;
+
+	/* configuration */
+	bool serializer_supported;
 };
 
 struct cam_tfe_camif_reg {
@@ -163,6 +166,10 @@ struct cam_tfe_camif_reg_data {
 	uint32_t     perf_client_sel_shift;
 	uint32_t     perf_window_start_shift;
 	uint32_t     perf_window_end_shift;
+
+	uint32_t     ai_c_srl_en_shift;
+	uint32_t     ds16_c_srl_en_shift;
+	uint32_t     ds4_c_srl_en_shift;
 };
 
 struct cam_tfe_camif_hw_info {

+ 6 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c

@@ -124,13 +124,13 @@ static int cam_top_tpg_ver1_reserve(
 		return -EINVAL;
 	}
 
-	if ((reserv->in_port[0]->vc > 0xF) ||
+	if ((reserv->in_port[0]->vc[0] > 0xF) ||
 		(reserv->in_port[0]->lane_num <= 0 ||
 		reserv->in_port[0]->lane_num > 4) ||
 		(reserv->in_port[0]->pix_pattern > 4) ||
 		(reserv->in_port[0]->lane_type >= 2)) {
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG:%u invalid input %d %d %d %d",
-			tpg_hw->hw_intf->hw_idx, reserv->in_port[0]->vc,
+			tpg_hw->hw_intf->hw_idx, reserv->in_port[0]->vc[0],
 			reserv->in_port[0]->lane_num,
 			reserv->in_port[0]->pix_pattern,
 			reserv->in_port[0]->lane_type);
@@ -145,13 +145,13 @@ static int cam_top_tpg_ver1_reserve(
 	CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx);
 
 	tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
-	tpg_data->vc_num[0] = reserv->in_port[0]->vc;
+	tpg_data->vc_num[0] = reserv->in_port[0]->vc[0];
 	tpg_data->phy_sel = reserv->in_port[0]->lane_type;
 	tpg_data->num_active_lanes = reserv->in_port[0]->lane_num;
 	tpg_data->h_blank_count = reserv->in_port[0]->sensor_hbi;
 	tpg_data->v_blank_count = reserv->in_port[0]->sensor_vbi;
 	tpg_data->pix_pattern = reserv->in_port[0]->pix_pattern;
-	tpg_data->dt_cfg[0].data_type = reserv->in_port[0]->dt;
+	tpg_data->dt_cfg[0].data_type = reserv->in_port[0]->dt[0];
 	tpg_data->dt_cfg[0].frame_height = reserv->in_port[0]->height;
 	if (reserv->in_port[0]->usage_type)
 		tpg_data->dt_cfg[0].frame_width =
@@ -182,7 +182,7 @@ static int cam_top_tpg_ver1_reserve(
 		goto end;
 
 	for (i = 1; i < reserv->num_inport; i++) {
-		if ((tpg_data->vc_num[0] != reserv->in_port[i]->vc) ||
+		if ((tpg_data->vc_num[0] != reserv->in_port[i]->vc[0]) ||
 			(tpg_data->phy_sel != reserv->in_port[i]->lane_type) ||
 			(tpg_data->num_active_lanes !=
 				reserv->in_port[i]->lane_num) ||
@@ -199,7 +199,7 @@ static int cam_top_tpg_ver1_reserve(
 		if (rc)
 			return rc;
 
-		tpg_data->dt_cfg[i].data_type = reserv->in_port[i]->dt;
+		tpg_data->dt_cfg[i].data_type = reserv->in_port[i]->dt[0];
 		tpg_data->dt_cfg[i].frame_height =
 			reserv->in_port[i]->height;
 		tpg_data->dt_cfg[i].frame_width =

+ 2 - 2
drivers/camera_main.c

@@ -58,7 +58,7 @@
 
 #include "cam_top_tpg.h"
 #include "cam_tfe_dev.h"
-#include "cam_tfe_csid530.h"
+#include "cam_tfe_csid.h"
 #include "cam_csid_ppi100.h"
 #include "camera_main.h"
 
@@ -86,7 +86,7 @@ static const struct camera_submodule_component camera_tfe[] = {
 #ifdef CONFIG_SPECTRA_TFE
 	{&cam_csid_ppi100_init_module, &cam_csid_ppi100_exit_module},
 	{&cam_tfe_init_module, &cam_tfe_exit_module},
-	{&cam_tfe_csid530_init_module, &cam_tfe_csid530_exit_module},
+	{&cam_tfe_csid_init_module, &cam_tfe_csid_exit_module},
 #endif
 };
 

+ 2 - 2
drivers/camera_main.h

@@ -25,7 +25,7 @@ extern struct platform_driver isp_driver;
 #ifdef CONFIG_SPECTRA_TFE
 extern struct platform_driver cam_csid_ppi100_driver;
 extern struct platform_driver cam_tfe_driver;
-extern struct platform_driver cam_tfe_csid530_driver;
+extern struct platform_driver cam_tfe_csid_driver;
 #endif
 #ifdef CONFIG_SPECTRA_SENSOR
 extern struct platform_driver cam_res_mgr_driver;
@@ -87,7 +87,7 @@ static struct platform_driver *const cam_component_drivers[] = {
 #ifdef CONFIG_SPECTRA_TFE
 	&cam_csid_ppi100_driver,
 	&cam_tfe_driver,
-	&cam_tfe_csid530_driver,
+	&cam_tfe_csid_driver,
 #endif
 #ifdef CONFIG_SPECTRA_ISP
 	&cam_top_tpg_driver,

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

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __UAPI_CAM_TFE_H__
@@ -88,6 +88,12 @@
 #define CAM_ISP_TFE_WM_LINE_BASED_MODE     1
 #define CAM_ISP_TFE_WM_INDEX_BASED_MODE    2
 
+#define CAM_ISP_TFE_VC_DT_CFG              2
+
+/* Feature Flag indicators */
+#define CAM_ISP_TFE_FLAG_QCFA_BIN                        BIT(0)
+#define CAM_ISP_TFE_FLAG_BAYER_BIN                       BIT(1)
+
 /* Query devices */
 /**
  * struct cam_isp_tfe_dev_cap_info - A cap info for particular hw type
@@ -220,6 +226,92 @@ struct cam_isp_tfe_in_port_info {
 	struct cam_isp_tfe_out_port_info data[1];
 };
 
+/**
+ * struct cam_isp_tfe_in_port_info_v2 - An input port resource info
+ *
+ * @res_id:                     input resource id CAM_ISP_TFE_IN_RES_XXX
+ * @lane_type:                  lane type: c-phy or d-phy.
+ * @lane_num:                   active lane number
+ * @lane_cfg:                   lane configurations: 4 bits per lane
+ * @vc:                         input virtual channel number
+ * @dt:                         input data type number
+ * @format:                     input format
+ * @pix_pattern:                pixel pattern
+ * @usage_type:                 whether dual tfe is required
+ * @left_start:                 left input start offset in pixels
+ * @left_end:                   left input stop offset in pixels
+ * @left_width:                 left input width in pixels
+ * @right_start:                right input start offset in pixels.
+ *                              Only for Dual TFE
+ * @right_end:                  right input stop offset in
+ *                              pixels. Only for Dual TFE
+ * @right_width:                right input width in pixels.
+ *                              Only for dual TFE
+ * @line_start:                 top of the line number
+ * @line_stop:                  bottome of the line number
+ * @height:                     input height in lines
+ * @batch_size:                 batch size for HFR mode
+ * @dsp_mode:                   DSP stream mode(Defines as
+ *                              CAM_ISP_TFE_DSP_MODE_*)
+ * @sensor_width:               sensor width
+ * @sensor_height:              sensor height
+ * @sensor_hbi:                 sensor HBI value
+ * @sensor_vbi:                 sensor VBI value
+ * @sensor_fps:                 sensor fps
+ * @init_frame_drop             init frame drop value.
+ * @num_out_res:                number of the output resource associated
+ * @feature_flag:               Feature flags for indicating QCFA, Bayer bin
+ * @core_cfg:                   Core configuration
+ * @reserve_field_1:            Reserve field 1
+ * @reserve_field_2:            Reserve field 2
+ * @reserve_field_3:            Reserve field 3
+ * @reserve_field_4:            Reserve field 4
+ * @reserve_field_5:            Reserve field 5
+ * @reserve_field_6:            Reserve filed 6
+ * @data:                       payload that contains the output resources,
+ *                              array of cam_isp_tfe_out_port_info data
+ *
+ */
+struct cam_isp_tfe_in_port_info_v2 {
+	__u32                            res_id;
+	__u32                            lane_type;
+	__u32                            lane_num;
+	__u32                            lane_cfg;
+	__u32                            vc[CAM_ISP_TFE_VC_DT_CFG];
+	__u32                            dt[CAM_ISP_TFE_VC_DT_CFG];
+	__u32                            num_valid_vc_dt;
+	__u32                            format;
+	__u32                            pix_pattern;
+	__u32                            usage_type;
+	__u32                            left_start;
+	__u32                            left_end;
+	__u32                            left_width;
+	__u32                            right_start;
+	__u32                            right_end;
+	__u32                            right_width;
+	__u32                            line_start;
+	__u32                            line_end;
+	__u32                            height;
+	__u32                            batch_size;
+	__u32                            dsp_mode;
+	__u32                            sensor_width;
+	__u32                            sensor_height;
+	__u32                            sensor_hbi;
+	__u32                            sensor_vbi;
+	__u32                            sensor_fps;
+	__u32                            init_frame_drop;
+	__u32                            num_out_res;
+	__u32                            feature_flag;
+	__u32                            core_cfg;
+	__u32                            reserve_field_1;
+	__u32                            reserve_field_2;
+	__u32                            reserve_field_3;
+	__u32                            reserve_field_4;
+	__u32                            reserve_field_5;
+	__u32                            reserve_field_6;
+	struct cam_isp_tfe_out_port_info data[1];
+};
+
 /**
  * struct cam_isp_tfe_resource - A resource bundle
  *