Prechádzať zdrojové kódy

msm: camera: isp: Add Blob support for dynamic mode switch

Add blob support to get the mup value for dynamic mode switch
from user space.

CRs-Fixed: 2830502
Change-Id: Ia90d8e38aab69c372d80e6817cc950d741648dcb
Signed-off-by: Chandan Kumar Jha <[email protected]>
Chandan Kumar Jha 4 rokov pred
rodič
commit
9c6e48201c

+ 100 - 26
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -4152,31 +4152,33 @@ static int cam_ife_mgr_acquire_get_unified_structure_v2(
 		in_port->dt[i]        =  in->dt[i];
 	}
 
-	in_port->format           =  in->format;
-	in_port->test_pattern     =  in->test_pattern;
-	in_port->usage_type       =  in->usage_type;
-	in_port->left_start       =  in->left_start;
-	in_port->left_stop        =  in->left_stop;
-	in_port->left_width       =  in->left_width;
-	in_port->right_start      =  in->right_start;
-	in_port->right_stop       =  in->right_stop;
-	in_port->right_width      =  in->right_width;
-	in_port->line_start       =  in->line_start;
-	in_port->line_stop        =  in->line_stop;
-	in_port->height           =  in->height;
-	in_port->pixel_clk        =  in->pixel_clk;
-	in_port->batch_size       =  in->batch_size;
-	in_port->dsp_mode         =  in->dsp_mode;
-	in_port->fe_unpacker_fmt  =  in->format;
-	in_port->hbi_cnt          =  in->hbi_cnt;
-	in_port->cust_node        =  in->cust_node;
-	in_port->horizontal_bin   =  in->horizontal_bin;
-	in_port->qcfa_bin         =  in->qcfa_bin;
-	in_port->num_out_res      =  in->num_out_res;
-	in_port->sfe_in_path_type =  (in->sfe_in_path_type & 0xFFFF);
-	in_port->sfe_ife_enable   =  in->sfe_in_path_type >> 16;
-	in_port->secure_mode      = (in->feature_flag &
-		CAM_ISP_PARAM_FETCH_SECURITY_MODE);
+	in_port->format                   =  in->format;
+	in_port->test_pattern             =  in->test_pattern;
+	in_port->usage_type               =  in->usage_type;
+	in_port->left_start               =  in->left_start;
+	in_port->left_stop                =  in->left_stop;
+	in_port->left_width               =  in->left_width;
+	in_port->right_start              =  in->right_start;
+	in_port->right_stop               =  in->right_stop;
+	in_port->right_width              =  in->right_width;
+	in_port->line_start               =  in->line_start;
+	in_port->line_stop                =  in->line_stop;
+	in_port->height                   =  in->height;
+	in_port->pixel_clk                =  in->pixel_clk;
+	in_port->batch_size               =  in->batch_size;
+	in_port->dsp_mode                 =  in->dsp_mode;
+	in_port->fe_unpacker_fmt          =  in->format;
+	in_port->hbi_cnt                  =  in->hbi_cnt;
+	in_port->cust_node                =  in->cust_node;
+	in_port->horizontal_bin           =  in->horizontal_bin;
+	in_port->qcfa_bin                 =  in->qcfa_bin;
+	in_port->num_out_res              =  in->num_out_res;
+	in_port->sfe_in_path_type         =  (in->sfe_in_path_type & 0xFFFF);
+	in_port->sfe_ife_enable           =  in->sfe_in_path_type >> 16;
+	in_port->secure_mode              = (in->feature_flag &
+		                           CAM_ISP_PARAM_FETCH_SECURITY_MODE);
+	in_port->dynamic_sensor_switch_en = (in->feature_flag &
+		                           CAM_ISP_DYNAMIC_SENOR_SWITCH_EN);
 
 	in_port->data = kcalloc(in->num_out_res,
 		sizeof(struct cam_isp_out_port_generic_info),
@@ -5180,7 +5182,7 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 			return rc;
 		}
 
-		if (cfg->init_packet ||
+		if (cfg->init_packet || hw_update_data->mup_en ||
 			(ctx->custom_config & CAM_IFE_CUSTOM_CFG_SW_SYNC_ON)) {
 			rem_jiffies = wait_for_completion_timeout(
 				&ctx->config_done_complete,
@@ -5197,6 +5199,7 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 				CAM_DBG(CAM_ISP,
 					"config done Success for req_id=%llu ctx_index %d",
 					cfg->request_id, ctx->ctx_index);
+			hw_update_data->mup_en = false;
 		}
 	} else {
 		CAM_ERR(CAM_ISP, "No commands to config");
@@ -6649,6 +6652,60 @@ static int cam_isp_blob_hfr_update(
 	return rc;
 }
 
+static int cam_isp_blob_csid_mup_update(
+	uint32_t                               blob_type,
+	struct cam_isp_generic_blob_info      *blob_info,
+	struct cam_isp_mode_switch_info       *mup_config,
+	struct cam_hw_prepare_update_args     *prepare)
+{
+	struct cam_ife_hw_mgr_ctx             *ctx = NULL;
+	struct cam_isp_hw_mgr_res             *hw_mgr_res;
+	struct cam_hw_intf                    *hw_intf;
+	struct cam_ife_csid_mup_update_args    csid_mup_upd_args;
+	struct cam_isp_prepare_hw_update_data *prepare_hw_data;
+	uint64_t                               mup_val = 0;
+	int                                    rc = -EINVAL;
+	uint32_t                               i;
+
+	ctx = prepare->ctxt_to_hw_map;
+
+	CAM_DBG(CAM_ISP,
+		"csid mup value=%u", mup_config->mup);
+
+	prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *)
+			prepare->priv;
+	prepare_hw_data->mup_en = true;
+
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			mup_val = 0;
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+			if (i == CAM_ISP_HW_SPLIT_RIGHT)
+				continue;
+			mup_val = mup_config->mup;
+			hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+			if (hw_intf && hw_intf->hw_ops.process_cmd) {
+				csid_mup_upd_args.mup = mup_val;
+				CAM_DBG(CAM_ISP, "i= %d mup=%llu\n ctx %d",
+				i, csid_mup_upd_args.mup, ctx->ctx_index);
+
+				rc = hw_intf->hw_ops.process_cmd(
+					hw_intf->hw_priv,
+					CAM_ISP_HW_CMD_CSID_MUP_UPDATE,
+					&csid_mup_upd_args,
+					sizeof(
+					struct cam_ife_csid_mup_update_args));
+				if (rc)
+					CAM_ERR(CAM_ISP, "MUP Update failed");
+			} else
+				CAM_ERR(CAM_ISP, "NULL hw_intf!");
+		}
+	}
+
+	return rc;
+}
+
 static int cam_isp_blob_csid_clock_update(
 	uint32_t                               blob_type,
 	struct cam_isp_generic_blob_info      *blob_info,
@@ -8206,6 +8263,23 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
 	case CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG:
 	case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG:
 	case CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG:
+	case CAM_ISP_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH: {
+		struct cam_isp_mode_switch_info    *mup_config;
+
+		if (blob_size < sizeof(struct cam_isp_mode_switch_info)) {
+			CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+				blob_size,
+				sizeof(struct cam_isp_mode_switch_info));
+			return -EINVAL;
+		}
+
+		mup_config = (struct cam_isp_mode_switch_info *)blob_data;
+
+		rc = cam_isp_blob_csid_mup_update(blob_type, blob_info,
+			mup_config, prepare);
+		if (rc)
+			CAM_ERR(CAM_ISP, "MUP Update Failed");
+	}
 		break;
 	default:
 		CAM_WARN(CAM_ISP, "Invalid blob type: %u", blob_type);

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -132,6 +132,7 @@ struct cam_isp_bw_config_internal {
  * @reg_dump_buf_desc:     cmd buffer descriptors for reg dump
  * @num_reg_dump_buf:      Count of descriptors in reg_dump_buf_desc
  * @packet                 CSL packet from user mode driver
+ * @mup_en                 Flag if dynamic sensor switch is enabled
  *
  */
 struct cam_isp_prepare_hw_update_data {
@@ -148,6 +149,7 @@ struct cam_isp_prepare_hw_update_data {
 						CAM_REG_DUMP_MAX_BUF_ENTRIES];
 	uint32_t                              num_reg_dump_buf;
 	struct cam_packet                     *packet;
+	bool                                  mup_en;
 };
 
 

+ 10 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h

@@ -299,12 +299,14 @@ struct cam_ife_csid_cid_data {
 /*
  * struct cam_ife_csid_hw_flags: place holder for flags
  *
- * @phy_sel:       selected phy
- * @lane_type:     type of lane selected
- * @lane_num:      number of lanes
- * @lane_cfg:      lane configuration
- * @tpg_mux_sel:   TPG mux sel
- * @tpg_num_sel:   TPG num sel
+ * @phy_sel:                  Selected phy
+ * @lane_type:                type of lane selected
+ * @lane_num:                 number of lanes
+ * @lane_cfg:                 lane configuration
+ * @tpg_mux_sel:              TPG mux sel
+ * @tpg_num_sel:              TPG num sel
+ * @dynamic_senso_switch_en:  Flag if dynamic sensor switch is enabled
+ * @mup:                      Mode Update bit. 0 for odd vc, 1 for even VC
  */
 struct cam_ife_csid_rx_cfg  {
 	uint32_t                        phy_sel;
@@ -313,6 +315,8 @@ struct cam_ife_csid_rx_cfg  {
 	uint32_t                        lane_cfg;
 	uint32_t                        tpg_mux_sel;
 	uint32_t                        tpg_num_sel;
+	uint32_t                        dynamic_sensor_switch_en;
+	uint32_t                        mup;
 };
 
 int cam_ife_csid_is_pix_res_format_supported(

+ 28 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -1313,6 +1313,8 @@ static int cam_ife_csid_hw_ver2_config_rx(
 	csid_hw->rx_cfg.lane_num =
 		reserve->in_port->lane_num;
 	csid_hw->res_type = reserve->in_port->res_type;
+	csid_hw->rx_cfg.dynamic_sensor_switch_en =
+		reserve->in_port->dynamic_sensor_switch_en;
 
 	switch (reserve->in_port->res_type) {
 	case CAM_ISP_IFE_IN_RES_TPG:
@@ -2562,6 +2564,8 @@ static int cam_ife_csid_ver2_enable_csi2(struct cam_ife_csid_ver2_hw *csid_hw)
 	/*Configure Rx cfg1*/
 	val = 1 << csi2_reg->misr_enable_shift_val;
 	val |= 1 << csi2_reg->ecc_correction_shift_en;
+	val |= (rx_cfg->dynamic_sensor_switch_en
+			<< csi2_reg->dyn_sensor_switch_shift_en);
 
 	vc_full_width = cam_ife_csid_is_vc_full_width(csid_hw->cid_data);
 
@@ -3311,8 +3315,8 @@ static int cam_ife_csid_ver2_reg_update(
 	reg_val_pair[0] = csid_reg->cmn_reg->rup_aup_cmd_addr;
 	reg_val_pair[1] = rup_aup_mask;
 
-	if (rup_args->is_mup_update)
-		reg_val_pair[1] |= 1 << csid_reg->cmn_reg->mup_shift_val;
+	reg_val_pair[1] |= csid_hw->rx_cfg.mup <<
+			csid_reg->cmn_reg->mup_shift_val;
 
 	CAM_DBG(CAM_ISP, "CSID:%d reg_update_cmd 0x%X offset 0x%X",
 		csid_hw->hw_intf->hw_idx,
@@ -3540,6 +3544,25 @@ static int cam_ife_csid_ver2_print_hbi_vbi(
 	return 0;
 }
 
+static int cam_ife_csid_ver2_set_mup_config(
+	struct cam_ife_csid_ver2_hw          *csid_hw,
+	void *cmd_args)
+{
+	struct cam_ife_csid_mup_update_args *mup_update = NULL;
+
+	if (!csid_hw)
+		return -EINVAL;
+
+	mup_update =
+		(struct cam_ife_csid_mup_update_args *)cmd_args;
+
+	csid_hw->rx_cfg.mup = mup_update->mup;
+	CAM_INFO(CAM_ISP, "CSID[%u] MUP %u", csid_hw->hw_intf->hw_idx,
+		csid_hw->rx_cfg.mup);
+
+	return 0;
+}
+
 static int cam_ife_csid_ver2_set_csid_clock(
 	struct cam_ife_csid_ver2_hw          *csid_hw,
 	void *cmd_args)
@@ -3721,6 +3744,9 @@ static int cam_ife_csid_ver2_process_cmd(void *hw_priv,
 		rc = cam_ife_csid_ver2_program_offline_go_cmd(
 			csid_hw, cmd_args, arg_size);
 		break;
+	case CAM_ISP_HW_CMD_CSID_MUP_UPDATE:
+		rc = cam_ife_csid_ver2_set_mup_config(csid_hw, cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h

@@ -593,6 +593,7 @@ struct cam_ife_csid_ver2_reg_info {
  * @reset_irq_handle:         Reset irq handle
  * @buf_done_irq_handle:      Buf done irq handle
  * @sync_mode:                Master/Slave modes
+ * @mup:                      MUP for incoming VC of next frame
  *
  */
 struct cam_ife_csid_ver2_hw {
@@ -636,6 +637,7 @@ struct cam_ife_csid_ver2_hw {
 	int                                    reset_irq_handle;
 	int                                    buf_done_irq_handle;
 	enum cam_isp_hw_sync_mode              sync_mode;
+	uint32_t                               mup;
 };
 
 int cam_ife_csid_hw_ver2_init(struct cam_hw_intf  *csid_hw_intf,

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

@@ -129,6 +129,7 @@ struct cam_isp_in_port_generic_info {
 	uint32_t                        sfe_in_path_type;
 	uint32_t                        sfe_ife_enable;
 	uint32_t                        secure_mode;
+	uint32_t                        dynamic_sensor_switch_en;
 	struct cam_isp_out_port_generic_info    *data;
 };
 
@@ -373,4 +374,13 @@ struct cam_ife_csid_offline_cmd_update_args {
 	struct cam_isp_hw_cmd_buf_update  cmd;
 	struct cam_isp_resource_node     *res;
 };
+
+/*
+ * struct cam_ife_csid_mup_update_args:
+ *
+ * @mup:                MUP for incoming VC of next frame
+ */
+struct cam_ife_csid_mup_update_args {
+	uint32_t                           mup;
+};
 #endif /* _CAM_CSID_HW_INTF_H_ */

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

@@ -146,6 +146,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_IFE_CSID_TOP_CONFIG,
 	CAM_IFE_CSID_PROGRAM_OFFLINE_CMD,
 	CAM_IFE_CSID_SET_DUAL_SYNC_CONFIG,
+	CAM_ISP_HW_CMD_CSID_MUP_UPDATE,
 	CAM_ISP_HW_CMD_MAX,
 };