mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
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 <rpampana@codeaurora.org>
This commit is contained in:
parent
4574450a12
commit
1fa7773fb1
3 changed files with 22 additions and 154 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) |
|
||||
|
|
|
|||
Loading…
Reference in a new issue