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

Commit 9286dc47 authored by likelong's avatar likelong Committed by hecaiqiang
Browse files

Do recovery after IRQ delayed

Change-Id: I3edaad134aa3a252105d9169e15c2b068d728c1a
parent 80daa52f
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ static const char isp_dev_name[] = "isp";
#define INC_STATE_MONITOR_HEAD(head) \
	(atomic64_add_return(1, head) % \
	CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES)

#define CAM_ISP_BUF_DONE_DELAY_TH 33000
static int cam_isp_context_dump_active_request(void *data, unsigned long iova,
	uint32_t buf_info);

@@ -402,6 +402,14 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
	trace_cam_buf_done("ISP", ctx, req);

	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
	if (ctx_isp->frame_id == 1)
		ctx_isp->irq_timestamps = done->irq_mono_boot_time;
	else if (done->irq_mono_boot_time -
				ctx_isp->irq_timestamps > CAM_ISP_BUF_DONE_DELAY_TH)
		ctx_isp->irq_delay_detect = 1;

	ctx_isp->irq_timestamps = done->irq_mono_boot_time;

	for (i = 0; i < done->num_handles; i++) {
		for (j = 0; j < req_isp->num_fence_map_out; j++) {
			if (done->resource_handle[i] ==
@@ -502,6 +510,26 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
			 req->request_id, ctx_isp->active_req_cnt);
	}

	if (ctx_isp->active_req_cnt && ctx_isp->irq_delay_detect) {
		CAM_ERR(CAM_ISP, "isp req[%lld] IRQ buf done got delayed",
				req->request_id);
		req = list_first_entry(&ctx->active_req_list,
			struct cam_ctx_request, list);
		req_isp = (struct cam_isp_ctx_req *) req->req_priv;

		for (j = 0; j < req_isp->num_fence_map_out; j++) {
			rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
				CAM_SYNC_STATE_SIGNALED_ERROR);
			if (rc)
				CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
					rc);
			req_isp->fence_map_out[j].sync_id = -1;
		}
		list_del_init(&req->list);
		list_add_tail(&req->list, &ctx->free_req_list);
		ctx_isp->active_req_cnt--;
	}
	ctx_isp->irq_delay_detect = 0;
end:
	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
		CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
@@ -569,12 +597,21 @@ static void __cam_isp_ctx_send_sof_timestamp(
static int __cam_isp_ctx_reg_upd_in_epoch_state(
	struct cam_isp_context *ctx_isp, void *evt_data)
{
	struct cam_isp_hw_reg_update_event_data  *rup_event_data = evt_data;

	if (ctx_isp->frame_id == 1)
		CAM_DBG(CAM_ISP, "Reg update for early PCR");
	else
		CAM_WARN(CAM_ISP,
			"Unexpected reg update in activated substate:%d for frame_id:%lld",
			ctx_isp->substate_activated, ctx_isp->frame_id);
	if (ctx_isp->frame_id == 1)
		ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
	else if (rup_event_data->irq_mono_boot_time -
				ctx_isp->irq_timestamps > CAM_ISP_BUF_DONE_DELAY_TH)
		ctx_isp->irq_delay_detect = 1;

	ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
	return 0;
}

@@ -585,6 +622,7 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
	struct cam_ctx_request  *req;
	struct cam_context      *ctx = ctx_isp->base;
	struct cam_isp_ctx_req  *req_isp;
	struct cam_isp_hw_reg_update_event_data  *rup_event_data = evt_data;

	if (list_empty(&ctx->wait_req_list)) {
		CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request");
@@ -614,6 +652,13 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
	 */
	ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
	CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
	if (ctx_isp->frame_id == 1)
		ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
	else if (rup_event_data->irq_mono_boot_time -
				ctx_isp->irq_timestamps > CAM_ISP_BUF_DONE_DELAY_TH)
		ctx_isp->irq_delay_detect = 1;

	ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;

end:
	return rc;
@@ -723,6 +768,12 @@ static int __cam_isp_ctx_sof_in_activated_state(
	ctx_isp->frame_id++;
	ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
	ctx_isp->boot_timestamp = sof_event_data->boot_time;
	if (ctx_isp->frame_id == 1)
		ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
	else if (sof_event_data->irq_mono_boot_time -
				ctx_isp->irq_timestamps > CAM_ISP_BUF_DONE_DELAY_TH)
		ctx_isp->irq_delay_detect = 1;
	ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
		CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id);
	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
@@ -738,6 +789,7 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
	struct cam_ctx_request *req = NULL;
	struct cam_isp_ctx_req *req_isp;
	struct cam_context *ctx = ctx_isp->base;
	struct cam_isp_hw_reg_update_event_data  *rup_event_data = evt_data;

	if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
		CAM_DBG(CAM_ISP, "invalid RUP");
@@ -764,6 +816,12 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
			CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
			req->request_id);
	}
	if (ctx_isp->frame_id == 1)
		ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
	else if (rup_event_data->irq_mono_boot_time -
				ctx_isp->irq_timestamps > CAM_ISP_BUF_DONE_DELAY_TH)
		ctx_isp->irq_delay_detect = 1;
	ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
end:
	return rc;
}
@@ -775,6 +833,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
	struct cam_isp_ctx_req    *req_isp;
	struct cam_context        *ctx = ctx_isp->base;
	uint64_t  request_id = 0;
	struct cam_isp_hw_epoch_event_data *epoch_hw_event_data = evt_data;

	if (list_empty(&ctx->wait_req_list)) {
		/*
@@ -843,6 +902,13 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
			CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id);
	}
	if (ctx_isp->frame_id == 1)
		ctx_isp->irq_timestamps =
			epoch_hw_event_data->irq_mono_boot_time;
	else if (epoch_hw_event_data->irq_mono_boot_time -
				ctx_isp->irq_timestamps > CAM_ISP_BUF_DONE_DELAY_TH)
		ctx_isp->irq_delay_detect = 1;
	ctx_isp->irq_timestamps = epoch_hw_event_data->irq_mono_boot_time;
	return 0;
}

@@ -876,6 +942,13 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
	ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
	ctx_isp->boot_timestamp = sof_event_data->boot_time;

	if (ctx_isp->frame_id == 1)
		ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
	else if (sof_event_data->irq_mono_boot_time -
					ctx_isp->irq_timestamps > CAM_ISP_BUF_DONE_DELAY_TH)
		ctx_isp->irq_delay_detect = 1;
	ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;

	if (list_empty(&ctx->active_req_list))
		ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
	else
+2 −0
Original line number Diff line number Diff line
@@ -193,6 +193,8 @@ struct cam_isp_context {
	bool                             hw_acquired;
	bool                             init_received;
	bool                             split_acquire;
	bool                             irq_delay_detect;
	uint64_t			irq_timestamps;
};

/**
+18 −2
Original line number Diff line number Diff line
@@ -4454,6 +4454,8 @@ static int cam_ife_hw_mgr_handle_reg_update(
				break;

			if (!rup_status) {
				rup_event_data.irq_mono_boot_time =
						evt_payload->ts.time_usecs;
				ife_hwr_irq_rup_cb(
					ife_hwr_mgr_ctx->common.cb_priv,
					CAM_ISP_HW_EVENT_REG_UPDATE,
@@ -4483,6 +4485,8 @@ static int cam_ife_hw_mgr_handle_reg_update(
			if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
				break;
			if (!rup_status) {
				rup_event_data.irq_mono_boot_time =
						evt_payload->ts.time_usecs;
				/* Send the Reg update hw event */
				ife_hwr_irq_rup_cb(
					ife_hwr_mgr_ctx->common.cb_priv,
@@ -4827,6 +4831,8 @@ static int cam_ife_hw_mgr_handle_sof(
						ife_hw_mgr_ctx,
						&sof_done_event_data.timestamp,
						&sof_done_event_data.boot_time);
					sof_done_event_data.irq_mono_boot_time =
						evt_payload->ts.time_usecs;

					ife_hw_irq_sof_cb(
						ife_hw_mgr_ctx->common.cb_priv,
@@ -4850,6 +4856,8 @@ static int cam_ife_hw_mgr_handle_sof(
					ife_hw_mgr_ctx,
					&sof_done_event_data.timestamp,
					&sof_done_event_data.boot_time);
				sof_done_event_data.irq_mono_boot_time =
						evt_payload->ts.time_usecs;

				ife_hw_irq_sof_cb(
					ife_hw_mgr_ctx->common.cb_priv,
@@ -4935,12 +4943,15 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
				if (atomic_read(
					&ife_hwr_mgr_ctx->overflow_pending))
					break;
				if (!eof_status)
				if (!eof_status) {
					eof_done_event_data.irq_mono_boot_time =
						evt_payload->ts.time_usecs;
					ife_hwr_irq_eof_cb(
						ife_hwr_mgr_ctx->common.cb_priv,
						CAM_ISP_HW_EVENT_EOF,
						&eof_done_event_data);
					}
			}

			break;
		/* Handling dual VFE Scenario */
@@ -4982,11 +4993,14 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
			if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
				break;

			if (!rc)
			if (!rc) {
				eof_done_event_data.irq_mono_boot_time =
					evt_payload->ts.time_usecs;
				ife_hwr_irq_eof_cb(
					ife_hwr_mgr_ctx->common.cb_priv,
					CAM_ISP_HW_EVENT_EOF,
					&eof_done_event_data);
			}

			break;

@@ -5086,6 +5100,8 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(

			if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
				break;
			buf_done_event_data.irq_mono_boot_time =
					evt_payload->ts.time_usecs;
			/* Report for Successful buf_done event if any */
			if (buf_done_event_data.num_handles > 0 &&
				ife_hwr_irq_wm_done_cb) {
+5 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ struct cam_isp_prepare_hw_update_data {
struct cam_isp_hw_sof_event_data {
	uint64_t       timestamp;
	uint64_t       boot_time;
	uint64_t       irq_mono_boot_time;
};

/**
@@ -142,6 +143,7 @@ struct cam_isp_hw_sof_event_data {
 */
struct cam_isp_hw_reg_update_event_data {
	uint64_t       timestamp;
	uint64_t       irq_mono_boot_time;
};

/**
@@ -152,6 +154,7 @@ struct cam_isp_hw_reg_update_event_data {
 */
struct cam_isp_hw_epoch_event_data {
	uint64_t       timestamp;
	uint64_t       irq_mono_boot_time;
};

/**
@@ -167,6 +170,7 @@ struct cam_isp_hw_done_event_data {
	uint32_t             resource_handle[
				CAM_NUM_OUT_PER_COMP_IRQ_MAX];
	uint64_t       timestamp;
	uint64_t       irq_mono_boot_time;
};

/**
@@ -177,6 +181,7 @@ struct cam_isp_hw_done_event_data {
 */
struct cam_isp_hw_eof_event_data {
	uint64_t       timestamp;
	uint64_t       irq_mono_boot_time;
};

/**
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct cam_isp_timestamp {
	struct timeval          mono_time;
	struct timeval          vt_time;
	uint64_t                ticks;
	uint64_t                time_usecs;
};

/*
Loading