msm: camera: reqmgr: reset the slot on buf_done

Reset the slot with the valid request on receiving
the buf_done which is reported on next EPOCH.
In case of back to back irqs slot is marked as skip idx
it will apply the request and try to reset a slot based
on MAX_PD + 1 calculation which might have the request
for which we have got a bubble. To make sure this does not
happen, reset a slot only on the buf_done for valid request.

If STOP ioctl is called from UMD for ISP, it will flush all
the lists. But this is not notified to CRM which might have
a stale entry of the half applied request, so on STOP ioctl
clear all the slots.

In case of SAT mode if one of the link has generated bubble,
while the sync_link has the sync_request slot reset sync_link
will not let the link recover of the bubble. To make sure the
recovery sync_mode is set to 0 for two consecutive slots of
the link.

CRs-Fixed: 2551701
Change-Id: If4b6f8a4a831ffddcef2cae6292d066778c18b04
Signed-off-by: Tejas Prajapati <tpraja@codeaurora.org>
Цей коміт міститься в:
Tejas Prajapati
2019-10-25 15:36:03 +05:30
зафіксовано Gerrit - the friendly Code Review server
джерело bf16c8a8e5
коміт 96390653c5
5 змінених файлів з 179 додано та 5 видалено

Переглянути файл

@@ -708,6 +708,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
CAM_DBG(CAM_REQ,
"Move active request %lld to free list(cnt = %d) [all fences done], ctx %u",
buf_done_req_id, ctx_isp->active_req_cnt, ctx->ctx_id);
ctx_isp->req_info.last_bufdone_req_id = req->request_id;
}
__cam_isp_ctx_update_state_monitor_array(ctx_isp,
@@ -907,6 +908,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -1077,7 +1079,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
* If no wait req in epoch, this is an error case.
* The recovery is to go back to sof state
*/
CAM_ERR(CAM_ISP, "No wait request");
CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id);
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
/* Send SOF event as empty frame*/
@@ -1093,7 +1095,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
req_isp->bubble_detected = true;
req_isp->reapply = true;
CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld",
ctx->ctx_id, req_isp->bubble_report, req->request_id);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify;
@@ -1242,7 +1245,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
* If no pending req in epoch, this is an error case.
* Just go back to the bubble state.
*/
CAM_ERR(CAM_ISP, "No pending request.");
CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id);
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@@ -1254,6 +1257,8 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true;
CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld",
ctx->ctx_id, req_isp->bubble_report, req->request_id);
req_isp->reapply = true;
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
@@ -1592,6 +1597,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -1769,6 +1775,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -2457,6 +2464,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -2553,9 +2561,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true;
CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld",
ctx->ctx_id, req_isp->bubble_report, req->request_id);
req_isp->reapply = true;
CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify;
@@ -2654,6 +2663,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -2726,6 +2736,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -2923,6 +2934,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
ctx_isp->reported_req_id = 0;
ctx_isp->hw_acquired = false;
ctx_isp->init_received = false;
ctx_isp->req_info.last_bufdone_req_id = 0;
atomic64_set(&ctx_isp->state_monitor_head, -1);
@@ -2983,6 +2995,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
ctx_isp->hw_acquired = false;
ctx_isp->init_received = false;
ctx_isp->rdi_only_context = false;
ctx_isp->req_info.last_bufdone_req_id = 0;
atomic64_set(&ctx_isp->state_monitor_head, -1);
@@ -3913,6 +3926,18 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
__cam_isp_ctx_substate_val_to_type(
ctx_isp->substate_activated));
if (ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_stop) {
struct cam_req_mgr_notify_stop notify;
notify.link_hdl = ctx->link_hdl;
CAM_DBG(CAM_ISP,
"Notify CRM about device stop ctx %u link 0x%x",
ctx->ctx_id, ctx->link_hdl);
ctx->ctx_crm_intf->notify_stop(&notify);
} else
CAM_ERR(CAM_ISP, "cb not present");
while (!list_empty(&ctx->pending_req_list)) {
req = list_first_entry(&ctx->pending_req_list,
struct cam_ctx_request, list);
@@ -3960,11 +3985,13 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
}
list_add_tail(&req->list, &ctx->free_req_list);
}
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->last_applied_req_id = 0;
ctx_isp->req_info.last_bufdone_req_id = 0;
atomic_set(&ctx_isp->process_bubble, 0);
atomic64_set(&ctx_isp->state_monitor_head, -1);
@@ -4424,6 +4451,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->req_info.last_bufdone_req_id = 0;
ctx->bubble_frame_cnt = 0;
ctx->hw_ctx = NULL;
ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;