From 7a9cd0d210436398148dfa756b65795f4cfe847b Mon Sep 17 00:00:00 2001 From: Ayush Kumar Date: Fri, 4 Nov 2022 18:15:38 +0530 Subject: [PATCH] msm: camera: tfe: Add MUP support for TFE HW This change add support for MUP in TFE HW. Also enable interrupt if case of mup mismatch and add error bit in header file to remove hardcoded values. CRs-Fixed: 3350436 Change-Id: I5556fa3f8ab47fea16fe92007303eb68a5b80943 Signed-off-by: Ayush Kumar --- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 2 +- drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c | 33 +++- .../hw_utils/cam_isp_packet_parser.c | 11 +- .../hw_utils/include/cam_isp_packet_parser.h | 4 +- .../isp_hw_mgr/include/cam_isp_hw_mgr_intf.h | 15 ++ .../isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h | 17 +- .../isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h | 17 +- .../isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c | 148 ++++++++++++------ .../isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h | 21 +++ include/uapi/camera/media/cam_tfe.h | 1 + 10 files changed, 208 insertions(+), 61 deletions(-) diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 5d425caf55..0c93b61cbd 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -12791,7 +12791,7 @@ static int cam_ife_mgr_isp_add_reg_update(struct cam_ife_hw_mgr_ctx *ctx, rc = cam_isp_add_reg_update(prepare, &ctx->res_list_ife_src, ctx->base[i].idx, kmd_buf, - !ctx->flags.internal_cdm); + !ctx->flags.internal_cdm, NULL); if (rc) { CAM_ERR(CAM_ISP, diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c index a378c0a43a..2dc355c75a 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c @@ -2923,7 +2923,7 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv, ctx->last_submit_bl_cmd.cmd[i].input_len = cdm_cmd->cmd[i].len; } - if (!cfg->init_packet) + if (!cfg->init_packet && !hw_update_data->mup_en) goto end; for (i = 0; i < CAM_TFE_HW_CONFIG_WAIT_MAX_TRY; i++) { @@ -4380,6 +4380,30 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "BW limit update failed for TFE rc: %d", rc); } break; + case CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH: { + struct cam_isp_mode_switch_info *mup_config; + struct cam_isp_prepare_hw_update_data *prepare_hw_data; + + 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; + CAM_DBG(CAM_ISP, + "Ctx id %d request id %lld csid mup value=%u num_exposures=%d", + tfe_mgr_ctx->ctx_index, prepare->packet->header.request_id, + mup_config->mup, mup_config->num_expoures); + + prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)prepare->priv; + + prepare_hw_data->mup_en = true; + prepare_hw_data->mup_val = mup_config->mup; + prepare_hw_data->num_exp = mup_config->num_expoures; + } + break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); break; @@ -4678,6 +4702,7 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv, struct cam_isp_change_base_args change_base_info = {0}; struct cam_isp_check_io_cfg_for_scratch check_for_scratch = {0}; struct cam_isp_io_buf_info io_buf_info = {0}; + struct cam_isp_mode_switch_data mup_config; if (!hw_mgr_priv || !prepare_hw_update_args) { CAM_ERR(CAM_ISP, "Invalid args"); @@ -4840,9 +4865,13 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv, goto end; } + mup_config.mup = prepare_hw_data->mup_val; + mup_config.num_expoures = prepare_hw_data->num_exp; + mup_config.mup_en = prepare_hw_data->mup_en; + /*Add reg update */ rc = cam_isp_add_reg_update(prepare, &ctx->res_list_tfe_in, - ctx->base[i].idx, &prepare_hw_data->kmd_cmd_buff_info, false); + ctx->base[i].idx, &prepare_hw_data->kmd_cmd_buff_info, false, &mup_config); if (rc) { CAM_ERR(CAM_ISP, "Add Reg_update cmd Failed i=%d, idx=%d, rc=%d", diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index a07fc9a3cd..f422217c33 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -1242,12 +1242,13 @@ int cam_isp_add_reg_update( struct list_head *res_list_isp_src, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info, - bool combine) + bool combine, + void *priv_data) { int rc = -EINVAL; - struct cam_isp_resource_node *res; - struct cam_isp_hw_mgr_res *hw_mgr_res; - struct cam_isp_hw_get_cmd_update get_regup; + struct cam_isp_resource_node *res; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_isp_hw_get_cmd_update get_regup; uint32_t kmd_buf_remain_size, i, reg_update_size; /* Max one hw entries required for each base */ @@ -1293,6 +1294,8 @@ int cam_isp_add_reg_update( get_regup.cmd_type = CAM_ISP_HW_CMD_GET_REG_UPDATE; get_regup.res = res; + get_regup.data = priv_data; + rc = res->hw_intf->hw_ops.process_cmd( res->hw_intf->hw_priv, CAM_ISP_HW_CMD_GET_REG_UPDATE, &get_regup, diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h index 8fdf7148c8..f0ceb18909 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h @@ -290,6 +290,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info); * @base_idx: Base or dev index of the IFE/VFE HW instance * @kmd_buf_info: Kmd buffer to store the change base command * @combine: Indicate whether combine with prev update entry + * @priv_data: private data for HW driver * @return: 0 for success * -EINVAL for Fail */ @@ -298,7 +299,8 @@ int cam_isp_add_reg_update( struct list_head *res_list_isp_src, uint32_t base_idx, struct cam_kmd_buf_info *kmd_buf_info, - bool combine); + bool combine, + void *priv_data); /* * cam_isp_add_comp_wait() diff --git a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h index 8637c50dd0..ddc081ddb2 100644 --- a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h @@ -546,6 +546,21 @@ struct cam_isp_lcr_rdi_cfg_args { bool is_init; }; + +/** + * struct cam_isp_mode_switch_data - isp hardware mode update arguments + * + * @mup Mup value + * @num_expoures Number of exposures + * @mup_en Flag to indicate if mup is enable + * + */ +struct cam_isp_mode_switch_data { + uint32_t mup; + uint32_t num_expoures; + bool mup_en; +}; + /** * cam_isp_hw_mgr_init() * diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h index 19982cb03e..a9190adc70 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h @@ -53,6 +53,22 @@ static struct cam_tfe_top_reg_offset_common tfe530_top_commong_reg = { .diag_neq_hbi_shift = 14, .diag_sensor_hbi_mask = 0x3FFF, .serializer_supported = false, + .pp_camif_violation_bit = BIT(0), + .pp_violation_bit = BIT(1), + .rdi0_camif_violation_bit = BIT(2), + .rdi1_camif_violation_bit = BIT(3), + .rdi2_camif_violation_bit = BIT(4), + .diag_violation_bit = BIT(5), + .pp_frame_drop_bit = BIT(8), + .rdi0_frame_drop_bit = BIT(9), + .rdi1_frame_drop_bit = BIT(10), + .rdi2_frame_drop_bit = BIT(11), + .pp_overflow_bit = BIT(16), + .rdi0_overflow_bit = BIT(17), + .rdi1_overflow_bit = BIT(18), + .rdi2_overflow_bit = BIT(19), + .mup_shift_val = 0, + .mup_supported = false, }; static struct cam_tfe_camif_reg tfe530_camif_reg = { @@ -220,7 +236,6 @@ static struct cam_tfe_rdi_reg_data tfe530_rdi2_reg_data = { .enable_diagnostic_hw = 0x1, .diag_sensor_sel = 0x3, .diag_sensor_shift = 0x1, - }; static struct cam_tfe_clc_hw_status tfe530_clc_hw_info[CAM_TFE_MAX_CLC] = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h index 9b60c47491..c948a82001 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h @@ -66,6 +66,22 @@ static struct cam_tfe_top_reg_offset_common tfe640_top_commong_reg = { .diag_neq_hbi_shift = 14, .diag_sensor_hbi_mask = 0x3FFF, .serializer_supported = true, + .pp_camif_violation_bit = BIT(0), + .pp_violation_bit = BIT(1), + .rdi0_camif_violation_bit = BIT(2), + .rdi1_camif_violation_bit = BIT(3), + .rdi2_camif_violation_bit = BIT(4), + .diag_violation_bit = BIT(5), + .pp_frame_drop_bit = BIT(8), + .rdi0_frame_drop_bit = BIT(9), + .rdi1_frame_drop_bit = BIT(10), + .rdi2_frame_drop_bit = BIT(11), + .pp_overflow_bit = BIT(16), + .rdi0_overflow_bit = BIT(17), + .rdi1_overflow_bit = BIT(18), + .rdi2_overflow_bit = BIT(19), + .mup_shift_val = 0, + .mup_supported = false, }; static struct cam_tfe_camif_reg tfe640_camif_reg = { @@ -235,7 +251,6 @@ static struct cam_tfe_rdi_reg_data tfe640_rdi2_reg_data = { .enable_diagnostic_hw = 0x1, .diag_sensor_sel = 0x3, .diag_sensor_shift = 0x1, - }; static struct cam_tfe_clc_hw_status tfe640_clc_hw_info[CAM_TFE_MAX_CLC] = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c index b620397cad..92c968e11a 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c @@ -58,6 +58,7 @@ struct cam_tfe_top_priv { struct timespec64 eof_ts; struct timespec64 error_ts; uint32_t top_debug; + uint32_t last_mup_val; }; struct cam_tfe_camif_data { @@ -319,6 +320,7 @@ static void cam_tfe_log_error_irq_status( struct cam_tfe_soc_private *soc_private; struct cam_tfe_clc_hw_status *clc_hw_status; + struct cam_tfe_top_reg_offset_common *common_reg; struct timespec64 ts; uint32_t i, val_0, val_1, val_2, val_3; @@ -328,6 +330,7 @@ static void cam_tfe_log_error_irq_status( mem_base = top_priv->common_data.soc_info->reg_map[0].mem_base; soc_info = top_priv->common_data.soc_info; soc_private = top_priv->common_data.soc_info->soc_private; + common_reg = top_priv->common_data.common_reg; CAM_INFO(CAM_ISP, "current monotonic timestamp:[%lld.%06lld]", ts.tv_sec, ts.tv_nsec/1000); @@ -346,26 +349,22 @@ static void cam_tfe_log_error_irq_status( evt_payload->irq_reg_val[0], evt_payload->irq_reg_val[1], evt_payload->irq_reg_val[2]); - for (i = 0; i < top_priv->common_data.common_reg->num_debug_reg; i++) { + for (i = 0; i < common_reg->num_debug_reg; i++) { val_0 = cam_io_r(mem_base + - top_priv->common_data.common_reg->debug_reg[i]); - CAM_INFO(CAM_ISP, "Top debug [%d]:0x%x", i, val_0); + common_reg->debug_reg[i]); + CAM_INFO(CAM_ISP, "Top debug [i]:0x%x", i, val_0); } cam_cpas_dump_camnoc_buff_fill_info(soc_private->cpas_handle); - for (i = 0; i < top_priv->common_data.common_reg->num_perf_cfg; i++) { - val_0 = cam_io_r(mem_base + - top_priv->common_data.common_reg->perf_cfg[i].perf_pixel_count); + for (i = 0; i < common_reg->num_perf_cfg; i++) { + val_0 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_pixel_count); - val_1 = cam_io_r(mem_base + - top_priv->common_data.common_reg->perf_cfg[i].perf_line_count); + val_1 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_line_count); - val_2 = cam_io_r(mem_base + - top_priv->common_data.common_reg->perf_cfg[i].perf_stall_count); + val_2 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_stall_count); - val_3 = cam_io_r(mem_base + - top_priv->common_data.common_reg->perf_cfg[i].perf_always_count); + val_3 = cam_io_r(mem_base + common_reg->perf_cfg[i].perf_always_count); CAM_INFO(CAM_ISP, "Top perf cnt [%d] pix:0x%x line:0x%x stall:0x%x always:0x%x", @@ -388,54 +387,65 @@ static void cam_tfe_log_error_irq_status( /* Check the overflow errors */ if (evt_payload->irq_reg_val[0] & hw_info->error_irq_mask[0]) { - if (evt_payload->irq_reg_val[0] & BIT(8)) - CAM_INFO(CAM_ISP, "PP_FRAME_DROP"); + if (evt_payload->irq_reg_val[0] & common_reg->pp_frame_drop_bit) + CAM_INFO(CAM_ISP, "TFE %d PP_FRAME_DROP", core_info->core_index); - if (evt_payload->irq_reg_val[0] & BIT(9)) - CAM_INFO(CAM_ISP, "RDI0_FRAME_DROP"); + if (evt_payload->irq_reg_val[0] & common_reg->rdi0_frame_drop_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI0_FRAME_DROP", core_info->core_index); - if (evt_payload->irq_reg_val[0] & BIT(10)) - CAM_INFO(CAM_ISP, "RDI1_FRAME_DROP"); + if (evt_payload->irq_reg_val[0] & common_reg->rdi1_frame_drop_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI1_FRAME_DROP", core_info->core_index); - if (evt_payload->irq_reg_val[0] & BIT(11)) - CAM_INFO(CAM_ISP, "RDI2_FRAME_DROP"); + if (evt_payload->irq_reg_val[0] & common_reg->rdi2_frame_drop_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI2_FRAME_DROP", core_info->core_index); - if (evt_payload->irq_reg_val[0] & BIT(16)) - CAM_INFO(CAM_ISP, "PP_OVERFLOW"); + if (evt_payload->irq_reg_val[0] & common_reg->pp_overflow_bit) + CAM_INFO(CAM_ISP, "TFE %d PP_OVERFLOW", core_info->core_index); - if (evt_payload->irq_reg_val[0] & BIT(17)) - CAM_INFO(CAM_ISP, "RDI0_OVERFLOW"); + if (evt_payload->irq_reg_val[0] & common_reg->rdi0_overflow_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI0_OVERFLOW", core_info->core_index); - if (evt_payload->irq_reg_val[0] & BIT(18)) - CAM_INFO(CAM_ISP, "RDI1_OVERFLOW"); + if (evt_payload->irq_reg_val[0] & common_reg->rdi1_overflow_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI1_OVERFLOW", core_info->core_index); - if (evt_payload->irq_reg_val[0] & BIT(19)) - CAM_INFO(CAM_ISP, "RDI2_OVERFLOW"); + if (evt_payload->irq_reg_val[0] & common_reg->rdi2_overflow_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI2_OVERFLOW", core_info->core_index); + + if (evt_payload->irq_reg_val[0] & common_reg->out_of_sync_frame_drop_bit) { + CAM_INFO(CAM_ISP, + "TFE %d SENSOR_SWITCH_OUT_OF_SYNC_FRAME_DROP mup: last %d curr %d", + core_info->core_index, top_priv->last_mup_val, + ((cam_io_r(mem_base + common_reg->reg_update_cmd) >> 8) & 1)); + } } /* Check the violation errors */ if (evt_payload->irq_reg_val[2] & hw_info->error_irq_mask[2]) { - if (evt_payload->irq_reg_val[2] & BIT(0)) - CAM_INFO(CAM_ISP, "PP_CAMIF_VIOLATION"); + if (evt_payload->irq_reg_val[2] & common_reg->pp_camif_violation_bit) + CAM_INFO(CAM_ISP, "TFE %d PP_CAMIF_VIOLATION", core_info->core_index); - if (evt_payload->irq_reg_val[2] & BIT(1)) - CAM_INFO(CAM_ISP, "PP_VIOLATION"); + if (evt_payload->irq_reg_val[2] & common_reg->pp_violation_bit) + CAM_INFO(CAM_ISP, "TFE %d PP_VIOLATION", core_info->core_index); - if (evt_payload->irq_reg_val[2] & BIT(2)) - CAM_INFO(CAM_ISP, "RDI0_CAMIF_VIOLATION"); + if (evt_payload->irq_reg_val[2] & common_reg->rdi0_camif_violation_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI0_CAMIF_VIOLATION", core_info->core_index); - if (evt_payload->irq_reg_val[2] & BIT(3)) - CAM_INFO(CAM_ISP, "RDI1_CAMIF_VIOLATION"); + if (evt_payload->irq_reg_val[2] & common_reg->rdi1_camif_violation_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI1_CAMIF_VIOLATION", core_info->core_index); - if (evt_payload->irq_reg_val[2] & BIT(4)) - CAM_INFO(CAM_ISP, "RDI2_CAMIF_VIOLATION"); + if (evt_payload->irq_reg_val[2] & common_reg->rdi2_camif_violation_bit) + CAM_INFO(CAM_ISP, "TFE %d RDI2_CAMIF_VIOLATION", core_info->core_index); - if (evt_payload->irq_reg_val[2] & BIT(5)) - CAM_INFO(CAM_ISP, "DIAG_VIOLATION"); + if (evt_payload->irq_reg_val[2] & common_reg->diag_violation_bit) + CAM_INFO(CAM_ISP, "TFE %d DIAG_VIOLATION", core_info->core_index); - val_0 = cam_io_r(mem_base + - top_priv->common_data.common_reg->violation_status); - CAM_INFO(CAM_ISP, "TOP Violation status:0x%x", val_0); + if (evt_payload->irq_reg_val[2] & common_reg->dyamanic_switch_violation_bit) + CAM_INFO(CAM_ISP, + "TFE %d DYNAMIC_SHDR_MODE_SWITCH_VIOLATION mup val %d", + core_info->core_index, top_priv->last_mup_val); + + val_0 = cam_io_r(mem_base + common_reg->violation_status); + CAM_INFO(CAM_ISP, "TFE %d TOP Violation status:0x%x", core_info->core_index, val_0); } core_info->tfe_bus->bottom_half_handler( @@ -1256,24 +1266,46 @@ static int cam_tfe_top_get_base(struct cam_tfe_top_priv *top_priv, return 0; } +static int cam_tfe_top_update_mup( + struct cam_tfe_top_priv *top_priv, + struct cam_isp_mode_switch_data *mup_config) +{ + uint32_t mup_val = 0, final_mup = 0; + struct cam_tfe_top_reg_offset_common *common_reg; + + mup_val = mup_config->mup; + common_reg = top_priv->common_data.common_reg; + + if (mup_config->mup_en) { + final_mup = (mup_val << common_reg->mup_shift_val); + top_priv->last_mup_val = mup_val; + } else { + final_mup = (top_priv->last_mup_val << common_reg->mup_shift_val); + } + + return final_mup; +} + static int cam_tfe_top_get_reg_update( struct cam_tfe_top_priv *top_priv, void *cmd_args, uint32_t arg_size) { - uint32_t size = 0; - uint32_t reg_val_pair[2]; - struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args; - struct cam_cdm_utils_ops *cdm_util_ops = NULL; - struct cam_tfe_camif_data *camif_rsrc_data = NULL; - struct cam_tfe_rdi_data *rdi_rsrc_data = NULL; - struct cam_isp_resource_node *in_res; + uint32_t size = 0; + uint32_t reg_val_pair[2]; + struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args; + struct cam_cdm_utils_ops *cdm_util_ops = NULL; + struct cam_tfe_camif_data *camif_rsrc_data = NULL; + struct cam_tfe_rdi_data *rdi_rsrc_data = NULL; + struct cam_isp_resource_node *in_res; + struct cam_isp_mode_switch_data *mup_config = NULL; + struct cam_tfe_top_reg_offset_common *common_reg; if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) { CAM_ERR(CAM_ISP, "Invalid cmd size"); return -EINVAL; } - if (!cdm_args || !cdm_args->res) { + if (!cdm_args || !cdm_args->res || !top_priv) { CAM_ERR(CAM_ISP, "Invalid args"); return -EINVAL; } @@ -1306,6 +1338,19 @@ static int cam_tfe_top_get_reg_update( reg_val_pair[1] = rdi_rsrc_data->reg_data->reg_update_cmd_data; } + common_reg = top_priv->common_data.common_reg; + if (common_reg->mup_supported) { + if (!cdm_args->data) { + CAM_ERR(CAM_ISP, "invalid data (NULL), TFE: %d mup_supported :%d", + top_priv->common_data.hw_intf->hw_idx , cdm_args->data); + return -EINVAL; + } + mup_config = (struct cam_isp_mode_switch_data *) cdm_args->data; + reg_val_pair[1] |= cam_tfe_top_update_mup(top_priv, mup_config); + CAM_DBG(CAM_ISP, "MUP supported, TFE: %d final reg_up cmd: 0x%x", + top_priv->common_data.hw_intf->hw_idx, reg_val_pair[1]); + } + cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr, 1, reg_val_pair); @@ -2190,6 +2235,7 @@ int cam_tfe_top_start(struct cam_tfe_hw_core_info *core_info, goto end; } + top_priv->last_mup_val = 0; rc = cam_tfe_top_set_hw_clk_rate(top_priv); if (rc) { CAM_ERR(CAM_ISP, "TFE:%d set_hw_clk_rate failed, rc=%d", diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h index 0ef9aa7e27..761471e01b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ @@ -107,9 +108,29 @@ struct cam_tfe_top_reg_offset_common { uint32_t diag_min_hbi_error_shift; uint32_t diag_neq_hbi_shift; uint32_t diag_sensor_hbi_mask; + uint32_t mup_shift_val; + + /* error bit data */ + uint32_t pp_camif_violation_bit; + uint32_t pp_violation_bit; + uint32_t rdi0_camif_violation_bit; + uint32_t rdi1_camif_violation_bit; + uint32_t rdi2_camif_violation_bit; + uint32_t diag_violation_bit; + uint32_t dyamanic_switch_violation_bit; + uint32_t pp_frame_drop_bit; + uint32_t rdi0_frame_drop_bit; + uint32_t rdi1_frame_drop_bit; + uint32_t rdi2_frame_drop_bit; + uint32_t pp_overflow_bit; + uint32_t rdi0_overflow_bit; + uint32_t rdi1_overflow_bit; + uint32_t rdi2_overflow_bit; + uint32_t out_of_sync_frame_drop_bit; /* configuration */ bool serializer_supported; + bool mup_supported; }; struct cam_tfe_camif_reg { diff --git a/include/uapi/camera/media/cam_tfe.h b/include/uapi/camera/media/cam_tfe.h index 7b9b008b22..5fe6ef3b32 100644 --- a/include/uapi/camera/media/cam_tfe.h +++ b/include/uapi/camera/media/cam_tfe.h @@ -73,6 +73,7 @@ #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2 2 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 3 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG 16 +#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH 15 /* DSP mode */ #define CAM_ISP_TFE_DSP_MODE_NONE 0