瀏覽代碼

msm: camera: isp: Handle PD and RDI resource if PIX port is not present

In some use-case, PD and RDI ports are only present and we need
separate state machine to handle this scenario as we don't
enable any interrupts on PPP path.

This commit handles such scenario with help of RDI only state
machine.

CRs-Fixed: 3090212
Change-Id: I42b708a11669ead1058e87f9eaa56a79e13b0474
Signed-off-by: Chandan Kumar Jha <[email protected]>
Signed-off-by: Gaurav Jindal <[email protected]>
Gaurav Jindal 3 年之前
父節點
當前提交
73c115c318

+ 50 - 23
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -80,6 +80,15 @@ static int cam_ife_mgr_prog_default_settings(
 static int cam_ife_mgr_cmd_get_sof_timestamp(struct cam_ife_hw_mgr_ctx *ife_ctx,
 	uint64_t *time_stamp, uint64_t *boot_time_stamp, uint64_t *prev_time_stamp);
 
+static bool cam_isp_is_ctx_primary_rdi(struct cam_ife_hw_mgr_ctx  *ctx)
+{
+	/* check for RDI only and RDI PD context*/
+	if (ctx->flags.is_rdi_only_context || ctx->flags.rdi_pd_context)
+		return true;
+
+	return false;
+}
+
 static int cam_ife_mgr_finish_clk_bw_update(
 	struct cam_ife_hw_mgr_ctx *ctx,
 	uint64_t request_id, bool skip_clk_data_rst)
@@ -793,8 +802,8 @@ static int cam_ife_mgr_csid_start_hw(
 				continue;
 
 			if (primary_rdi_csid_res == hw_mgr_res->res_id) {
-				hw_mgr_res->hw_res[0]->rdi_only_ctx =
-				ctx->flags.is_rdi_only_context;
+				hw_mgr_res->hw_res[0]->is_rdi_primary_res =
+					cam_isp_is_ctx_primary_rdi(ctx);
 			}
 
 			CAM_DBG(CAM_ISP, "csid[%u] res:%s res_id %d cnt %u",
@@ -882,7 +891,7 @@ static void cam_ife_hw_mgr_stop_hw_res(
 				CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ,
 				&dummy_args, sizeof(dummy_args));
 		}
-		isp_hw_res->hw_res[i]->rdi_only_ctx = false;
+		isp_hw_res->hw_res[i]->is_rdi_primary_res = false;
 	}
 }
 
@@ -1536,7 +1545,7 @@ static int cam_ife_mgr_csid_stop_hw(
 		stop.stop_cmd = stop_cmd;
 		hw_intf->hw_ops.stop(hw_intf->hw_priv, &stop, sizeof(stop));
 		for (i = 0; i < cnt; i++)
-			stop_res[i]->rdi_only_ctx = false;
+			stop_res[i]->is_rdi_primary_res = false;
 	}
 
 	return 0;
@@ -4347,17 +4356,6 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
 		}
 	}
 
-	if (in_port->rdi_count) {
-		/* get ife csid RDI resource */
-		rc = cam_ife_hw_mgr_acquire_res_ife_csid_rdi(ife_ctx, in_port,
-			acquired_hw_path);
-		if (rc) {
-			CAM_ERR(CAM_ISP,
-				"Acquire IFE CSID RDI resource Failed");
-			goto err;
-		}
-	}
-
 	if (in_port->ppp_count) {
 		/* get ife csid PPP resource */
 
@@ -4378,6 +4376,17 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
 		}
 	}
 
+	if (in_port->rdi_count) {
+		/* get ife csid RDI resource */
+		rc = cam_ife_hw_mgr_acquire_res_ife_csid_rdi(ife_ctx, in_port,
+			acquired_hw_path);
+		if (rc) {
+			CAM_ERR(CAM_ISP,
+				"Acquire IFE CSID RDI resource Failed");
+			goto err;
+		}
+	}
+
 	/* acquire SFE input resource */
 	if ((ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) &&
 		(in_port->ipp_count || in_port->rdi_count)) {
@@ -4856,6 +4865,14 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		CAM_DBG(CAM_ISP, "RDI only context");
 	}
 
+	/* Check whether context has only RDI and PD resource */
+	if (!total_pix_port &&
+		(total_pd_port && total_rdi_port)) {
+		ife_ctx->flags.rdi_pd_context = true;
+		CAM_DBG(CAM_ISP, "RDI and PD context with [%u pd] [%u rdi]",
+			total_pd_port, total_rdi_port);
+	}
+
 	/* Check if all output ports are of lite  */
 	if (total_lite_port == total_pix_port + total_rdi_port)
 		ife_ctx->flags.is_lite_context = true;
@@ -5212,6 +5229,14 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 		CAM_DBG(CAM_ISP, "RDI only context");
 	}
 
+	/* Check whether context has only RDI and PD resource */
+	if (!total_pix_port &&
+		(total_pd_port && total_rdi_port)) {
+		ife_ctx->flags.rdi_pd_context = true;
+		CAM_DBG(CAM_ISP, "RDI and PD context with [%u pd] [%u rdi]",
+			total_pd_port, total_rdi_port);
+	}
+
 	/* acquire HW resources */
 	for (i = 0; i < acquire_args->num_acq; i++) {
 		if (isp_resource[i].resource_id != CAM_ISP_RES_ID_PORT)
@@ -6709,9 +6734,9 @@ start_only:
 		case CAM_ISP_IFE_OUT_RES_RDI_1:
 		case CAM_ISP_IFE_OUT_RES_RDI_2:
 		case CAM_ISP_IFE_OUT_RES_RDI_3:
-			if (!res_rdi_context_set && ctx->flags.is_rdi_only_context) {
-				hw_mgr_res->hw_res[0]->rdi_only_ctx =
-					ctx->flags.is_rdi_only_context;
+			if (!res_rdi_context_set && cam_isp_is_ctx_primary_rdi(ctx)) {
+				hw_mgr_res->hw_res[0]->is_rdi_primary_res =
+					cam_isp_is_ctx_primary_rdi(ctx);
 				res_rdi_context_set = true;
 				primary_rdi_out_res = hw_mgr_res->res_id;
 			}
@@ -6741,9 +6766,10 @@ start_only:
 	/* Start the IFE mux in devices */
 	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
 		if (primary_rdi_src_res == hw_mgr_res->res_id) {
-			hw_mgr_res->hw_res[0]->rdi_only_ctx =
-				ctx->flags.is_rdi_only_context;
+			hw_mgr_res->hw_res[0]->is_rdi_primary_res =
+				cam_isp_is_ctx_primary_rdi(ctx);
 		}
+
 		rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
 		if (rc) {
 			CAM_ERR(CAM_ISP, "Can not start IFE Mux (%d)",
@@ -11456,7 +11482,8 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 			else if (ctx->flags.is_fe_enabled && !ctx->flags.is_offline &&
 				ctx->ctx_type != CAM_IFE_CTX_TYPE_SFE)
 				isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_FS2;
-			else if (ctx->flags.is_rdi_only_context || ctx->flags.is_lite_context)
+			else if (ctx->flags.is_rdi_only_context || ctx->flags.is_lite_context ||
+					ctx->flags.rdi_pd_context)
 				isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_RDI;
 			else
 				isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_PIX;
@@ -12401,7 +12428,7 @@ static int cam_ife_hw_mgr_handle_hw_rup(
 	case CAM_ISP_HW_VFE_IN_RDI1:
 	case CAM_ISP_HW_VFE_IN_RDI2:
 	case CAM_ISP_HW_VFE_IN_RDI3:
-		if (!ife_hw_mgr_ctx->flags.is_rdi_only_context)
+		if (!cam_isp_is_ctx_primary_rdi(ife_hw_mgr_ctx))
 			break;
 		if (atomic_read(&ife_hw_mgr_ctx->overflow_pending))
 			break;
@@ -12514,7 +12541,7 @@ static int cam_ife_hw_mgr_handle_hw_sof(
 	case CAM_ISP_HW_VFE_IN_RDI1:
 	case CAM_ISP_HW_VFE_IN_RDI2:
 	case CAM_ISP_HW_VFE_IN_RDI3:
-		if (!ife_hw_mgr_ctx->flags.is_rdi_only_context)
+		if (!cam_isp_is_ctx_primary_rdi(ife_hw_mgr_ctx))
 			break;
 		cam_ife_mgr_cmd_get_sof_timestamp(ife_hw_mgr_ctx,
 			&sof_done_event_data.timestamp,

+ 3 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -173,6 +173,8 @@ struct cam_ife_hw_mgr_sfe_info {
  * @sys_cache_usage:     Per context sys cache usage
  *                       The corresponding index will be set
  *                       for the cache type
+ * @rdi_pd_context:      Flag to specify the context has
+ *                       only rdi and PD resource without PIX port.
  *
  */
 struct cam_ife_hw_mgr_ctx_flags {
@@ -194,6 +196,7 @@ struct cam_ife_hw_mgr_ctx_flags {
 	bool   is_aeb_mode;
 	bool   rdi_lcr_en;
 	bool   sys_cache_usage[CAM_LLCC_MAX];
+	bool   rdi_pd_context;
 };
 
 /**

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -3169,7 +3169,7 @@ static int cam_ife_csid_ver2_program_rdi_path(
 
 	val = csid_hw->debug_info.path_mask;
 
-	if (res->rdi_only_ctx) {
+	if (res->is_rdi_primary_res) {
 		path_cfg->handle_camif_irq = true;
 		val |= path_reg->camif_irq_mask;
 	}

+ 3 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -224,7 +224,6 @@ enum cam_isp_hw_cmd_type {
  * @tasklet_info:                 Tasklet structure that will be used to
  *                                schedule IRQ events related to this resource
  * @irq_handle:                   handle returned on subscribing for IRQ event
- * @rdi_only_ctx:                 resource belong to rdi only context or not
  * @init:                         function pointer to init the HW resource
  * @deinit:                       function pointer to deinit the HW resource
  * @start:                        function pointer to start the HW resource
@@ -234,6 +233,8 @@ enum cam_isp_hw_cmd_type {
  * @top_half_handler:             Top Half handler function
  * @bottom_half_handler:          Bottom Half handler function
  * @res_name:                     Name of resource
+ * @is_rdi_primary_res:           Indicates whether RDI is primiary resource or not.
+ *                                Based on this, We need to enable interrupts on RDI path only.
  */
 struct cam_isp_resource_node {
 	enum cam_isp_resource_type     res_type;
@@ -245,7 +246,6 @@ struct cam_isp_resource_node {
 	void                          *cdm_ops;
 	void                          *tasklet_info;
 	int                            irq_handle;
-	int                            rdi_only_ctx;
 
 	int (*init)(struct cam_isp_resource_node *rsrc_node,
 		void *init_args, uint32_t arg_size);
@@ -258,6 +258,7 @@ struct cam_isp_resource_node {
 	CAM_IRQ_HANDLER_TOP_HALF       top_half_handler;
 	CAM_IRQ_HANDLER_BOTTOM_HALF    bottom_half_handler;
 	uint8_t                        res_name[CAM_ISP_RES_NAME_LEN];
+	bool                           is_rdi_primary_res;
 };
 
 /*

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c

@@ -1361,7 +1361,7 @@ static int cam_sfe_bus_acquire_sfe_out(void *priv, void *acquire_args,
 	mutex_unlock(&rsrc_data->common_data->bus_mutex);
 
 	bus_priv->tasklet_info = acq_args->tasklet;
-	rsrc_node->rdi_only_ctx = 0;
+	rsrc_node->is_rdi_primary_res = false;
 	rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
 	rsrc_node->tasklet_info = acq_args->tasklet;
 	rsrc_node->cdm_ops = out_acquire_args->cdm_ops;

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -2040,7 +2040,7 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args,
 	mutex_unlock(&rsrc_data->common_data->bus_mutex);
 
 	ver3_bus_priv->tasklet_info = acq_args->tasklet;
-	rsrc_node->rdi_only_ctx = 0;
+	rsrc_node->is_rdi_primary_res = false;
 	rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
 	rsrc_node->tasklet_info = acq_args->tasklet;
 	rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
@@ -2239,7 +2239,7 @@ static int cam_vfe_bus_ver3_start_vfe_out(
 	}
 
 	if ((common_data->is_lite || source_group > CAM_VFE_BUS_VER3_SRC_GRP_0)
-		&& !vfe_out->rdi_only_ctx)
+		&& !vfe_out->is_rdi_primary_res)
 		goto end;
 
 	if ((common_data->supported_irq & CAM_VFE_HW_IRQ_CAP_RUP) &&

+ 6 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c

@@ -231,10 +231,10 @@ int cam_vfe_camif_lite_ver3_acquire_resource(
 		camif_lite_res->res_priv;
 	acquire_data = (struct cam_vfe_acquire_args *)acquire_param;
 
-	camif_lite_data->sync_mode   = acquire_data->vfe_in.sync_mode;
-	camif_lite_data->event_cb    = acquire_data->event_cb;
-	camif_lite_data->priv        = acquire_data->priv;
-	camif_lite_res->rdi_only_ctx = 0;
+	camif_lite_data->sync_mode         = acquire_data->vfe_in.sync_mode;
+	camif_lite_data->event_cb          = acquire_data->event_cb;
+	camif_lite_data->priv              = acquire_data->priv;
+	camif_lite_res->is_rdi_primary_res = false;
 	CAM_DBG(CAM_ISP, "Acquired VFE:%d CAMIF LITE:%d %s sync_mode=%d",
 		camif_lite_res->hw_intf->hw_idx,
 		camif_lite_res->res_id,
@@ -329,7 +329,7 @@ skip_core_cfg:
 	cam_io_w_mb(rsrc_data->reg_data->top_debug_cfg_en, rsrc_data->mem_base +
 		rsrc_data->common_reg->top_debug_cfg);
 
-	if (!camif_lite_res->rdi_only_ctx)
+	if (!camif_lite_res->is_rdi_primary_res)
 		goto subscribe_err;
 
 	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
@@ -1179,7 +1179,7 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 			camif_lite_priv->error_ts.tv_sec,
 			camif_lite_priv->error_ts.tv_nsec);
 
-		if (camif_lite_node->rdi_only_ctx)
+		if (camif_lite_node->is_rdi_primary_res)
 			CAM_INFO(CAM_ISP,
 				"SOF %lld:%lld EPOCH %lld:%lld EOF %lld:%lld",
 				camif_lite_priv->sof_ts.tv_sec,

+ 5 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c

@@ -273,10 +273,10 @@ int cam_vfe_rdi_ver2_acquire_resource(
 	rdi_data     = (struct cam_vfe_mux_rdi_data *)rdi_res->res_priv;
 	acquire_data = (struct cam_vfe_acquire_args *)acquire_param;
 
-	rdi_data->event_cb    = acquire_data->event_cb;
-	rdi_data->priv        = acquire_data->priv;
-	rdi_data->sync_mode   = acquire_data->vfe_in.sync_mode;
-	rdi_res->rdi_only_ctx = 0;
+	rdi_data->event_cb          = acquire_data->event_cb;
+	rdi_data->priv              = acquire_data->priv;
+	rdi_data->sync_mode         = acquire_data->vfe_in.sync_mode;
+	rdi_res->is_rdi_primary_res = false;
 
 	return 0;
 }
@@ -330,7 +330,7 @@ static int cam_vfe_rdi_resource_start(
 		}
 	}
 
-	if (!rdi_res->rdi_only_ctx)
+	if (!rdi_res->is_rdi_primary_res)
 		goto end;
 
 	rdi_irq_mask[0] =

+ 4 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

@@ -440,9 +440,9 @@ int cam_vfe_top_ver4_dump_timestamps(
 			if (res->res_id == res_id)
 				break;
 		} else {
-			if (res->rdi_only_ctx && res->res_id == res_id) {
+			if (res->is_rdi_primary_res && res->res_id == res_id) {
 				break;
-			} else if (!res->rdi_only_ctx && camif_res) {
+			} else if (!res->is_rdi_primary_res && camif_res) {
 				vfe_priv  = camif_res->res_priv;
 				break;
 			}
@@ -1113,7 +1113,7 @@ static enum cam_vfe_top_ver4_fsm_state cam_vfe_top_ver4_fsm_next_state(
 {
 	switch (state) {
 	case VFE_TOP_VER4_FSM_SOF:
-		return (res->rdi_only_ctx) ? VFE_TOP_VER4_FSM_EOF : VFE_TOP_VER4_FSM_EPOCH;
+		return (res->is_rdi_primary_res) ? VFE_TOP_VER4_FSM_EOF : VFE_TOP_VER4_FSM_EPOCH;
 	case VFE_TOP_VER4_FSM_EPOCH:
 		return VFE_TOP_VER4_FSM_EOF;
 	case VFE_TOP_VER4_FSM_EOF:
@@ -1498,7 +1498,7 @@ skip_core_cfg:
 	 *     2. Resource is not primary RDI
 	 */
 	if (((rsrc_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE) && rsrc_data->is_dual) ||
-		(!rsrc_data->is_pixel_path && !vfe_res->rdi_only_ctx))
+		(!rsrc_data->is_pixel_path && !vfe_res->is_rdi_primary_res))
 		goto subscribe_err;
 
 	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] = rsrc_data->reg_data->sof_irq_mask |