فهرست منبع

msm: camera: sensor: Add changes for XCFA in TPG

Add generic changes to support RGBIR, 3x3 and 4x4
XCFA from TPG XML.

CRs-Fixed: 3175994
External Impact: No
Change-Id: I129e20eb5db2bf2f168202f4854de62926eb613b
Signed-off-by: Rishab Garg <[email protected]>
Rishab Garg 3 سال پیش
والد
کامیت
9cbc7cd024

+ 34 - 6
drivers/cam_sensor_module/cam_tpg/cam_tpg_core.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_tpg_core.h"
@@ -388,15 +389,31 @@ static int cam_tpg_validate_cmd_descriptor(
 		break;
 	}
 	case TPG_CMD_TYPE_STREAM_CONFIG: {
-		if (cmd_header->size != sizeof(struct tpg_stream_config_t)) {
+		if (cmd_header->cmd_version == 3 &&
+			cmd_header->size != sizeof(struct tpg_stream_config_v3_t)) {
 			CAM_ERR(CAM_TPG, "Got invalid stream config command recv: %d exp: %d",
-					cmd_header->size,
-					sizeof(struct tpg_stream_config_t));
+				cmd_header->size,
+				sizeof(struct tpg_stream_config_v3_t));
+
+			rc = -EINVAL;
+			goto end;
+		} else if (cmd_header->cmd_version == 2 &&
+			cmd_header->size != sizeof(struct tpg_stream_config_t)) {
+			CAM_ERR(CAM_TPG, "Got invalid stream config cmd recv: %d exp: %d",
+				cmd_header->size,
+				sizeof(struct tpg_stream_config_t));
+
+			rc = -EINVAL;
+			goto end;
+		} else if (cmd_header->cmd_version == 1 &&
+			cmd_header->size != sizeof(struct tpg_old_stream_config_t)) {
+			CAM_ERR(CAM_TPG, "Got invalid stream config cmd recv: %d exp: %d",
+				cmd_header->size,
+				sizeof(struct tpg_old_stream_config_t));
 
 			rc = -EINVAL;
 			goto end;
 		}
-		CAM_INFO(CAM_TPG, "Got stream config cmd");
 		*cmd_type = TPG_CMD_TYPE_STREAM_CONFIG;
 		break;
 	}
@@ -437,6 +454,7 @@ static int cam_tpg_cmd_buf_parse(
 	for (i = 0; i < packet->num_cmd_buf; i++) {
 		uint32_t cmd_type = TPG_CMD_TYPE_INVALID;
 		uintptr_t cmd_addr;
+		struct tpg_command_header_t *cmd_header = NULL;
 
 		cmd_desc = (struct cam_cmd_buf_desc *)
 			((uint32_t *)&packet->payload +
@@ -448,14 +466,24 @@ static int cam_tpg_cmd_buf_parse(
 		if (rc < 0)
 			goto end;
 
+		cmd_header = (struct tpg_command_header_t *)cmd_addr;
+
 		switch (cmd_type) {
 		case TPG_CMD_TYPE_GLOBAL_CONFIG:
 			rc = tpg_hw_copy_global_config(&tpg_dev->tpg_hw,
 				(struct tpg_global_config_t *)cmd_addr);
 			break;
 		case TPG_CMD_TYPE_STREAM_CONFIG: {
-			rc = tpg_hw_add_stream(&tpg_dev->tpg_hw,
-				(struct tpg_stream_config_t *)cmd_addr);
+			if (cmd_header->cmd_version == 3) {
+				rc = tpg_hw_add_stream_v3(&tpg_dev->tpg_hw,
+					(struct tpg_stream_config_v3_t *)cmd_addr);
+				CAM_DBG(CAM_TPG, "Stream config v3");
+			} else if (cmd_header->cmd_version == 1 ||
+				cmd_header->cmd_version == 2) {
+				rc = tpg_hw_add_stream(&tpg_dev->tpg_hw,
+					(struct tpg_stream_config_t *)cmd_addr);
+				CAM_DBG(CAM_TPG, "Stream config");
+			}
 			break;
 		}
 		case TPG_CMD_TYPE_ILLUMINATION_CONFIG:

+ 330 - 26
drivers/cam_sensor_module/cam_tpg/tpg_hw/tpg_hw.c

@@ -228,6 +228,75 @@ int dump_stream_configs(int hw_idx,
 	return 0;
 }
 
+int dump_stream_configs_v3(int hw_idx,
+		int stream_idx,
+		struct tpg_stream_config_v3_t *stream)
+{
+#ifdef __TPG_DEBUG_DUMP__
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] pattern_type    : %s",
+			hw_idx,
+			stream_idx,
+			tpg_pattern_type_strings[stream->pattern_type]);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] cb_mode         : %s",
+			hw_idx,
+			stream_idx,
+			tpg_color_bar_mode_strings[stream->cb_mode]);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] frame_count     : %d",
+			hw_idx,
+			stream_idx,
+			stream->frame_count);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] stream_type     : %s",
+			hw_idx,
+			stream_idx,
+			tpg_stream_type_strings[stream->stream_type]);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] left            : %d",
+			hw_idx,
+			stream_idx,
+			stream->stream_dimension.left);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] top             : %d",
+			hw_idx,
+			stream_idx,
+			stream->stream_dimension.top);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] width           : %d",
+			hw_idx,
+			stream_idx,
+			stream->stream_dimension.width);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] height          : %d",
+			hw_idx,
+			stream_idx,
+			stream->stream_dimension.height);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] pixel_depth     : %d",
+			hw_idx,
+			stream_idx,
+			stream->pixel_depth);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] cfa_arrangement : %d",
+			hw_idx,
+			stream_idx,
+			stream->cfa_arrangement);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] output_format   : %s",
+			hw_idx,
+			stream_idx,
+		tpg_image_format_type_strings[stream->output_format]);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] vc              : 0x%x",
+			hw_idx,
+			stream_idx,
+			stream->vc);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] dt              : 0x%x",
+			hw_idx,
+			stream_idx,
+			stream->dt);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] hbi             : %d",
+			hw_idx,
+			stream_idx,
+			stream->hbi);
+	CAM_DBG(CAM_TPG, "TPG[%d][%d] vbi             : %d",
+			hw_idx,
+			stream_idx,
+			stream->vbi);
+#endif
+	return 0;
+}
+
 
 static int tpg_hw_soc_disable(struct tpg_hw *hw)
 {
@@ -239,13 +308,15 @@ static int tpg_hw_soc_disable(struct tpg_hw *hw)
 	}
 
 	rc = cam_soc_util_disable_platform_resource(hw->soc_info, true, false);
-	if (rc)
+	if (rc) {
 		CAM_ERR(CAM_TPG, "TPG[%d] Disable platform failed %d",
-				hw->hw_idx, rc);
-
+			hw->hw_idx, rc);
+		return rc;
+	}
 	if ((rc = cam_cpas_stop(hw->cpas_handle))) {
 		CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed",
-				hw->hw_idx);
+			hw->hw_idx);
+		return rc;
 	} else {
 		hw->state = TPG_HW_STATE_HW_DISABLED;
 	}
@@ -280,7 +351,7 @@ static int tpg_hw_soc_enable(
 	rc = cam_cpas_start(hw->cpas_handle, &ahb_vote, &axi_vote);
 	if (rc) {
 		CAM_ERR(CAM_TPG, "TPG[%d] CPAS start failed",
-				hw->hw_idx);
+			hw->hw_idx);
 		rc = -EFAULT;
 		goto end;
 	}
@@ -289,7 +360,7 @@ static int tpg_hw_soc_enable(
 		clk_level, false);
 	if (rc) {
 		CAM_ERR(CAM_TPG, "TPG[%d] enable platform failed",
-				hw->hw_idx);
+			hw->hw_idx);
 		goto stop_cpas;
 	}
 	hw->state = TPG_HW_STATE_HW_ENABLED;
@@ -354,12 +425,67 @@ static int tpg_hw_start_default_new(struct tpg_hw *hw)
 	return 0;
 }
 
+static int tpg_hw_start_default_new_v3(struct tpg_hw *hw)
+{
+	int i = 0;
+	uint32_t stream_idx = 0;
+	int num_vcs = 0;
+	struct global_config_args globalargs = {0};
+
+	if (!hw || !hw->hw_info ||
+		!hw->hw_info->ops || !hw->hw_info->ops->process_cmd) {
+		CAM_ERR(CAM_TPG, "Invalid argument");
+		return -EINVAL;
+	}
+
+	dump_global_configs(hw->hw_idx, &hw->global_config);
+	for (i = 0; i < hw->hw_info->max_vc_channels; i++) {
+		int dt_slot = 0;
+		struct vc_config_args_v3 vc_config = {0};
+		struct list_head *pos = NULL, *pos_next = NULL;
+		struct tpg_hw_stream_v3 *entry = NULL, *vc_stream_entry = NULL;
+
+		if (hw->vc_slots[i].vc == -1)
+			break;
+		num_vcs++;
+		vc_config.vc_slot = i;
+		vc_config.num_dts = hw->vc_slots[i].stream_count;
+		vc_stream_entry = list_first_entry(&hw->vc_slots[i].head,
+			struct tpg_hw_stream_v3, list);
+		vc_config.stream  = &vc_stream_entry->stream;
+		hw->hw_info->ops->process_cmd(hw,
+				TPG_CONFIG_VC, &vc_config);
+
+		list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
+			struct dt_config_args_v3 dt_config = {0};
+
+			entry = list_entry(pos, struct tpg_hw_stream_v3, list);
+			dump_stream_configs_v3(hw->hw_idx,
+				stream_idx++,
+				&entry->stream);
+			dt_config.vc_slot = i;
+			dt_config.dt_slot = dt_slot++;
+			dt_config.stream  = &entry->stream;
+			hw->hw_info->ops->process_cmd(hw, TPG_CONFIG_DT, &dt_config);
+		}
+	}
+
+	globalargs.num_vcs      = num_vcs;
+	globalargs.globalconfig = &hw->global_config;
+	hw->hw_info->ops->process_cmd(hw,
+		TPG_CONFIG_CTRL, &globalargs);
+
+	return 0;
+}
+
+
 int tpg_hw_dump_status(struct tpg_hw *hw)
 {
 	if (!hw || !hw->hw_info || !hw->hw_info->ops)
 		return -EINVAL;
 	switch (hw->hw_info->version) {
 	case TPG_HW_VERSION_1_3:
+	case TPG_HW_VERSION_1_3_1:
 		if (hw->hw_info->ops->dump_status)
 			hw->hw_info->ops->dump_status(hw, NULL);
 		break;
@@ -385,14 +511,18 @@ int tpg_hw_start(struct tpg_hw *hw)
 		break;
 	case TPG_HW_VERSION_1_2:
 	case TPG_HW_VERSION_1_3:
+	case TPG_HW_VERSION_1_3_1:
 		if (hw->hw_info->ops->start)
 			hw->hw_info->ops->start(hw, NULL);
-		tpg_hw_start_default_new(hw);
+		if (hw->stream_version == 1)
+			tpg_hw_start_default_new(hw);
+		else if (hw->stream_version == 3)
+			tpg_hw_start_default_new_v3(hw);
 		cam_tpg_mem_dmp(hw->soc_info);
 		break;
 	default:
 		CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
-				hw->hw_idx);
+			hw->hw_idx);
 		rc = -EINVAL;
 		break;
 	}
@@ -412,13 +542,25 @@ int tpg_hw_stop(struct tpg_hw *hw)
 	case TPG_HW_VERSION_1_1:
 	case TPG_HW_VERSION_1_2:
 	case TPG_HW_VERSION_1_3:
-		if (hw->hw_info->ops->stop)
+	case TPG_HW_VERSION_1_3_1:
+		if (hw->hw_info->ops->stop) {
 			rc = hw->hw_info->ops->stop(hw, NULL);
+			if (rc) {
+				CAM_ERR(CAM_TPG, "TPG[%d] hw stop failed %d",
+					hw->hw_idx, rc);
+				return rc;
+			}
+		}
 		rc = tpg_hw_soc_disable(hw);
+		if (rc) {
+			CAM_ERR(CAM_TPG, "TPG[%d] hw soc disable failed %d",
+				hw->hw_idx, rc);
+			return rc;
+		}
 		break;
 	default:
 		CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
-				hw->hw_idx);
+			hw->hw_idx);
 		rc = -EINVAL;
 		break;
 	}
@@ -441,11 +583,12 @@ int tpg_hw_acquire(struct tpg_hw *hw,
 	case TPG_HW_VERSION_1_1:
 	case TPG_HW_VERSION_1_2:
 	case TPG_HW_VERSION_1_3:
+	case TPG_HW_VERSION_1_3_1:
 		// Start Cpas and enable required clocks
 		break;
 	default:
 		CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
-				hw->hw_idx);
+			hw->hw_idx);
 		rc = -EINVAL;
 		break;
 	}
@@ -465,10 +608,11 @@ int tpg_hw_release(struct tpg_hw *hw)
 	case TPG_HW_VERSION_1_1:
 	case TPG_HW_VERSION_1_2:
 	case TPG_HW_VERSION_1_3:
+	case TPG_HW_VERSION_1_3_1:
 		break;
 	default:
 		CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
-				hw->hw_idx);
+			hw->hw_idx);
 		rc = -EINVAL;
 		break;
 	}
@@ -526,14 +670,26 @@ static int tpg_hw_configure_init_settings(
 	case TPG_HW_VERSION_1_1:
 	case TPG_HW_VERSION_1_2:
 	case TPG_HW_VERSION_1_3:
+	case TPG_HW_VERSION_1_3_1:
 		clk_level = get_tpg_clk_level(hw);
 		rc = tpg_hw_soc_enable(hw, clk_level);
-		if (hw->hw_info->ops->init)
+		if (rc) {
+			CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
+				hw->hw_idx, rc);
+			return rc;
+		}
+		if (hw->hw_info->ops->init) {
 			rc = hw->hw_info->ops->init(hw, settings);
+			if (rc) {
+				CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
+					hw->hw_idx, rc);
+				return rc;
+			}
+		}
 		break;
 	default:
 		CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
-				hw->hw_idx);
+			hw->hw_idx);
 		rc = -EINVAL;
 		break;
 	}
@@ -541,6 +697,47 @@ static int tpg_hw_configure_init_settings(
 	return rc;
 }
 
+static int tpg_hw_configure_init_settings_v3(
+		struct tpg_hw *hw,
+		struct tpg_hw_initsettings_v3 *settings)
+{
+	int rc = 0;
+
+	if (!hw || !hw->hw_info || !hw->hw_info->ops)
+		return -EINVAL;
+	mutex_lock(&hw->mutex);
+	switch (hw->hw_info->version) {
+	case TPG_HW_VERSION_1_0:
+	case TPG_HW_VERSION_1_1:
+	case TPG_HW_VERSION_1_2:
+	case TPG_HW_VERSION_1_3:
+	case TPG_HW_VERSION_1_3_1:
+		rc = tpg_hw_soc_enable(hw, CAM_SVS_VOTE);
+		if (rc) {
+			CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
+				hw->hw_idx, rc);
+			return rc;
+		}
+		if (hw->hw_info->ops->init) {
+			rc = hw->hw_info->ops->init(hw, settings);
+			if (rc) {
+				CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
+					hw->hw_idx, rc);
+				return rc;
+			}
+		}
+		break;
+	default:
+		CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
+			hw->hw_idx);
+		rc = -EINVAL;
+		break;
+	}
+	mutex_unlock(&hw->mutex);
+	return rc;
+}
+
+
 int tpg_hw_config(
 	struct tpg_hw *hw,
 	enum tpg_hw_cmd_t config_cmd,
@@ -553,12 +750,17 @@ int tpg_hw_config(
 	switch (config_cmd) {
 	case TPG_HW_CMD_INIT_CONFIG:
 		//validate_stream_list(hw);
-		tpg_hw_configure_init_settings(hw,
-			(struct tpg_hw_initsettings *)config_args);
+		if (hw->stream_version == 1) {
+			tpg_hw_configure_init_settings(hw,
+				(struct tpg_hw_initsettings *)config_args);
+		} else if (hw->stream_version == 3) {
+			tpg_hw_configure_init_settings_v3(hw,
+				(struct tpg_hw_initsettings_v3 *)config_args);
+		}
 		break;
 	default:
 		CAM_ERR(CAM_TPG, "TPG[%d] Unsupported hw config command",
-				hw->hw_idx);
+			hw->hw_idx);
 		rc = -EINVAL;
 		break;
 	}
@@ -569,6 +771,7 @@ int tpg_hw_free_streams(struct tpg_hw *hw)
 {
 	struct list_head *pos = NULL, *pos_next = NULL;
 	struct tpg_hw_stream *entry;
+	struct tpg_hw_stream_v3 *entry_v3;
 	int i = 0;
 
 	if (!hw)
@@ -583,10 +786,19 @@ int tpg_hw_free_streams(struct tpg_hw *hw)
 		hw->vc_slots[i].slot_id      =  i;
 		hw->vc_slots[i].vc           = -1;
 		hw->vc_slots[i].stream_count =  0;
-		list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
-			entry = list_entry(pos, struct tpg_hw_stream, list);
-			list_del(pos);
-			kfree(entry);
+
+		if (hw->stream_version == 1) {
+			list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
+				entry = list_entry(pos, struct tpg_hw_stream, list);
+				list_del(pos);
+				kfree(entry);
+			}
+		} else if (hw->stream_version == 3) {
+			list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
+				entry_v3 = list_entry(pos, struct tpg_hw_stream_v3, list);
+				list_del(pos);
+				kfree(entry_v3);
+			}
 		}
 		INIT_LIST_HEAD(&(hw->vc_slots[i].head));
 	}
@@ -671,6 +883,65 @@ static int assign_vc_slot(
 	return rc;
 }
 
+static int assign_vc_slot_v3(
+	struct tpg_hw *hw,
+	int  vc,
+	struct tpg_hw_stream_v3 *stream
+	)
+{
+	int rc = -EINVAL, i = 0, slot_matched = 0;
+
+	if (!hw || !stream)
+		return -EINVAL;
+
+	for (i = 0; i < hw->hw_info->max_vc_channels; i++) {
+		/* Found a matching slot */
+		if (hw->vc_slots[i].vc == vc) {
+			slot_matched = 1;
+			if (hw->vc_slots[i].stream_count
+					< hw->hw_info->max_dt_channels_per_vc) {
+				list_add_tail(&stream->list, &hw->vc_slots[i].head);
+				hw->vc_slots[i].stream_count++;
+				hw->vc_slots[i].vc = vc;
+				rc = 0;
+				CAM_DBG(CAM_TPG, "vc[%d]dt[%d]=>slot[%d]",
+					vc,
+					stream->stream.dt,
+					i);
+			} else {
+
+				/**
+				 * already slot was assigned for this vc
+				 * however this slot have been filled with
+				 * full streams
+				 */
+				rc = -EINVAL;
+				CAM_ERR(CAM_TPG, "vc[%d]dt[%d]=>slot[%d] is overlfown",
+					vc, stream->stream.dt, i);
+			}
+			break;
+		}
+
+		/**
+		 * none of the above slots matched, and now found an empty slot
+		 * so assigning stream to that slot
+		 */
+		if (hw->vc_slots[i].vc == -1) {
+			list_add_tail(&stream->list, &hw->vc_slots[i].head);
+			hw->vc_slots[i].stream_count++;
+			hw->vc_slots[i].vc = vc;
+			hw->vc_count++;
+			rc = 0;
+			CAM_DBG(CAM_TPG, "vc[%d]dt[%d]=>slot[%d]", vc, stream->stream.dt, i);
+			break;
+		}
+	}
+	if ((slot_matched == 0) && (rc != 0))
+		CAM_ERR(CAM_TPG, "No slot matched");
+
+	return rc;
+}
+
 int tpg_hw_reset(struct tpg_hw *hw)
 {
 	int rc = 0;
@@ -686,13 +957,15 @@ int tpg_hw_reset(struct tpg_hw *hw)
 	mutex_lock(&hw->mutex);
 	if (hw->state != TPG_HW_STATE_HW_DISABLED) {
 		rc = cam_soc_util_disable_platform_resource(hw->soc_info, true, false);
-		if (rc)
+		if (rc) {
 			CAM_ERR(CAM_TPG, "TPG[%d] Disable platform failed %d", hw->hw_idx, rc);
-
+			return rc;
+		}
 		rc = cam_cpas_stop(hw->cpas_handle);
-		if (rc)
+		if (rc) {
 			CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed", hw->hw_idx);
-
+			return rc;
+		}
 		hw->state = TPG_HW_STATE_HW_DISABLED;
 	}
 	mutex_unlock(&hw->mutex);
@@ -711,11 +984,12 @@ int tpg_hw_add_stream(
 		return -EINVAL;
 	}
 
+	hw->stream_version = 1;
 	mutex_lock(&hw->mutex);
 	stream = kzalloc(sizeof(struct tpg_hw_stream), GFP_KERNEL);
 	if (!stream) {
 		CAM_ERR(CAM_TPG, "TPG[%d] stream allocation failed",
-				hw->hw_idx);
+			hw->hw_idx);
 		mutex_unlock(&hw->mutex);
 		return -ENOMEM;
 	}
@@ -727,3 +1001,33 @@ int tpg_hw_add_stream(
 	mutex_unlock(&hw->mutex);
 	return rc;
 }
+int tpg_hw_add_stream_v3(
+	struct tpg_hw *hw,
+	struct tpg_stream_config_v3_t *cmd)
+{
+	int rc = 0;
+	struct tpg_hw_stream_v3 *stream = NULL;
+
+	if (!hw || !cmd) {
+		CAM_ERR(CAM_TPG, "Invalid params");
+		return -EINVAL;
+	}
+
+	hw->stream_version = 3;
+	mutex_lock(&hw->mutex);
+	stream = kzalloc(sizeof(struct tpg_hw_stream_v3), GFP_KERNEL);
+	if (!stream) {
+		CAM_ERR(CAM_TPG, "TPG[%d] stream allocation failed",
+			hw->hw_idx);
+		mutex_unlock(&hw->mutex);
+		return -ENOMEM;
+	}
+	memcpy(&stream->stream,
+		cmd,
+		sizeof(struct tpg_stream_config_v3_t));
+
+	rc = assign_vc_slot_v3(hw, stream->stream.vc, stream);
+	mutex_unlock(&hw->mutex);
+	return rc;
+}
+

+ 91 - 12
drivers/cam_sensor_module/cam_tpg/tpg_hw/tpg_hw.h

@@ -12,10 +12,11 @@
 #include "cam_soc_util.h"
 #include <cam_cpas_api.h>
 #include <media/cam_sensor.h>
-#define TPG_HW_VERSION_1_0 0x10000000
-#define TPG_HW_VERSION_1_1 0x10000001
-#define TPG_HW_VERSION_1_2 0x10000002
-#define TPG_HW_VERSION_1_3 0x10000003
+#define TPG_HW_VERSION_1_0   0x10000000
+#define TPG_HW_VERSION_1_1   0x10000001
+#define TPG_HW_VERSION_1_2   0x10000002
+#define TPG_HW_VERSION_1_3   0x10000003
+#define TPG_HW_VERSION_1_3_1 0x10000004
 
 
 struct tpg_hw;
@@ -109,20 +110,34 @@ struct tpg_hw_stream {
 	struct list_head list;
 };
 
+/**
+ * tpg_hw_stream_v3 : tpg hw stream version 2
+ *
+ * @stream : tpg stream version 2
+ * @list   : entry to tpg stream list
+ */
+struct tpg_hw_stream_v3 {
+	struct tpg_stream_config_v3_t stream;
+	struct list_head list;
+};
+
+
 /**
  * tpg_hw : tpg hw
  *
- * @hw_idx        : hw id
- * @state         : tpg hw state
- * @cpas_handle   : handle to cpas
- * @hw_info       : tp hw info
- * @soc_info      : soc info
- * @mutex         : lock
- * @stream_list   : list of tpg stream
- * @global_config : global configuration
+ * @hw_idx         : hw id
+ * @stream_version : stream version
+ * @state          : tpg hw state
+ * @cpas_handle    : handle to cpas
+ * @hw_info        : tp hw info
+ * @soc_info       : soc info
+ * @mutex          : lock
+ * @stream_list    : list of tpg stream
+ * @global_config  : global configuration
  */
 struct tpg_hw {
 	uint32_t                   hw_idx;
+	uint32_t                   stream_version;
 	uint32_t                   state;
 	uint32_t                   cpas_handle;
 	uint32_t                   vc_count;
@@ -189,6 +204,33 @@ struct dt_config_args {
 	struct tpg_stream_config_t *stream;
 };
 
+/**
+ * @vc_config_args_v3 : arguments for vc config process cmd version 2
+ *
+ * @vc_slot : slot to configure this vc
+ * @num_dts : number of dts in this vc
+ * @stream  : output stream version 2
+ */
+struct vc_config_args_v3 {
+	uint32_t vc_slot;
+	uint32_t num_dts;
+	struct tpg_stream_config_v3_t *stream;
+};
+
+/**
+ * dt_config_args_v3 : arguments for dt config process cmd version 2
+ *
+ * @vc_slot  : vc slot to configure this dt
+ * @dt_slot  : dt slot to configure this dt
+ * @stream   : stream packet to configure for this dt version 2
+ */
+struct dt_config_args_v3 {
+	uint32_t vc_slot;
+	uint32_t dt_slot;
+	struct tpg_stream_config_v3_t *stream;
+};
+
+
 /**
  * global_config_args : tpg global config args
  *
@@ -213,6 +255,20 @@ struct tpg_hw_initsettings {
 	uint32_t num_streams;
 };
 
+/**
+ * tpg_hw_initsettings_v3 : initial configurations version 2
+ *
+ * @global_config : global configuration
+ * @streamconfigs : array of stream configurations version 2
+ * @num_streams   : number of streams in strea config array
+ */
+struct tpg_hw_initsettings_v3 {
+	struct tpg_global_config_t globalconfig;
+	struct tpg_stream_config_v3_t *streamconfigs;
+	uint32_t num_streams;
+};
+
+
 /**
  * @brief dump the tpg memory info
  *
@@ -243,6 +299,18 @@ int dump_global_configs(int idx, struct tpg_global_config_t *global);
  */
 int dump_stream_configs(int hw_idx, int stream_idx, struct tpg_stream_config_t *stream);
 
+/**
+ * @brief : dump stream config command version 2
+ *
+ * @param hw_idx: hw index
+ * @param stream_idx: stream index
+ * @param stream: stream config command version 2
+ *
+ * @return : 0 on success
+ */
+int dump_stream_configs_v3(int hw_idx, int stream_idx, struct tpg_stream_config_v3_t *stream);
+
+
 /**
  * @brief : dump any hw status registers
  *
@@ -327,6 +395,17 @@ int tpg_hw_reset(struct tpg_hw *hw);
  */
 int tpg_hw_add_stream(struct tpg_hw *hw, struct tpg_stream_config_t *cmd);
 
+/**
+ * @brief : tp hw add stream version 2
+ *
+ * @param hw: tpg hw instance
+ * @param cmd: tpg hw command version 2
+ *
+ * @return : 0 on success
+ */
+int tpg_hw_add_stream_v3(struct tpg_hw *hw, struct tpg_stream_config_v3_t *cmd);
+
+
 /**
  * @brief : copy global config command
  *

+ 301 - 29
drivers/cam_sensor_module/cam_tpg/tpg_hw/tpg_hw_v_1_3/tpg_hw_v_1_3.c

@@ -15,10 +15,19 @@ enum tpg_hw_v_1_3_encode_fomat_t {
 };
 
 
-#define  FRAME_INTERLEAVE  0x0
-#define  LINE_INTERLEAVE   0x1
-#define  SHDR_INTERLEAVE   0x2
-#define  SPARSE_PD_INTERLEAVE 0x3
+#define  FRAME_INTERLEAVE           0x0
+#define  LINE_INTERLEAVE            0x1
+#define  SHDR_INTERLEAVE            0x2
+#define  SPARSE_PD_INTERLEAVE       0x3
+#define  CFA_PATTERN_ROW_WIDTH      8
+#define  CFA_PATTERN_BITS_PER_INDEX 2
+#define  Invalid 0x0
+#define  Red     0x0
+#define  Green   0x1
+#define  Blue    0x2
+#define  IR      0x3
+#define  Mono    0x3
+
 static int get_tpg_vc_dt_pattern_id(
 		enum tpg_interleaving_format_t vc_dt_pattern)
 {
@@ -82,7 +91,6 @@ static int configure_global_configs(
 		(1 << tpg_reg->tpg_en_shift_val);
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
 	CAM_DBG(CAM_TPG, "tpg[%d] tpg_ctrl=0x%x", hw->hw_idx, val);
-
 	return 0;
 }
 
@@ -129,6 +137,149 @@ static int get_tpg_payload_mode(enum tpg_pattern_t pattern)
 	return COLOR_BARS;
 }
 
+static int get_pixel_coordinate(
+	int cfa_pattern_start_index,
+	int cfa_pattern_end_index,
+	uint32_t *val,
+	struct tpg_stream_config_v3_t *configs)
+{
+	uint32_t shift = 0;
+	int idx = 0;
+	int i = 0;
+	int j = 0;
+	*val = 0;
+	for (i = cfa_pattern_start_index; i < cfa_pattern_end_index; i++) {
+		for (j = 0; j < configs->cfa_info.pattern_width; j++) {
+			shift = ((i * CFA_PATTERN_ROW_WIDTH) + j) *
+				CFA_PATTERN_BITS_PER_INDEX;
+			idx = i * configs->cfa_info.pattern_height + j;
+			*val |= (configs->cfa_info.pixel_coordinate[idx].pixel_type) << shift;
+		}
+	}
+	return 0;
+}
+
+static int configure_xcfa_array_v3(
+	struct tpg_hw *hw,
+	struct tpg_stream_config_v3_t *configs)
+{
+	struct cam_hw_soc_info *soc_info = NULL;
+	struct cam_tpg_ver_1_3_reg_offset *tpg_reg = NULL;
+	uint32_t val = 0;
+
+	if (!hw || !hw->hw_info || !hw->hw_info->hw_data) {
+		CAM_ERR(CAM_TPG, "invalid params");
+		return -EINVAL;
+	}
+	tpg_reg  = hw->hw_info->hw_data;
+
+	soc_info = hw->soc_info;
+
+	switch (configs->xcfa_type) {
+	case XCFA_TYPE_RGBIR:
+		get_pixel_coordinate(0, 2, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
+		get_pixel_coordinate(2, configs->cfa_info.pattern_height, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
+		break;
+	case XCFA_TYPE_QUADCFA:
+		get_pixel_coordinate(0, 2, &val, configs);
+		CAM_DBG(CAM_TPG, "val = 0x%x", val);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
+		get_pixel_coordinate(2, configs->cfa_info.pattern_height, &val, configs);
+		CAM_DBG(CAM_TPG, "val = 0x%x", val);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
+		break;
+	case XCFA_TYPE_THREEXTHREECFA:
+		get_pixel_coordinate(0, 2, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
+		get_pixel_coordinate(2, 4, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
+		get_pixel_coordinate(4, configs->cfa_info.pattern_height, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color2);
+		break;
+	case XCFA_TYPE_FOURXFOURCFA:
+		get_pixel_coordinate(0, 2, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
+		get_pixel_coordinate(2, 4, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
+		get_pixel_coordinate(4, 6, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color2);
+		get_pixel_coordinate(6, configs->cfa_info.pattern_height, &val, configs);
+		cam_io_w_mb(val,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color3);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int configure_dt_v3(
+	struct tpg_hw *hw,
+	uint32_t       vc_slot,
+	uint32_t       dt_slot,
+	struct tpg_stream_config_v3_t *stream)
+{
+	uint32_t val;
+	struct cam_hw_soc_info *soc_info = NULL;
+	struct cam_tpg_ver_1_3_reg_offset *tpg_reg = NULL;
+
+	if (!hw || !hw->hw_info || !hw->hw_info->hw_data) {
+		CAM_ERR(CAM_TPG, "invalid params");
+		return -EINVAL;
+	}
+
+	tpg_reg  = hw->hw_info->hw_data;
+
+	soc_info = hw->soc_info;
+
+	CAM_DBG(CAM_TPG, "TPG[%d] slot(%d,%d) <= dt:%d",
+			hw->hw_idx,
+			vc_slot,
+			dt_slot,
+			stream->dt);
+
+	val = (((stream->stream_dimension.width & 0xFFFF) << 16) |
+			(stream->stream_dimension.height & 0xFFFF));
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc0_dt_0_cfg_0 +
+			(0x60 * vc_slot) + (dt_slot * 0x0c));
+	CAM_DBG(CAM_TPG, "TPG[%d] vc%d_dt%d_cfg_0=0x%x",
+			hw->hw_idx,
+			vc_slot, dt_slot, val);
+
+	cam_io_w_mb(stream->dt,
+			soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc0_dt_0_cfg_1 +
+			(0x60 * vc_slot) + (dt_slot * 0x0c));
+	CAM_DBG(CAM_TPG, "TPG[%d] vc%d_dt%d_cfg_1=0x%x",
+			hw->hw_idx,
+			vc_slot, dt_slot, stream->dt);
+
+	val = ((get_tpg_encode_format(stream->pixel_depth) & 0xF) <<
+			tpg_reg->tpg_dt_encode_format_shift) |
+			get_tpg_payload_mode(stream->pattern_type);
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc0_dt_0_cfg_2 +
+			(0x60 * vc_slot) + (dt_slot * 0x0c));
+	CAM_DBG(CAM_TPG, "TPG[%d] vc%d_dt%d_cfg_2=0x%x",
+			hw->hw_idx,
+			vc_slot, dt_slot, val);
+
+	return 0;
+}
+
 static int configure_dt(
 	struct tpg_hw *hw,
 	uint32_t       vc_slot,
@@ -184,6 +335,100 @@ static int configure_dt(
 	return 0;
 }
 
+
+
+#define VC1_GAIN   0x100
+
+static int configure_vc_v3(
+	struct tpg_hw *hw,
+	uint32_t       vc_slot,
+	int            num_dts,
+	struct tpg_stream_config_v3_t *stream)
+{
+	uint32_t val = 0;
+	struct cam_hw_soc_info *soc_info = NULL;
+	struct cam_tpg_ver_1_3_reg_offset *tpg_reg = NULL;
+
+	if (!hw || !hw->hw_info || !hw->hw_info->hw_data) {
+		CAM_ERR(CAM_TPG, "invalid params");
+		return -EINVAL;
+	}
+	tpg_reg  = hw->hw_info->hw_data;
+
+	soc_info = hw->soc_info;
+	/* Use CFA pattern here */
+	if (stream->output_format == TPG_IMAGE_FORMAT_QCFA)
+		val |= (1 << tpg_reg->tpg_color_bar_qcfa_en_shift);
+
+	if (stream->cb_mode == TPG_COLOR_BAR_MODE_SPLIT)
+		val |= (1 << tpg_reg->tpg_split_en_shift);
+
+	if (stream->cfa_info_exist != 0) {
+		val |= ((stream->cfa_info.pattern_height - 1) << tpg_reg->tpg_size_y_shift);
+		val |= ((stream->cfa_info.pattern_width - 1) << tpg_reg->tpg_size_x_shift);
+		val |= (1 << tpg_reg->tpg_xcfa_en_shift);
+		configure_xcfa_array_v3(hw, stream);
+	}
+
+	CAM_DBG(CAM_TPG, "TPG[%d] period: %d", hw->hw_idx, stream->rotate_period);
+	val |= ((stream->rotate_period & 0x3F) <<
+			tpg_reg->tpg_color_bar_qcfa_rotate_period_shift);
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc0_color_bar_cfg + (0x60 * vc_slot));
+	CAM_DBG(CAM_TPG, "TPG[%d] vc%d_color_bar_cfg=0x%x",
+			hw->hw_idx,
+			vc_slot, val);
+
+	val = stream->hbi;
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc0_hbi_cfg + (0x60 * vc_slot));
+	CAM_DBG(CAM_TPG, "TPG[%d] vc%d_hbi_cfg=0x%x",
+			hw->hw_idx,
+			vc_slot, val);
+
+	val = stream->vbi;
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc0_vbi_cfg + (0x60 * vc_slot));
+	CAM_DBG(CAM_TPG, "TPG[%d] vc%d_vbi_cgf=0x%x",
+			hw->hw_idx,
+			vc_slot, val);
+
+	cam_io_w_mb(0x12345678,
+		soc_info->reg_map[0].mem_base +
+		tpg_reg->tpg_vc0_lfsr_seed + (0x60 * vc_slot));
+
+	val = ((0 << tpg_reg->tpg_num_frames_shift_val) |
+		((num_dts-1) <<	 tpg_reg->tpg_num_dts_shift_val) |
+		stream->vc);
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc0_cfg0 + (0x60 * vc_slot));
+	CAM_DBG(CAM_TPG, "TPG[%d] vc%d_cfg0=0x%x",
+			hw->hw_idx,
+			vc_slot, val);
+	if (hw->hw_info->shdr_overlap == 1) {
+		cam_io_w_mb(hw->hw_info->shdr_overlap << tpg_reg->tpg_overlap_shdr_en_shift,
+			soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
+	}
+	if (hw->hw_info->shdr_offset_num_batch >= 0 && vc_slot > 0)	{
+		val =  (VC1_GAIN << tpg_reg->tpg_gain_shift);
+		val |= (hw->hw_info->shdr_offset_num_batch <<
+				tpg_reg->tpg_shdr_offset_num_batch_shift);
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+					tpg_reg->tpg_vc1_gain_cfg + (0x60 * (vc_slot-1)));
+		val =  ((stream->shdr_line_offset0 * vc_slot)
+			<< tpg_reg->tpg_shdr_line_offset0_shift);
+		val |= ((stream->shdr_line_offset1 * vc_slot)
+			<< tpg_reg->tpg_shdr_line_offset1_shift);
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_vc1_shdr_cfg + (0x60 * (vc_slot-1)));
+		CAM_DBG(CAM_TPG, "TPG[%d] vc%d_cfg0=0x%x shdr",
+			hw->hw_idx,
+			vc_slot, val);
+	}
+
+	return 0;
+}
+
 #define RGGB_IR_0  0x00770091
 #define RGGB_IR_1  0x00770019
 #define RGGB_2x2   0x05055A5A
@@ -258,7 +503,7 @@ static int configure_vc(
 		CAM_ERR(CAM_TPG, "invalid params");
 		return -EINVAL;
 	}
-	tpg_reg  = hw->hw_info->hw_data;
+	tpg_reg = hw->hw_info->hw_data;
 
 	soc_info = hw->soc_info;
 	/* Use CFA pattern here */
@@ -309,7 +554,7 @@ static int configure_vc(
 		tpg_reg->tpg_vc0_lfsr_seed + (0x60 * vc_slot));
 
 	val = ((0 << tpg_reg->tpg_num_frames_shift_val) |
-		((num_dts-1) <<	 tpg_reg->tpg_num_dts_shift_val) |
+		((num_dts-1) << tpg_reg->tpg_num_dts_shift_val) |
 		stream->vc);
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 			tpg_reg->tpg_vc0_cfg0 + (0x60 * vc_slot));
@@ -320,7 +565,7 @@ static int configure_vc(
 		cam_io_w_mb(hw->hw_info->shdr_overlap << tpg_reg->tpg_overlap_shdr_en_shift,
 			soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
 	}
-	if (hw->hw_info->shdr_offset_num_batch >= 0 && vc_slot > 0)	{
+	if (hw->hw_info->shdr_offset_num_batch >= 0 && vc_slot > 0) {
 		val =  (VC1_GAIN << tpg_reg->tpg_gain_shift);
 		val |= (hw->hw_info->shdr_offset_num_batch <<
 				tpg_reg->tpg_shdr_offset_num_batch_shift);
@@ -336,7 +581,6 @@ static int configure_vc(
 			hw->hw_idx,
 			vc_slot, val);
 	}
-
 	return 0;
 }
 
@@ -391,32 +635,60 @@ int tpg_hw_v_1_3_process_cmd(
 	switch(cmd) {
 	case TPG_CONFIG_VC:
 	{
-		struct vc_config_args *vc_config =
-			(struct vc_config_args *)arg;
-
-		if (vc_config == NULL) {
-			CAM_ERR(CAM_TPG, "invalid argument");
-			return -EINVAL;
+		if (hw->stream_version == 1) {
+			struct vc_config_args *vc_config =
+				(struct vc_config_args *)arg;
+
+			if (vc_config == NULL) {
+				CAM_ERR(CAM_TPG, "invalid argument");
+				return -EINVAL;
+			}
+			rc = configure_vc(hw,
+				vc_config->vc_slot,
+				vc_config->num_dts,
+				vc_config->stream);
+		} else if (hw->stream_version == 3) {
+			struct vc_config_args_v3 *vc_config_v3 =
+				(struct vc_config_args_v3 *)arg;
+
+			if (vc_config_v3 == NULL) {
+				CAM_ERR(CAM_TPG, "invalid argument");
+				return -EINVAL;
+			}
+			rc = configure_vc_v3(hw,
+				vc_config_v3->vc_slot,
+				vc_config_v3->num_dts,
+				vc_config_v3->stream);
 		}
-		rc = configure_vc(hw,
-			vc_config->vc_slot,
-			vc_config->num_dts,
-			vc_config->stream);
 	}
 	break;
 	case TPG_CONFIG_DT:
 	{
-		struct dt_config_args *dt_config =
-			(struct dt_config_args *)arg;
-
-		if (dt_config == NULL) {
-			CAM_ERR(CAM_TPG, "invalid argument");
-			return -EINVAL;
+		if (hw->stream_version == 1) {
+			struct dt_config_args *dt_config =
+				(struct dt_config_args *)arg;
+
+			if (dt_config == NULL) {
+				CAM_ERR(CAM_TPG, "invalid argument");
+				return -EINVAL;
+			}
+			rc = configure_dt(hw,
+				dt_config->vc_slot,
+				dt_config->dt_slot,
+				dt_config->stream);
+		} else if (hw->stream_version == 3) {
+			struct dt_config_args_v3 *dt_config_v3 =
+				(struct dt_config_args_v3 *)arg;
+
+			if (dt_config_v3 == NULL) {
+				CAM_ERR(CAM_TPG, "invalid argument");
+				return -EINVAL;
+			}
+			rc = configure_dt_v3(hw,
+				dt_config_v3->vc_slot,
+				dt_config_v3->dt_slot,
+				dt_config_v3->stream);
 		}
-		rc = configure_dt(hw,
-			dt_config->vc_slot,
-			dt_config->dt_slot,
-			dt_config->stream);
 	}
 	break;
 	case TPG_CONFIG_CTRL:

+ 1 - 1
drivers/cam_sensor_module/cam_tpg/tpg_hw/tpg_hw_v_1_3/tpg_hw_v_1_3_data.h

@@ -35,7 +35,7 @@ struct tpg_hw_info tpg_v_1_3_hw_info = {
 };
 
 struct tpg_hw_info tpg_v_1_3_1_hw_info = {
-	.version = TPG_HW_VERSION_1_3,
+	.version = TPG_HW_VERSION_1_3_1,
 	.max_vc_channels = 4,
 	.max_dt_channels_per_vc = 4,
 	.ops = &tpg_hw_v_1_3_ops,

+ 149 - 1
include/uapi/camera/media/cam_sensor.h

@@ -163,6 +163,33 @@ enum tpg_phy_type_t {
 	TPG_PHY_TYPE_MAX,
 };
 
+enum tpg_pixel_type_t {
+	TPG_PIXEL_TYPE_INVALID = 0,
+	TPG_PIXEL_TYPE_RED,
+	TPG_PIXEL_TYPE_GREEN,
+	TPG_PIXEL_TYPE_BLUE,
+	TPG_PIXEL_TYPE_IR,
+	TPG_PIXEL_TYPE_MONO,
+};
+
+enum tpg_exposure_type_t {
+	TPG_EXPOSUREL_TYPE_INVALID = 0,
+	TPG_EXPOSURE_TYPE_LONG,
+	TPG_EXPOSURE_TYPE_MIDDLE,
+	TPG_EXPOSURE_TYPE_SHORT,
+};
+
+enum xcfa_type_t {
+	XCFA_TYPE_BAYER = 0,
+	XCFA_TYPE_QUADCFA,
+	XCFA_TYPE_THREEXTHREECFA,
+	XCFA_TYPE_FOURXFOURCFA,
+	XCFA_TYPE_RGBIR,
+	XCFA_TYPE_RGBWC,
+	XCFA_TYPE_RGBWK,
+	XCFA_TYPE_UNCONVENTIONAL_BAYER,
+};
+
 enum tpg_interleaving_format_t {
 	TPG_INTERLEAVING_FORMAT_INVALID = 0,
 	TPG_INTERLEAVING_FORMAT_FRAME,
@@ -738,6 +765,37 @@ struct tpg_command_header_t {
 	uint32_t cmd_version;
 } __attribute__((packed));
 
+/**
+ * tpg_pixel_coordinate_t : pixel coordinate structure
+ *
+ * @xcoordinate           : X coordinate
+ * @ycoordinate           : Y coordiante
+ * @pixel_type            : red green blue ir mono
+ */
+struct tpg_pixel_coordinate_t {
+	uint32_t xcoordinate;
+	uint32_t ycoordinate;
+	uint32_t exposure_type;
+	uint32_t pixel_type;
+} __attribute__((packed));
+
+/**
+ * tpg_cfa_information_t      : tpg cfa information structure
+ *
+ * @number_of_pixel_per_color : number of pixel per color
+ * @pattern_width             : pattern width
+ * @pattern_height            : pattern height
+ * @pixel_coordinate_count    : pixel coordinate count
+ * @pixel_coordinate          : pixel coordinate array
+ */
+struct tpg_cfa_information_t {
+	uint32_t number_of_pixel_per_color;
+	uint32_t pattern_width;
+	uint32_t pattern_height;
+	uint32_t pixel_coordinate_count;
+	struct tpg_pixel_coordinate_t pixel_coordinate[64];
+} __attribute__((packed));
+
 /**
  * tpg_global_config_t : global configuration command structure
  *
@@ -769,6 +827,45 @@ struct tpg_global_config_t {
 	uint32_t reserved[4];
 } __attribute__((packed));
 
+/**
+ * tpg_old_stream_config_t : stream configuration command
+ *
+ * @header:  common tpg command header
+ * @pattern_type     : tpg pattern type used in this stream
+ * @cb_mode          : tpg color bar mode used in this stream
+ * @frame_count      : frame count in case of trigger burst mode
+ * @stream_type      : type of stream like image pdaf etc
+ * @stream_dimension : Dimension of the stream
+ * @pixel_depth      : bits per each pixel
+ * @cfa_arrangement  : color filter arragement
+ * @output_format    : output image format
+ * @hbi              : horizontal blanking intervel
+ * @vbi              : vertical   blanking intervel
+ * @vc               : virtual channel of this stream
+ * @dt               : data type of this stream
+ * @skip_pattern     : skip pattern for this stream
+ * @rotate_period    : rotate period for this stream
+ * @reserved         : reserved for future use
+ */
+struct tpg_old_stream_config_t {
+	struct tpg_command_header_t header;
+	enum tpg_pattern_t pattern_type;
+	enum tpg_color_bar_mode_t cb_mode;
+	uint32_t frame_count;
+	enum tpg_stream_t stream_type;
+	struct stream_dimension stream_dimension;
+	uint8_t pixel_depth;
+	enum tpg_cfa_arrangement_t cfa_arrangement;
+	enum tpg_image_format_t output_format;
+	uint32_t hbi;
+	uint32_t vbi;
+	uint16_t vc;
+	uint16_t dt;
+	uint32_t skip_pattern;
+	uint32_t rotate_period;
+	uint32_t reserved[4];
+} __attribute__((packed));
+
 /**
  * tpg_stream_config_t : stream configuration command
  *
@@ -786,10 +883,11 @@ struct tpg_global_config_t {
  * @vc               : virtual channel of this stream
  * @dt               : data type of this stream
  * @skip_pattern     : skip pattern for this stream
+ * @rotate_period    : rotate period for this stream
  * @xcfa_debug       : for xcfa debug;
  * @shdr_line_offset0 : for shdr line offset0
  * @shdr_line_offset1 : for shdr line offset1
- * @reserved          : reserved for future use
+ * @reserved         : reserved for future use
  */
 struct tpg_stream_config_t {
 	struct tpg_command_header_t header;
@@ -813,6 +911,56 @@ struct tpg_stream_config_t {
 	uint32_t reserved[4];
 } __attribute__((packed));
 
+/**
+ * tpg_stream_config_t : stream configuration command
+ *
+ * @header:  common tpg command header
+ * @pattern_type     : tpg pattern type used in this stream
+ * @cb_mode          : tpg color bar mode used in this stream
+ * @frame_count      : frame count in case of trigger burst mode
+ * @stream_type      : type of stream like image pdaf etc
+ * @stream_dimension : Dimension of the stream
+ * @pixel_depth      : bits per each pixel
+ * @cfa_arrangement  : color filter arragement
+ * @output_format    : output image format
+ * @hbi              : horizontal blanking intervel
+ * @vbi              : vertical   blanking intervel
+ * @vc               : virtual channel of this stream
+ * @dt               : data type of this stream
+ * @skip_pattern     : skip pattern for this stream
+ * @rotate_period    : rotate period for this stream
+ * @shdr_line_offset0 : for shdr line offset0
+ * @shdr_line_offset1 : for shdr line offset1
+ * @cfa_info_exist    : cfa info exists
+ * @cfa_info          : cfa information
+ * @xcfa_type         : xcfa type
+ * @reserved          : reserved for future use
+ */
+struct tpg_stream_config_v3_t {
+	struct tpg_command_header_t header;
+	uint32_t pattern_type;
+	uint32_t cb_mode;
+	uint32_t frame_count;
+	uint32_t stream_type;
+	struct stream_dimension stream_dimension;
+	uint32_t pixel_depth;
+	uint32_t cfa_arrangement;
+	uint32_t output_format;
+	uint32_t hbi;
+	uint32_t vbi;
+	uint16_t vc;
+	uint16_t dt;
+	uint32_t skip_pattern;
+	uint32_t rotate_period;
+	uint32_t xcfa_debug;
+	uint32_t shdr_line_offset0;
+	uint32_t shdr_line_offset1;
+	uint32_t cfa_info_exist;
+	struct tpg_cfa_information_t cfa_info;
+	uint32_t xcfa_type;
+	uint32_t reserved[5];
+} __attribute__((packed));
+
 /**
  * tpg_illumination_control : illumianation control command
  *