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 <quic_dharshar@quicinc.com>
This commit is contained in:
Dharmender Sharma 2023-12-12 20:09:20 +05:30
parent 7d82a270a3
commit 1e193cd952
3 changed files with 87 additions and 0 deletions

View File

@ -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_ */

View File

@ -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) {

View File

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