浏览代码

msm: camera: isp: Drop initial few frames in TFE CSID

Add support to discard initial number of frames for all paths
at CSID input. The number of frames to discard is obtained
from userland in blob config.

CRs-Fixed: 3603614
Change-Id: Ifff5f6013ae37ab54154c092571f2b40d51fa849
Signed-off-by: Ayush Kumar <[email protected]>
Ayush Kumar 1 年之前
父节点
当前提交
490d086f78

+ 72 - 0
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -4645,6 +4645,59 @@ static inline int cam_isp_tfe_validate_bw_limiter_blob(
 	return 0;
 }
 
+static int cam_isp_tfe_blob_csid_discard_init_frame_update(
+	struct cam_isp_generic_blob_info       *blob_info,
+	struct cam_isp_discard_initial_frames  *discard_config,
+	struct cam_hw_prepare_update_args      *prepare)
+{
+	struct cam_tfe_hw_mgr_ctx                   *ctx = NULL;
+	struct cam_hw_intf                          *hw_intf;
+	struct cam_isp_hw_mgr_res                   *hw_mgr_res;
+	struct cam_isp_resource_node                *res;
+	struct cam_tfe_csid_discard_init_frame_args discard_args;
+	int rc = 0, i;
+
+	ctx = prepare->ctxt_to_hw_map;
+	discard_args.num_frames = discard_config->num_frames;
+
+	if (discard_args.num_frames <= 0) {
+		CAM_DBG(CAM_ISP, "Invalid num of frames %d CSID[%u]",
+			discard_args.num_frames, blob_info->base_info->idx);
+		return rc;
+	}
+
+	CAM_DBG(CAM_ISP, "Num of frame to be drop %d on CSID[%u]", discard_args.num_frames,
+		blob_info->base_info->idx);
+
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+
+			hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+			res = hw_mgr_res->hw_res[i];
+			if (!(hw_intf && hw_intf->hw_ops.process_cmd))
+				continue;
+
+			if (hw_intf->hw_idx != blob_info->base_info->idx)
+				continue;
+
+			discard_args.res = res;
+			rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+				CAM_ISP_HW_CMD_CSID_DISCARD_INIT_FRAMES,
+				&discard_args,
+				sizeof(struct cam_tfe_csid_discard_init_frame_args));
+			if (rc) {
+				CAM_ERR(CAM_ISP,
+					"Failed to update discard frame cfg for res: %s on CSID[%u]",
+					res->res_name, blob_info->base_info->idx);
+			}
+		}
+	}
+
+	return rc;
+}
+
 static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 	uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
 {
@@ -5014,6 +5067,25 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 				prepare->packet->header.request_id, rc, tfe_mgr_ctx->ctx_index);
 	}
 		break;
+	case CAM_ISP_TFE_GENERIC_BLOB_TYPE_DISCARD_INITIAL_FRAMES: {
+		struct cam_isp_discard_initial_frames *discard_config;
+
+		if (blob_size < sizeof(struct cam_isp_tfe_discard_initial_frames)) {
+			CAM_ERR(CAM_ISP,
+				"Invalid discard frames blob size %u expected %u",
+				blob_size, sizeof(struct cam_isp_discard_initial_frames));
+			return -EINVAL;
+		}
+
+		discard_config = (struct cam_isp_discard_initial_frames *)blob_data;
+
+		rc = cam_isp_tfe_blob_csid_discard_init_frame_update(
+			blob_info, discard_config, prepare);
+		if (rc)
+			CAM_ERR(CAM_ISP, "Discard init frames update failed rc %d req %lld",
+				rc, prepare->packet->header.request_id);
+	}
+		break;
 	default:
 		CAM_WARN(CAM_ISP, "Invalid blob type %d ctx %d", blob_type,
 			tfe_mgr_ctx->ctx_index);

+ 10 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h

@@ -273,5 +273,15 @@ struct cam_tfe_csid_clock_update_args {
 	uint64_t                           clk_rate;
 };
 
+/*
+ * struct cam_tfe_csid_discard_init_frame_args:
+ *
+ * @num_frames: Num frames to discard
+ * @res: Node res for this path
+ */
+struct cam_tfe_csid_discard_init_frame_args {
+	uint32_t                          num_frames;
+	struct cam_isp_resource_node     *res;
+};
 
 #endif /* _CAM_TFE_CSID_HW_INTF_H_ */

+ 69 - 9
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c

@@ -251,6 +251,9 @@ static void cam_tfe_csid_enable_path_for_init_frame_drop(
 	if (res_id == CAM_TFE_CSID_PATH_RES_IPP) {
 		res = &csid_hw->ipp_res;
 		pxl_reg = csid_reg->ipp_reg;
+	} else if (res_id == CAM_TFE_CSID_PATH_RES_PPP) {
+		res = &csid_hw->ppp_res;
+		pxl_reg = csid_reg->ppp_reg;
 	} else if (res_id >= CAM_TFE_CSID_PATH_RES_RDI_0 &&
 			res_id <= CAM_TFE_CSID_PATH_RES_RDI_2) {
 		res = &csid_hw->rdi_res[res_id];
@@ -282,8 +285,9 @@ static void cam_tfe_csid_enable_path_for_init_frame_drop(
 	if ((path_data->res_sof_cnt ==
 		path_data->init_frame_drop) &&
 		pxl_reg) {
-		CAM_DBG(CAM_ISP, "CSID:%d Enabling pixel IPP Path",
-			csid_hw->hw_intf->hw_idx);
+		CAM_DBG(CAM_ISP, "CSID:%d Enabling pixel %s Path",
+			csid_hw->hw_intf->hw_idx,
+			(res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP");
 		if (path_data->sync_mode !=
 			CAM_ISP_HW_SYNC_SLAVE) {
 			val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -1670,8 +1674,8 @@ static int cam_tfe_csid_enable_pxl_path(
 	 * Resume at frame boundary if Master or No Sync.
 	 * Slave will get resume command from Master.
 	 */
-	if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
-		path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
+	if ((path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
+		path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) && !path_data->init_frame_drop)
 		val |= CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY;
 
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
@@ -1691,7 +1695,7 @@ static int cam_tfe_csid_enable_pxl_path(
 			TFE_CSID_PATH_ERROR_LINE_COUNT;
 	}
 
-	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)
+	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ || path_data->init_frame_drop)
 		val |= TFE_CSID_PATH_INFO_INPUT_SOF;
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)
 		val |= TFE_CSID_PATH_INFO_INPUT_EOF;
@@ -1831,6 +1835,9 @@ static int cam_tfe_csid_disable_pxl_path(
 			pxl_reg->csid_pxl_ctrl_addr);
 	}
 
+	path_data->init_frame_drop = 0;
+	path_data->res_sof_cnt     = 0;
+
 	return rc;
 }
 
@@ -1886,8 +1893,8 @@ static int cam_tfe_csid_enable_ppp_path(
 	 * Resume at frame boundary if Master or No Sync.
 	 * Slave will get resume command from Master.
 	 */
-	if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
-		path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
+	if ((path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
+		path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) && !path_data->init_frame_drop)
 		val |= CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY;
 
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + ppp_reg->csid_pxl_ctrl_addr);
@@ -1901,7 +1908,7 @@ static int cam_tfe_csid_enable_ppp_path(
 	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)
+	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ || path_data->init_frame_drop)
 		val |= TFE_CSID_PATH_INFO_INPUT_SOF;
 	if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)
 		val |= TFE_CSID_PATH_INFO_INPUT_EOF;
@@ -1999,6 +2006,9 @@ static int cam_tfe_csid_disable_ppp_path(
 			ppp_reg->csid_pxl_ctrl_addr);
 	}
 
+	path_data->init_frame_drop = 0;
+	path_data->res_sof_cnt     = 0;
+
 	return rc;
 }
 
@@ -3261,6 +3271,38 @@ end:
 	return rc;
 }
 
+static int cam_tfe_csid_set_discard_frame_cfg(
+	struct cam_tfe_csid_hw *csid_hw, void *cmd_args)
+{
+	struct cam_isp_resource_node                 *res;
+	struct cam_tfe_csid_path_cfg                 *path_cfg;
+	struct cam_tfe_csid_discard_init_frame_args  *discard_config = NULL;
+
+	if (!csid_hw)
+		return -EINVAL;
+
+	discard_config = (struct cam_tfe_csid_discard_init_frame_args *)cmd_args;
+
+	res = discard_config->res;
+	if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
+		res->res_id >= CAM_TFE_CSID_PATH_RES_MAX) {
+		CAM_ERR(CAM_ISP, "CSID[%u] Invalid res_type: %d res id: %d",
+			csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
+		return -EINVAL;
+	}
+
+	if ((res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) ||
+		(res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW)) {
+
+		path_cfg = (struct cam_tfe_csid_path_cfg *)res->res_priv;
+
+		path_cfg->init_frame_drop = discard_config->num_frames;
+		path_cfg->res_sof_cnt = 0;
+	}
+
+	return 0;
+}
+
 static int cam_tfe_csid_get_regdump(struct cam_tfe_csid_hw *csid_hw,
 	void *cmd_args)
 {
@@ -3572,6 +3614,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv,
 	case CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE:
 		rc = cam_tfe_csid_set_csid_clock_dynamically(csid_hw, cmd_args);
 		break;
+	case CAM_ISP_HW_CMD_CSID_DISCARD_INIT_FRAMES:
+		rc = cam_tfe_csid_set_discard_frame_cfg(csid_hw, cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);
@@ -4101,6 +4146,12 @@ handle_fatal_error:
 			complete(&csid_hw->csid_ipp_complete);
 		}
 
+		if (irq_status[TFE_CSID_IRQ_REG_IPP] & TFE_CSID_PATH_INFO_INPUT_SOF) {
+			CAM_DBG(CAM_ISP, "CSID:%d IPP SOF received", csid_hw->hw_intf->hw_idx);
+			cam_tfe_csid_enable_path_for_init_frame_drop(csid_hw,
+				CAM_TFE_CSID_PATH_RES_IPP);
+		}
+
 		if ((irq_status[TFE_CSID_IRQ_REG_IPP] &
 			TFE_CSID_PATH_INFO_INPUT_SOF) &&
 			(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
@@ -4179,6 +4230,12 @@ handle_fatal_error:
 			complete(&csid_hw->csid_ppp_complete);
 		}
 
+		if (irq_status[TFE_CSID_IRQ_REG_PPP] & TFE_CSID_PATH_INFO_INPUT_SOF) {
+			CAM_DBG(CAM_ISP, "CSID:%d PPP SOF received", csid_hw->hw_intf->hw_idx);
+			cam_tfe_csid_enable_path_for_init_frame_drop(csid_hw,
+				CAM_TFE_CSID_PATH_RES_PPP);
+		}
+
 		if ((irq_status[TFE_CSID_IRQ_REG_PPP] &
 			TFE_CSID_PATH_INFO_INPUT_SOF) &&
 			(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
@@ -4265,8 +4322,11 @@ handle_fatal_error:
 			complete(&csid_hw->csid_rdin_complete[i]);
 		}
 
-		if (irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF)
+		if (irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF) {
+			CAM_DBG(CAM_ISP, "CSID:%d RDI:%d SOF received",
+				csid_hw->hw_intf->hw_idx);
 			cam_tfe_csid_enable_path_for_init_frame_drop(csid_hw, i);
+		}
 
 		if ((irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF) &&
 			(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {

+ 26 - 9
include/uapi/camera/media/cam_tfe.h

@@ -70,15 +70,16 @@
 #define CAM_ISP_TFE_PACKET_META_GENERIC_BLOB_RIGHT    10
 
 /* ISP TFE Generic Cmd Buffer Blob types */
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_HFR_CONFIG            0
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CLOCK_CONFIG          1
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2          2
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG     3
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_INIT_CONFIG           4
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH   15
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG        16
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_ALIGNMENT_OFFSET_INFO 17
-#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_UPDATE_OUT_RES        18
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_HFR_CONFIG              0
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CLOCK_CONFIG            1
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2            2
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG       3
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_INIT_CONFIG             4
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH     15
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG          16
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_ALIGNMENT_OFFSET_INFO   17
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_UPDATE_OUT_RES          18
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_DISCARD_INITIAL_FRAMES  19
 
 /* DSP mode */
 #define CAM_ISP_TFE_DSP_MODE_NONE                   0
@@ -594,6 +595,22 @@ struct cam_isp_tfe_out_resource_config {
 	struct cam_isp_tfe_wm_dimension_config      dimension_config[1];
 };
 
+/**
+ * struct cam_isp_tfe_discard_initial_frames - Discard init frames
+ *
+ *   Some sensors require discarding the initial frames
+ *   after the sensor is streamed on. The discard would be
+ *   applied on all paths [IPP/PPP/RDIx] for the given
+ *   pipeline.
+ *
+ * @version                 : Version field
+ * @num_frames              : Number of frames to be discarded
+ */
+struct cam_isp_tfe_discard_initial_frames {
+	__u32                    version;
+	__u32                    num_frames;
+} __attribute__((packed));
+
 #define CAM_TFE_ACQUIRE_COMMON_VER0         0x1000
 
 #define CAM_TFE_ACQUIRE_COMMON_SIZE_VER0    0x0