Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bee1df83 authored by Wyes Karny's avatar Wyes Karny
Browse files

msm: camera: isp: Handle Dual VFE incase of event mismatch



For dual IFE case if there is mismatch in the number of HW events
generated by two cores, then we recover for maximum of 10 HW events
mismatch. Beyond this KMD is not recovering.

CRs-Fixed: 2731316
Change-Id: Ifa1c932eef3340efbb64ed6d74cfc49581d91f36
Signed-off-by: default avatarWyes Karny <wkarny@codeaurora.org>
parent 2a26f41c
Loading
Loading
Loading
Loading
+55 −4
Original line number Diff line number Diff line
@@ -4396,6 +4396,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
		}
	}

	ctx->dual_ife_irq_mismatch_cnt = 0;
	/* Start IFE root node: do nothing */
	CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index);

@@ -4527,6 +4528,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
	ctx->dsp_enabled = false;
	ctx->is_fe_enabled = false;
	ctx->is_offline = false;
	ctx->dual_ife_irq_mismatch_cnt = 0;
	atomic_set(&ctx->overflow_pending, 0);
	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
		ctx->sof_cnt[i] = 0;
@@ -7175,6 +7177,36 @@ static int cam_ife_hw_mgr_handle_hw_rup(
	return 0;
}

static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx)
{
	struct cam_ife_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_ife_src, list) {
		if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT)
			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_VFE_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_ife_hw_mgr_check_irq_for_dual_vfe(
	struct cam_ife_hw_mgr_ctx            *ife_hw_mgr_ctx,
	uint32_t                              hw_event_type)
@@ -7214,18 +7246,37 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe(
	}

	if ((event_cnt[master_hw_idx] &&
		(event_cnt[master_hw_idx] - event_cnt[slave_hw_idx] > 1)) ||
		((int)(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))) {
		((int)(event_cnt[slave_hw_idx] - event_cnt[master_hw_idx]) > 1
		))) {

		CAM_ERR_RATE_LIMIT(CAM_ISP,
			"One of the VFE could not generate hw event %d master[%d] core_cnt %d slave[%d] core_cnt %d",
			hw_event_type, master_hw_idx, event_cnt[master_hw_idx],
			slave_hw_idx, event_cnt[slave_hw_idx]);

		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) {
			rc = -1;
			return rc;
		}

		if (event_cnt[master_hw_idx] >= 2) {
			event_cnt[master_hw_idx]--;
			ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
		}

		if (event_cnt[slave_hw_idx] >= 2) {
			event_cnt[slave_hw_idx]--;
			 ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
		}

		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1)
			cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx);
		rc = 0;
	}

	CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d",
			hw_event_type);

+3 −0
Original line number Diff line number Diff line
@@ -146,6 +146,8 @@ struct cam_ife_hw_mgr_debug {
 * @ts                      captured timestamp when the ctx is acquired
 * @is_offline              Indicate whether context is for offline IFE
 * @dsp_enabled             Indicate whether dsp is enabled in this context
 * @dual_ife_irq_mismatch_cnt   irq mismatch count value per core, used for
 *                              dual VFE
 */
struct cam_ife_hw_mgr_ctx {
	struct list_head                list;
@@ -197,6 +199,7 @@ struct cam_ife_hw_mgr_ctx {
	struct timespec64               ts;
	bool                            is_offline;
	bool                            dsp_enabled;
	uint32_t                        dual_ife_irq_mismatch_cnt;
};

/**
+1 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ enum cam_isp_hw_cmd_type {
	CAM_ISP_HW_CMD_DUMP_HW,
	CAM_ISP_HW_CMD_FE_TRIGGER_CMD,
	CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
	CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
	CAM_ISP_HW_CMD_MAX,
};

+1 −0
Original line number Diff line number Diff line
@@ -597,6 +597,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
	case CAM_ISP_HW_CMD_QUERY:
	case CAM_ISP_HW_CMD_QUERY_DSP_MODE:
	case CAM_ISP_HW_CMD_CAMIF_DATA:
	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
		rc = core_info->vfe_top->hw_ops.process_cmd(
			core_info->vfe_top->top_priv, cmd_type, cmd_args,
			arg_size);
+4 −0
Original line number Diff line number Diff line
@@ -295,6 +295,10 @@ static struct cam_vfe_top_ver2_reg_offset_common vfe170_150_top_common_reg = {
	.three_D_cfg              = 0x00000054,
	.violation_status         = 0x0000007C,
	.reg_update_cmd           = 0x000004AC,
	.irq_mask_0               = 0x0000005C,
	.irq_mask_1               = 0x00000060,
	.irq_status_0             = 0x0000006C,
	.irq_status_1             = 0x00000070,
};

static struct cam_vfe_rdi_ver2_reg vfe170_150_rdi_reg = {
Loading