Selaa lähdekoodia

Merge "msm: camera: isp: Program dual tfe settings in shdr" into camera-kernel.lnx.7.0

Camera Software Integration 1 vuosi sitten
vanhempi
sitoutus
6f76aa4f18

+ 5 - 5
drivers/cam_core/cam_hw_mgr_intf.h

@@ -169,6 +169,7 @@ struct cam_hw_acquire_stream_caps {
  * @hw_mgr_ctx_id          HWMgr context id(returned)
  * @op_flags:              Used as bitwise params from hw_mgr to ctx
  *                         See xxx_hw_mgr_intf.h for definitions
+ * @link_hdl:              Link handle
  * @acquired_hw_id:        Acquired hardware mask
  * @acquired_hw_path:      Acquired path mask for an input
  *                         if input splits into multiple paths,
@@ -189,11 +190,10 @@ struct cam_hw_acquire_args {
 	void                        *ctxt_to_hw_map;
 	uint32_t                     hw_mgr_ctx_id;
 	uint32_t                     op_flags;
-
-	uint32_t    acquired_hw_id[CAM_MAX_ACQ_RES];
-	uint32_t    acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
-	uint32_t    valid_acquired_hw;
-
+	int32_t                      link_hdl;
+	uint32_t                     acquired_hw_id[CAM_MAX_ACQ_RES];
+	uint32_t                     acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
+	uint32_t                     valid_acquired_hw;
 	struct cam_hw_acquire_stream_caps op_params;
 	cam_ctx_mini_dump_cb_func    mini_dump_cb;
 };

+ 2 - 0
drivers/cam_isp/cam_isp_context.c

@@ -7431,6 +7431,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx,
 	param.acquire_info_size = cmd->data_size;
 	param.acquire_info = (uint64_t) acquire_hw_info;
 	param.mini_dump_cb = __cam_isp_ctx_minidump_cb;
+	param.link_hdl = ctx->link_hdl;
 
 	rc = __cam_isp_ctx_allocate_mem_hw_entries(ctx,
 		&param);
@@ -7598,6 +7599,7 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
 	param.acquire_info_size = cmd->data_size;
 	param.acquire_info = (uint64_t) acquire_hw_info;
 	param.mini_dump_cb = __cam_isp_ctx_minidump_cb;
+	param.link_hdl = ctx->link_hdl;
 
 	/* call HW manager to reserve the resource */
 	rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv,

+ 38 - 2
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -2371,8 +2371,10 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 	for (i = 0; i < acquire_hw_info->num_inputs; i++) {
 		if (in_port[i].usage_type)
 			tfe_ctx->is_dual = true;
-		if (in_port[i].shdr_en)
+		if (in_port[i].shdr_en) {
 			is_shdr_en = true;
+			tfe_ctx->is_shdr = true;
+		}
 		if (in_port[i].is_shdr_master)
 			is_shdr_master = true;
 	}
@@ -2448,8 +2450,14 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		acquire_args->op_flags |= CAM_IFE_CTX_SHDR_EN;
 		if (is_shdr_master)
 			acquire_args->op_flags |= CAM_IFE_CTX_SHDR_IS_MASTER;
+		g_tfe_hw_mgr.session_data[tfe_ctx->base[0].idx].is_shdr = true;
+
+		CAM_DBG(CAM_ISP, "ctx %d TFE index %d link hdl %x",
+			tfe_ctx->ctx_index, tfe_ctx->base[0].idx, acquire_args->link_hdl);
 	}
 
+	g_tfe_hw_mgr.session_data[tfe_ctx->base[0].idx].link_hdl = acquire_args->link_hdl;
+
 	cam_tfe_hw_mgr_put_ctx(&tfe_hw_mgr->used_ctx_list, &tfe_ctx);
 
 	CAM_DBG(CAM_ISP, "Exit...(success)");
@@ -3583,7 +3591,7 @@ static int cam_tfe_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
 	struct cam_tfe_hw_mgr_ctx        *ctx;
 	struct cam_isp_hw_mgr_res        *hw_mgr_res;
 	struct cam_hw_intf               *hw_intf;
-	uint32_t                          i;
+	uint32_t                          i, j, hw_index = 0;
 	bool                              res_rdi_context_set = false;
 	uint32_t                          primary_rdi_in_res;
 	uint32_t                          primary_rdi_out_res;
@@ -3654,6 +3662,25 @@ static int cam_tfe_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
 				&g_tfe_hw_mgr.debug_cfg.camif_debug,
 				sizeof(g_tfe_hw_mgr.debug_cfg.camif_debug));
 			hw_id[hw_intf->hw_idx] = true;
+
+			if (ctx->is_shdr) {
+				for (j = 0; j < CAM_TFE_HW_NUM_MAX; j++) {
+					if (g_tfe_hw_mgr.session_data[j].link_hdl ==
+						g_tfe_hw_mgr.session_data[ctx->base[0].idx].link_hdl
+						&& (j != ctx->base[0].idx) &&
+						g_tfe_hw_mgr.session_data[j].is_shdr) {
+						hw_index = j;
+						break;
+					}
+				}
+
+				rc = hw_intf->hw_ops.process_cmd(
+					hw_intf->hw_priv,
+					CAM_ISP_HW_CMD_SET_SYNC_HW_IDX,
+					&hw_index,
+					sizeof(hw_index));
+				CAM_DBG(CAM_ISP, "TFE: %d sync idx %d", ctx->base[0].idx, hw_index);
+			}
 		}
 	}
 
@@ -4007,6 +4034,11 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
 	CAM_DBG(CAM_ISP, "Enter...ctx id:%d",
 		ctx->ctx_index);
 
+	if (ctx->is_shdr) {
+		g_tfe_hw_mgr.session_data[ctx->base[0].idx].link_hdl = 0;
+		g_tfe_hw_mgr.session_data[ctx->base[0].idx].is_shdr = false;
+	}
+
 	if (ctx->init_done)
 		cam_tfe_hw_mgr_deinit_hw(ctx);
 
@@ -4032,6 +4064,8 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
 	ctx->last_cdm_done_req = 0;
 	kfree(ctx->tfe_bus_comp_grp);
 	ctx->tfe_bus_comp_grp = NULL;
+	ctx->is_shdr = false;
+	ctx->is_shdr_slave = false;
 	atomic_set(&ctx->overflow_pending, 0);
 
 	for (i = 0; i < ctx->last_submit_bl_cmd.bl_count; i++) {
@@ -6745,6 +6779,8 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 			j++;
 
 			g_tfe_hw_mgr.cdm_reg_map[i] = &soc_info->reg_map[0];
+			g_tfe_hw_mgr.session_data[i].link_hdl = 0;
+			g_tfe_hw_mgr.session_data[i].is_shdr = false;
 			CAM_DBG(CAM_ISP,
 				"reg_map: mem base = %pK cam_base = 0x%llx",
 				(void __iomem *)soc_info->reg_map[0].mem_base,

+ 20 - 16
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h

@@ -129,7 +129,8 @@ struct cam_tfe_cdm_user_data {
  * @try_recovery_cnt          Retry count for overflow recovery
  * @current_mup               Current MUP val
  * @recovery_req_id           The request id on which overflow recovery happens
- * @is_shdr_slave              indicate whether context is slave in shdr usecase
+ * @is_shdr                   Indicate if the usecase is SHDR
+ * @is_shdr_slave             Indicate whether context is slave in shdr usecase
  */
 struct cam_tfe_hw_mgr_ctx {
 	struct list_head                list;
@@ -178,6 +179,7 @@ struct cam_tfe_hw_mgr_ctx {
 	uint32_t                        try_recovery_cnt;
 	uint64_t                        recovery_req_id;
 	enum cam_cdm_id                 cdm_id;
+	bool                            is_shdr;
 	bool                            is_shdr_slave;
 };
 
@@ -195,6 +197,7 @@ struct cam_tfe_hw_mgr_ctx {
  * @free_ctx_list:         free hw context list
  * @used_ctx_list:         used hw context list
  * @ctx_pool:              context storage
+ * @session_data:          Data related to current session
  * @tfe_csid_dev_caps      csid device capability stored per core
  * @tfe_dev_caps           tfe device capability per core
  * @work q                 work queue for TFE hw manager
@@ -204,24 +207,25 @@ struct cam_tfe_hw_mgr_ctx {
  * @ctx_lock               Spinlock for HW manager
  */
 struct cam_tfe_hw_mgr {
-	struct cam_isp_hw_mgr          mgr_common;
-	struct cam_hw_intf            *csid_devices[CAM_TFE_CSID_HW_NUM_MAX];
-	struct cam_isp_hw_intf_data   *tfe_devices[CAM_TFE_HW_NUM_MAX];
-	struct cam_soc_reg_map        *cdm_reg_map[CAM_TFE_HW_NUM_MAX];
-	struct mutex                   ctx_mutex;
-	atomic_t                       active_ctx_cnt;
-	struct list_head               free_ctx_list;
-	struct list_head               used_ctx_list;
-	struct cam_tfe_hw_mgr_ctx      ctx_pool[CAM_TFE_CTX_MAX];
+	struct cam_isp_hw_mgr            mgr_common;
+	struct cam_hw_intf              *csid_devices[CAM_TFE_CSID_HW_NUM_MAX];
+	struct cam_isp_hw_intf_data     *tfe_devices[CAM_TFE_HW_NUM_MAX];
+	struct cam_soc_reg_map          *cdm_reg_map[CAM_TFE_HW_NUM_MAX];
+	struct mutex                     ctx_mutex;
+	atomic_t                         active_ctx_cnt;
+	struct list_head                 free_ctx_list;
+	struct list_head                 used_ctx_list;
+	struct cam_tfe_hw_mgr_ctx        ctx_pool[CAM_TFE_CTX_MAX];
+	struct cam_isp_session_data      session_data[CAM_TFE_HW_NUM_MAX];
 
-	struct cam_tfe_csid_hw_caps    tfe_csid_dev_caps[
+	struct cam_tfe_csid_hw_caps      tfe_csid_dev_caps[
 						CAM_TFE_CSID_HW_NUM_MAX];
-	struct cam_tfe_hw_get_hw_cap   tfe_dev_caps[CAM_TFE_HW_NUM_MAX];
-	struct cam_req_mgr_core_workq *workq;
-	struct cam_tfe_hw_mgr_debug    debug_cfg;
+	struct cam_tfe_hw_get_hw_cap     tfe_dev_caps[CAM_TFE_HW_NUM_MAX];
+	struct cam_req_mgr_core_workq   *workq;
+	struct cam_tfe_hw_mgr_debug      debug_cfg;
 	struct cam_isp_hw_path_port_map  path_port_map;
-	bool                           support_consumed_addr;
-	spinlock_t                     ctx_lock;
+	bool                             support_consumed_addr;
+	spinlock_t                       ctx_lock;
 };
 
 /**

+ 15 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -257,6 +257,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_CMD_DUMP_IRQ_DESCRIPTION,
 	CAM_ISP_HW_CMD_GET_SET_PRIM_SOF_TS_ADDR,
 	CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
+	CAM_ISP_HW_CMD_SET_SYNC_HW_IDX,
 	CAM_ISP_HW_CMD_MAX,
 };
 
@@ -588,6 +589,20 @@ struct cam_isp_hw_dump_header {
 	uint32_t  word_size;
 };
 
+/**
+ * struct cam_isp_session_data - Session data
+ *
+ * @Brief:          ISP session or usecase data
+ *
+ * @link_hdl:       Link handle
+ * @is_shdr:        Indicate is usecase is shdr
+ *
+ */
+struct cam_isp_session_data {
+	int32_t   link_hdl;
+	bool      is_shdr;
+};
+
 /**
  * struct cam_isp_hw_intf_data - ISP hw intf data
  *

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe770.h

@@ -153,6 +153,8 @@ static struct cam_tfe_camif_reg_data tfe770_camif_reg_data = {
 	.ai_c_srl_en_shift            = 11,
 	.ds16_c_srl_en_shift          = 10,
 	.ds4_c_srl_en_shift           = 9,
+	.shdr_mode_shift              = 21,
+	.extern_mup_shift             = 22,
 };
 
 static struct cam_tfe_rdi_reg  tfe770_rdi0_reg = {

+ 35 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -31,6 +31,7 @@ static const char drv_name[] = "tfe";
 #define CAM_TFE_CAMIF_IRQ_SOF_DEBUG_CNT_MAX  2
 #define CAM_TFE_DELAY_BW_REDUCTION_NUM_FRAMES 3
 #define CAM_TFE_MAX_OUT_OF_SYNC_ERR_COUNT     3
+#define CAM_TFE_DUAL_TFE_SYNC_SEL_IDX_FACTOR  1
 
 struct cam_tfe_top_common_data {
 	struct cam_hw_soc_info                     *soc_info;
@@ -60,6 +61,7 @@ struct cam_tfe_top_priv {
 	struct timespec64                    error_ts;
 	uint32_t                             top_debug;
 	uint32_t                             last_mup_val;
+	uint32_t                             sync_hw_id;
 	atomic_t                             switch_out_of_sync_cnt;
 };
 
@@ -1765,6 +1767,27 @@ static int cam_tfe_top_bw_control(
 	return rc;
 }
 
+static int cam_tfe_set_sync_hw_idx(
+	struct cam_tfe_hw_core_info *core_info,
+	void *cmd_args, uint32_t arg_size)
+{
+	struct cam_tfe_top_priv              *top_priv;
+	uint32_t                             *hw_idx;
+
+	if (!cmd_args) {
+		CAM_ERR(CAM_ISP, "Error! Invalid input arguments");
+		return -EINVAL;
+	}
+
+	top_priv = (struct cam_tfe_top_priv  *)core_info->top_priv;
+	hw_idx = (uint32_t *)cmd_args;
+	top_priv->sync_hw_id = *hw_idx;
+
+	CAM_DBG(CAM_ISP, "TFE:%d top sync hw idx %d", core_info->core_index,
+		top_priv->sync_hw_id);
+	return 0;
+}
+
 static int cam_tfe_top_get_reg_dump(
 	struct cam_tfe_top_priv *top_priv,
 	void *cmd_args, uint32_t arg_size)
@@ -2398,7 +2421,7 @@ static int cam_tfe_camif_resource_start(
 	if ((rsrc_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE) ||
 		(rsrc_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)) {
 		val |= (1 << rsrc_data->reg_data->dual_tfe_pix_en_shift);
-		val |= ((rsrc_data->dual_tfe_sync_sel + 1) <<
+		val |= ((rsrc_data->dual_tfe_sync_sel + CAM_TFE_DUAL_TFE_SYNC_SEL_IDX_FACTOR) <<
 			rsrc_data->reg_data->dual_tfe_sync_sel_shift);
 	}
 
@@ -2427,11 +2450,14 @@ static int cam_tfe_camif_resource_start(
 	}
 
 	if (rsrc_data->shdr_en) {
-		val |= rsrc_data->core_cfg &
-			(1 << rsrc_data->reg_data->shdr_mode_shift);
-		if (!rsrc_data->is_shdr_master)
-			val |= rsrc_data->core_cfg &
-				(1 << rsrc_data->reg_data->extern_mup_shift);
+		val |= (1 << rsrc_data->reg_data->shdr_mode_shift);
+		val |= (1 << rsrc_data->reg_data->dual_tfe_pix_en_shift);
+		val |= ((top_priv->sync_hw_id + CAM_TFE_DUAL_TFE_SYNC_SEL_IDX_FACTOR) <<
+			rsrc_data->reg_data->dual_tfe_sync_sel_shift);
+		if (!rsrc_data->is_shdr_master) {
+			val |= (1 << rsrc_data->reg_data->extern_mup_shift);
+			val |= (1 << rsrc_data->reg_data->extern_reg_update_shift);
+		}
 	}
 
 	cam_io_w_mb(val, rsrc_data->mem_base +
@@ -3422,6 +3448,9 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 		rc = cam_tfe_bus_get_path_port_map(hw_info->top_hw_info, cmd_args,
 					arg_size);
 		break;
+	case CAM_ISP_HW_CMD_SET_SYNC_HW_IDX:
+		rc = cam_tfe_set_sync_hw_idx(core_info, cmd_args, arg_size);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "TFE:%d Invalid cmd type:%d",
 			core_info->core_index, cmd_type);