From 1e193cd952f1d82dbe0417172ae43a16ac85bc38 Mon Sep 17 00:00:00 2001 From: Dharmender Sharma Date: Tue, 12 Dec 2023 20:09:20 +0530 Subject: [PATCH] msm: camera: csid: Add fuse support for MP limit This change limit the resolution for the single camera based on fuse. Acquire will fail in case width is greater than the supported width. CRs-Fixed: 3679491 Change-Id: I4f3e8dfdbe80aee994ca66f12bbbcdc7cda77676 Signed-off-by: Dharmender Sharma --- .../isp_hw/ife_csid_hw/cam_ife_csid860.h | 3 + .../isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c | 79 +++++++++++++++++++ .../isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h | 5 ++ 3 files changed, 87 insertions(+) diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid860.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid860.h index 8aa0da0b27..5e517ae7f3 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid860.h +++ b/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_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c index 18fa60f773..22e6d189ea 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c +++ b/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) { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h index 956bf42f65..ac30fa3ec7 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h +++ b/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; }; /*