From 1fa7773fb13b2db38ba3eaf0811fdc3acc8ed9bd Mon Sep 17 00:00:00 2001 From: Ravikishore Pampana Date: Thu, 8 Oct 2020 18:45:20 +0530 Subject: [PATCH] msm: camera: tfe: Enable only master interrupts in dual tfe usecase Enable only master sof, eof, epoch interrupts in dual tfe case. Due to scheduling issues one tfe core interrupts will be delayed that cause mis match of dual core interrupts events and eventually cause the frame drops. CRs-Fixed: 2796046 Change-Id: Ic16de3242e902bebaf79f83b9a332f0b7006908e Signed-off-by: Ravikishore Pampana --- drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c | 161 ++---------------- drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h | 6 - .../isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c | 9 +- 3 files changed, 22 insertions(+), 154 deletions(-) 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 5f05ef93a1b2..6867defe103c 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 @@ -3441,11 +3441,6 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv, ctx->last_submit_bl_cmd.bl_count = 0; ctx->packet = NULL; - for (i = 0; i < CAM_TFE_HW_NUM_MAX; i++) { - ctx->sof_cnt[i] = 0; - ctx->eof_cnt[i] = 0; - ctx->epoch_cnt[i] = 0; - } CAM_DBG(CAM_ISP, "Exit...ctx id:%d", ctx->ctx_index); cam_tfe_hw_mgr_put_ctx(&hw_mgr->free_ctx_list, &ctx); @@ -4667,36 +4662,6 @@ outportlog: } -static void cam_tfe_mgr_ctx_irq_dump(struct cam_tfe_hw_mgr_ctx *ctx) -{ - struct cam_isp_hw_mgr_res *hw_mgr_res; - struct cam_hw_intf *hw_intf; - struct cam_isp_hw_get_cmd_update cmd_update; - int i = 0; - - list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_in, list) { - if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT) - continue; - for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { - if (!hw_mgr_res->hw_res[i]) - continue; - switch (hw_mgr_res->hw_res[i]->res_id) { - case CAM_ISP_HW_TFE_IN_CAMIF: - hw_intf = hw_mgr_res->hw_res[i]->hw_intf; - cmd_update.res = hw_mgr_res->hw_res[i]; - cmd_update.cmd_type = - CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP; - hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, - CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, - &cmd_update, sizeof(cmd_update)); - break; - default: - break; - } - } - } -} - static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; @@ -5312,82 +5277,6 @@ static int cam_tfe_hw_mgr_handle_hw_rup( return 0; } -static int cam_tfe_hw_mgr_check_irq_for_dual_tfe( - struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx, - uint32_t hw_event_type) -{ - int32_t rc = -EINVAL; - uint32_t *event_cnt = NULL; - uint32_t master_hw_idx; - uint32_t slave_hw_idx; - - if (!tfe_hw_mgr_ctx->is_dual) - return 0; - - master_hw_idx = tfe_hw_mgr_ctx->master_hw_idx; - slave_hw_idx = tfe_hw_mgr_ctx->slave_hw_idx; - - switch (hw_event_type) { - case CAM_ISP_HW_EVENT_SOF: - event_cnt = tfe_hw_mgr_ctx->sof_cnt; - break; - case CAM_ISP_HW_EVENT_EPOCH: - event_cnt = tfe_hw_mgr_ctx->epoch_cnt; - break; - case CAM_ISP_HW_EVENT_EOF: - event_cnt = tfe_hw_mgr_ctx->eof_cnt; - break; - default: - return 0; - } - - if (event_cnt[master_hw_idx] == event_cnt[slave_hw_idx]) { - - event_cnt[master_hw_idx] = 0; - event_cnt[slave_hw_idx] = 0; - - return 0; - } - - if ((event_cnt[master_hw_idx] && - (event_cnt[master_hw_idx] - event_cnt[slave_hw_idx] > 1)) || - (event_cnt[slave_hw_idx] && - (event_cnt[slave_hw_idx] - event_cnt[master_hw_idx] > 1))) { - - if (tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt > 10) { - rc = -1; - return rc; - } - - CAM_ERR_RATE_LIMIT(CAM_ISP, - "One TFE could not generate hw event %d master id :%d slave id:%d", - hw_event_type, event_cnt[master_hw_idx], - event_cnt[slave_hw_idx]); - if (event_cnt[master_hw_idx] >= 2) { - event_cnt[master_hw_idx]--; - tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt++; - } - if (event_cnt[slave_hw_idx] >= 2) { - event_cnt[slave_hw_idx]--; - tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt++; - } - - if (tfe_hw_mgr_ctx->dual_tfe_irq_mismatch_cnt == 1) { - cam_tfe_mgr_ctx_irq_dump(tfe_hw_mgr_ctx); - trace_cam_delay_detect("ISP", "dual tfe irq mismatch", - CAM_DEFAULT_VALUE, tfe_hw_mgr_ctx->ctx_index, - CAM_DEFAULT_VALUE, CAM_DEFAULT_VALUE, - rc); - } - rc = 0; - } - - CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", - hw_event_type); - - return rc; -} - static int cam_tfe_hw_mgr_handle_hw_epoch( void *ctx, void *evt_info) @@ -5396,22 +5285,16 @@ static int cam_tfe_hw_mgr_handle_hw_epoch( struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx = ctx; cam_hw_event_cb_func tfe_hw_irq_epoch_cb; struct cam_isp_hw_epoch_event_data epoch_done_event_data; - int rc = 0; tfe_hw_irq_epoch_cb = tfe_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EPOCH]; switch (event_info->res_id) { case CAM_ISP_HW_TFE_IN_CAMIF: - tfe_hw_mgr_ctx->epoch_cnt[event_info->hw_idx]++; - rc = cam_tfe_hw_mgr_check_irq_for_dual_tfe(tfe_hw_mgr_ctx, - CAM_ISP_HW_EVENT_EPOCH); - if (!rc) { - if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending)) - break; - tfe_hw_irq_epoch_cb(tfe_hw_mgr_ctx->common.cb_priv, - CAM_ISP_HW_EVENT_EPOCH, &epoch_done_event_data); - } + if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending)) + break; + tfe_hw_irq_epoch_cb(tfe_hw_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_EPOCH, &epoch_done_event_data); break; case CAM_ISP_HW_TFE_IN_RDI0: @@ -5438,27 +5321,22 @@ static int cam_tfe_hw_mgr_handle_hw_sof( struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx = ctx; cam_hw_event_cb_func tfe_hw_irq_sof_cb; struct cam_isp_hw_sof_event_data sof_done_event_data; - int rc = 0; tfe_hw_irq_sof_cb = tfe_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_SOF]; switch (event_info->res_id) { case CAM_ISP_HW_TFE_IN_CAMIF: - tfe_hw_mgr_ctx->sof_cnt[event_info->hw_idx]++; - rc = cam_tfe_hw_mgr_check_irq_for_dual_tfe(tfe_hw_mgr_ctx, - CAM_ISP_HW_EVENT_SOF); - if (!rc) { - cam_tfe_mgr_cmd_get_sof_timestamp(tfe_hw_mgr_ctx, - &sof_done_event_data.timestamp, - &sof_done_event_data.boot_time); + cam_tfe_mgr_cmd_get_sof_timestamp(tfe_hw_mgr_ctx, + &sof_done_event_data.timestamp, + &sof_done_event_data.boot_time); - if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending)) - break; + if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending)) + break; + + tfe_hw_irq_sof_cb(tfe_hw_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); - tfe_hw_irq_sof_cb(tfe_hw_mgr_ctx->common.cb_priv, - CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); - } break; case CAM_ISP_HW_TFE_IN_RDI0: @@ -5494,22 +5372,17 @@ static int cam_tfe_hw_mgr_handle_hw_eof( struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx = ctx; cam_hw_event_cb_func tfe_hw_irq_eof_cb; struct cam_isp_hw_eof_event_data eof_done_event_data; - int rc = 0; tfe_hw_irq_eof_cb = tfe_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF]; switch (event_info->res_id) { case CAM_ISP_HW_TFE_IN_CAMIF: - tfe_hw_mgr_ctx->eof_cnt[event_info->hw_idx]++; - rc = cam_tfe_hw_mgr_check_irq_for_dual_tfe(tfe_hw_mgr_ctx, - CAM_ISP_HW_EVENT_EOF); - if (!rc) { - if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending)) - break; - tfe_hw_irq_eof_cb(tfe_hw_mgr_ctx->common.cb_priv, - CAM_ISP_HW_EVENT_EOF, &eof_done_event_data); - } + if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending)) + break; + tfe_hw_irq_eof_cb(tfe_hw_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_EOF, &eof_done_event_data); + break; case CAM_ISP_HW_TFE_IN_RDI0: diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h index 81a4e19fcfa1..6ea17d74ec19 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h @@ -66,9 +66,6 @@ struct cam_tfe_hw_mgr_debug { * @cdm_cmd cdm base and length request pointer * @last_submit_bl_cmd last submiited CDM BL command data * @config_done_complete indicator for configuration complete - * @sof_cnt sof count value per core, used for dual TFE - * @epoch_cnt epoch count value per core, used for dual TFE - * @eof_cnt eof count value per core, used for dual TFE * @overflow_pending flat to specify the overflow is pending for the * context * @cdm_done flag to indicate cdm has finished writing shadow @@ -113,9 +110,6 @@ struct cam_tfe_hw_mgr_ctx { struct cam_cdm_bl_info last_submit_bl_cmd; struct completion config_done_complete; - uint32_t sof_cnt[CAM_TFE_HW_NUM_MAX]; - uint32_t epoch_cnt[CAM_TFE_HW_NUM_MAX]; - uint32_t eof_cnt[CAM_TFE_HW_NUM_MAX]; atomic_t overflow_pending; atomic_t cdm_done; uint32_t is_rdi_only_context; 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 60b456e44fd3..cf1696540e3e 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 @@ -2000,7 +2000,7 @@ static int cam_tfe_camif_resource_start( CAM_DBG(CAM_ISP, "hw id:%d RUP val:%d", camif_res->hw_intf->hw_idx, rsrc_data->reg_data->reg_update_cmd_data); - /* Disable sof irq debug flag */ + /* Disable sof irq debug flag */ rsrc_data->enable_sof_irq_debug = false; rsrc_data->irq_debug_cnt = 0; @@ -2012,9 +2012,10 @@ static int cam_tfe_camif_resource_start( rsrc_data->common_reg->diag_config); } - /* Enable the irq */ - cam_tfe_irq_config(core_info, rsrc_data->reg_data->subscribe_irq_mask, - CAM_TFE_TOP_IRQ_REG_NUM, true); + /* Enable the irq only for master or single tfe usecase */ + if (rsrc_data->sync_mode != CAM_ISP_HW_SYNC_SLAVE) + cam_tfe_irq_config(core_info, rsrc_data->reg_data->subscribe_irq_mask, + CAM_TFE_TOP_IRQ_REG_NUM, true); /* Program perf counters */ val = (1 << rsrc_data->reg_data->perf_cnt_start_cmd_shift) |