msm: camera: isp: Re-apply 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.

CRs-Fixed: 2506159
Change-Id: Ibcce21a1a87d0a64e49c6454391ca139fc7d1fa7
Signed-off-by: Vishalsingh Hajeri <vhajeri@codeaurora.org>
This commit is contained in:
Vishalsingh Hajeri 2019-09-30 16:43:18 -07:00 committed by Gerrit - the friendly Code Review server
parent 8c91109b74
commit 5c2bb43241
2 changed files with 50 additions and 0 deletions

View File

@ -637,6 +637,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
ctx->ctx_id);
} else {
list_add(&req->list, &ctx->pending_req_list);
ctx_isp->bubble_frame_cnt = 0;
CAM_DBG(CAM_REQ,
"Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u",
req->request_id, ctx_isp->active_req_cnt,
@ -788,6 +789,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
struct cam_req_mgr_trigger_notify notify;
struct cam_context *ctx = ctx_isp->base;
struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp;
uint64_t request_id = 0;
/*
@ -797,6 +799,48 @@ 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;
}
spin_lock_bh(&ctx->lock);
req = list_first_entry(&ctx->active_req_list,
struct cam_ctx_request, list);
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
spin_unlock_bh(&ctx->lock);
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;
spin_lock_bh(&ctx->lock);
list_del_init(&req->list);
list_add(&req->list, &ctx->pending_req_list);
spin_unlock_bh(&ctx->lock);
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) {
@ -2148,6 +2192,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
}
end:
ctx_isp->bubble_frame_cnt = 0;
atomic_set(&ctx_isp->process_bubble, 0);
return rc;
}
@ -3648,6 +3693,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
ctx_isp->reported_req_id = 0;
ctx_isp->bubble_frame_cnt = 0;
ctx_isp->substate_activated = ctx_isp->rdi_only_context ?
CAM_ISP_CTX_ACTIVATED_APPLIED :
(req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH :
@ -3791,6 +3837,7 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
ctx_isp->reported_req_id = 0;
ctx_isp->bubble_frame_cnt = 0;
atomic_set(&ctx_isp->process_bubble, 0);
atomic64_set(&ctx_isp->state_monitor_head, -1);
@ -4243,6 +4290,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
ctx->frame_id = 0;
ctx->active_req_cnt = 0;
ctx->reported_req_id = 0;
ctx->bubble_frame_cnt = 0;
ctx->hw_ctx = NULL;
ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
ctx->substate_machine = cam_isp_ctx_activated_state_machine;

View File

@ -156,6 +156,7 @@ struct cam_isp_context_state_monitor {
* @substate_actiavted: Current substate for the activated state.
* @process_bubble: Atomic variable to check if ctx is still
* processing bubble.
* @bubble_frame_cnt: Count number of frames since the req is in bubble
* @substate_machine: ISP substate machine for external interface
* @substate_machine_irq: ISP substate machine for irq handling
* @req_base: Common request object storage
@ -184,6 +185,7 @@ struct cam_isp_context {
int64_t frame_id;
uint32_t substate_activated;
atomic_t process_bubble;
uint32_t bubble_frame_cnt;
struct cam_ctx_ops *substate_machine;
struct cam_isp_ctx_irq_ops *substate_machine_irq;