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

Commit a3a87d61 authored by Chandan Kumar Jha's avatar Chandan Kumar Jha Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: isp: Reapply bubble request



In certain scenario Buf_done failures are observed
for the request which is in bubble state. Since we
never get bufdone we inadvertently are stuck
in Bubble state. This change will wait for a period
of two frames to receive bufdone and recover from bubble
state. If any bufdone IRQ is never generated within this
time period, we remove the request from active list and
add it back to pending request list.

Change-Id: Idad3528214401bde4e982807fef5de3313e9416b
Signed-off-by: default avatarChandan Kumar Jha <cjha@codeaurora.org>
parent 28b5c65d
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -689,6 +689,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
		list_del_init(&req->list);
		list_add(&req->list, &ctx->pending_req_list);
		atomic_set(&ctx_isp->process_bubble, 0);
		ctx_isp->bubble_frame_cnt = 0;

		CAM_DBG(CAM_REQ,
			"Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u",
@@ -930,6 +931,43 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
	 * In this case, we need to skip the current notification. This
	 * helps the state machine to catch up the delay.
	 */

	if (atomic_read(&ctx_isp->process_bubble)) {

		if (list_empty(&ctx->active_req_list)) {
			CAM_ERR(CAM_ISP,
				"No available active req in bubble");
			atomic_set(&ctx_isp->process_bubble, 0);
			rc = -EINVAL;
			return rc;
		}

		req = list_first_entry(&ctx->active_req_list,
			struct cam_ctx_request, list);
		req_isp = (struct cam_isp_ctx_req *) req->req_priv;

		if (ctx_isp->bubble_frame_cnt >= 1 &&
			req_isp->bubble_detected) {
			req_isp->num_acked = 0;
			ctx_isp->bubble_frame_cnt = 0;
			req_isp->bubble_detected = false;
			list_del_init(&req->list);
			list_add(&req->list, &ctx->pending_req_list);
			atomic_set(&ctx_isp->process_bubble, 0);
			ctx_isp->active_req_cnt--;
			CAM_DBG(CAM_REQ,
				"Move active req: %lld to pending list(cnt = %d) [bubble re-apply], ctx %u",
				req->request_id,
				ctx_isp->active_req_cnt, ctx->ctx_id);
		} else if (req_isp->bubble_detected) {
			ctx_isp->bubble_frame_cnt++;
			CAM_DBG(CAM_ISP,
				"Waiting on bufdone for bubble req: %lld, since frame_cnt = %lld",
				req->request_id, ctx_isp->bubble_frame_cnt);
		} else
			CAM_DBG(CAM_ISP, "Delayed bufdone for req: %lld",
				req->request_id);
	}
	if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
		ctx_isp->active_req_cnt <= 2) {
		if (ctx_isp->subscribe_event & CAM_TRIGGER_POINT_SOF) {
@@ -1314,6 +1352,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
		notify.req_id = req->request_id;
		notify.error = CRM_KMD_ERR_BUBBLE;
		ctx->ctx_crm_intf->notify_err(&notify);
		atomic_set(&ctx_isp->process_bubble, 1);
		CAM_DBG(CAM_REQ,
			"Notify CRM about Bubble req_id %llu frame %lld, ctx %u",
			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
@@ -2467,6 +2506,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
	}

end:
	ctx_isp->bubble_frame_cnt = 0;
	ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
	return rc;
}
@@ -3793,6 +3833,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
	atomic_set(&ctx_isp->process_bubble, 0);
	ctx_isp->frame_id = 0;
	ctx_isp->active_req_cnt = 0;
	ctx_isp->bubble_frame_cnt = 0;
	ctx_isp->req_info.reported_req_id = 0;
	ctx_isp->substate_activated = ctx_isp->rdi_only_context ?
		CAM_ISP_CTX_ACTIVATED_APPLIED :
@@ -3931,6 +3972,7 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
	ctx_isp->req_info.last_applied_time_stamp = 0;
	ctx_isp->req_info.last_bufdone_time_stamp = 0;
	ctx_isp->req_info.last_reported_id_time_stamp = 0;
	ctx_isp->bubble_frame_cnt = 0;

	atomic_set(&ctx_isp->process_bubble, 0);

@@ -4314,6 +4356,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
	ctx->base = ctx_base;
	ctx->frame_id = 0;
	ctx->active_req_cnt = 0;
	ctx->bubble_frame_cnt = 0;
	ctx->req_info.reported_req_id = 0;
	ctx->req_info.last_applied_req_id = 0;
	ctx->req_info.last_bufdone_req_id = 0;
+4 −2
Original line number Diff line number Diff line
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -237,7 +237,8 @@ struct cam_isp_context_event_record {
 * @irq_delay_detect:          Indicate whether a irq delay has detected or not
 * @irq_timestamps:            Timestamp from last handled IRQ
 * @fps:                       Current FPS for the activated state.
 *
 * @bubble_frame_cnt:          Count number of frames since the req is in
 *                             bubble
 */
struct cam_isp_context {
	struct cam_context              *base;
@@ -271,6 +272,7 @@ struct cam_isp_context {
	bool                             irq_delay_detect;
	uint64_t                         irq_timestamps;
	uint32_t                         fps;
	uint32_t                         bubble_frame_cnt;
};

/**