Browse Source

Merge "msm: camera: csid: Add fuse support for MP limit" into camera-kernel.lnx.7.0

Camera Software Integration 1 năm trước cách đây
mục cha
commit
0b8bffd664

+ 3 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid860.h

@@ -81,6 +81,9 @@ static struct cam_ife_csid_ver2_reg_info cam_ife_csid_860_reg_info = {
 	.num_path_err_irqs  = ARRAY_SIZE(cam_ife_csid_880_path_irq_desc),
 	.num_top_regs       = 1,
 	.num_rx_regs        = 1,
+	.width_fuse_max_val = 1,
+	.fused_max_dualife_width = {7296, 5344, UINT_MAX},
+	.fused_max_width = {7296, 7296, UINT_MAX},
 };
 
 #endif /*_CAM_IFE_CSID_860_H_ */

+ 79 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -3215,6 +3215,82 @@ end:
 	return rc;
 }
 
+static bool cam_ife_csid_ver2_is_width_valid_by_fuse(
+	struct cam_csid_hw_reserve_resource_args  *reserve,
+	struct cam_ife_csid_ver2_hw *csid_hw,
+	uint32_t width)
+{
+	struct cam_ife_csid_ver2_reg_info *csid_reg;
+	uint32_t fuse_val = UINT_MAX;
+
+	csid_reg = (struct cam_ife_csid_ver2_reg_info *)
+		csid_hw->core_info->csid_reg;
+
+	cam_cpas_is_feature_supported(CAM_CPAS_MP_LIMIT_FUSE, CAM_CPAS_HW_IDX_ANY, &fuse_val);
+	if (fuse_val == UINT_MAX) {
+		CAM_DBG(CAM_ISP, "CSID[%u] MP limit fuse not present",
+			csid_hw->hw_intf->hw_idx);
+		return true;
+	}
+
+	if ((fuse_val > csid_reg->width_fuse_max_val) ||
+		(fuse_val >= CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX)) {
+		CAM_ERR(CAM_ISP, "Invalid fuse value %u", fuse_val);
+		return false;
+	}
+
+	if (((reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) ||
+		(reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER)) &&
+		(width > csid_reg->fused_max_dualife_width[fuse_val])) {
+		CAM_ERR(CAM_ISP,
+			"CSID[%u] Resolution not supported required_width dualife: %d max_supported_width: %d",
+			csid_hw->hw_intf->hw_idx,
+			width, csid_reg->fused_max_dualife_width[fuse_val]);
+		return false;
+
+	} else if (width > csid_reg->fused_max_width[fuse_val]) {
+		CAM_ERR(CAM_ISP,
+			"CSID[%u] Resolution not supported required_width: %d max_supported_width: %d",
+			csid_hw->hw_intf->hw_idx,
+			width, csid_reg->fused_max_width[fuse_val]);
+		return false;
+	}
+
+	return true;
+}
+
+bool cam_ife_csid_ver2_is_width_valid(
+	struct cam_csid_hw_reserve_resource_args  *reserve,
+	struct cam_ife_csid_ver2_hw *csid_hw)
+{
+	uint32_t width = 0;
+	struct cam_csid_soc_private *soc_private;
+
+	soc_private = (struct cam_csid_soc_private *)csid_hw->hw_info->soc_info.soc_private;
+
+	if ((reserve->res_id != CAM_IFE_PIX_PATH_RES_IPP) || soc_private->is_ife_csid_lite)
+		return true;
+
+	if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
+		reserve->sync_mode == CAM_ISP_HW_SYNC_NONE)
+		width = reserve->in_port->left_stop -
+			reserve->in_port->left_start + 1;
+	else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
+		width = reserve->in_port->right_stop -
+			reserve->in_port->right_start + 1;
+
+	if (reserve->in_port->horizontal_bin || reserve->in_port->qcfa_bin)
+		width /= 2;
+
+	if (!cam_ife_csid_ver2_is_width_valid_by_fuse(reserve, csid_hw, width)) {
+		CAM_ERR(CAM_ISP, "CSID[%u] width limited by fuse",
+			csid_hw->hw_intf->hw_idx);
+		return false;
+	}
+
+	return true;
+}
+
 static int cam_ife_csid_ver2_in_port_validate(
 	struct cam_csid_hw_reserve_resource_args  *reserve,
 	struct cam_ife_csid_ver2_hw     *csid_hw)
@@ -3229,6 +3305,9 @@ static int cam_ife_csid_ver2_in_port_validate(
 			goto err;
 	}
 
+	if (!cam_ife_csid_ver2_is_width_valid(reserve, csid_hw))
+		goto err;
+
 	if (csid_hw->counters.csi2_reserve_cnt) {
 
 		if (csid_hw->token != reserve->cb_priv) {

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

@@ -742,6 +742,11 @@ struct cam_ife_csid_ver2_reg_info {
 	const uint32_t                                    num_path_err_irqs;
 	const uint32_t                                    num_top_regs;
 	const uint32_t                                    num_rx_regs;
+	const uint32_t                                    fused_max_dualife_width[
+		   CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX];
+	const uint32_t                                    fused_max_width[
+		   CAM_IFE_CSID_WIDTH_FUSE_VAL_MAX];
+	const uint32_t                                    width_fuse_max_val;
 };
 
 /*