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; }; /*