msm: camera: isp: Handle RUP in applied substate

In TFE top-half handler, TOP register status is read first and
then based on top register status, bus register status is read.
There could be a corner case where bufdone irq top-half handling
is ongoing, top status registers are read, and while reading bus
register status we might have got SOF and RUP irqs. Since RUP and
Bufdone both come from bus side, RUP bit is set during this bus
register read. Hence, RUP is handled first along with bufdone and
then SOF irq is handled. There is no handling in statemachine for
such RUP's in RDI only context statemachine. Hence leading to
bubble condition resulting in frame drop

To overcome such scenario, handling for RUP in applied substate
is introduced in RDI only statemachine.

CRs-Fixed: 3298719
Change-Id: I5cc8a0c122aa09c22da6536303f849344454c480
Signed-off-by: Shivakumar Malke <quic_smalke@quicinc.com>
This commit is contained in:
Shivakumar Malke 2022-09-22 21:35:14 +05:30
Родитель 336163ddec
Коммит a2b2dfab21
1 изменённых файлов: 60 добавлений и 1 удалений

Просмотреть файл

@ -4305,6 +4305,65 @@ error:
return 0;
}
static int __cam_isp_ctx_rdi_only_reg_upd_in_applied_state(
struct cam_isp_context *ctx_isp, void *evt_data)
{
struct cam_ctx_request *req = NULL;
struct cam_context *ctx = ctx_isp->base;
struct cam_isp_ctx_req *req_isp;
uint64_t request_id = 0;
if (list_empty(&ctx->wait_req_list)) {
CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request");
goto end;
}
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
req = list_first_entry(&ctx->wait_req_list,
struct cam_ctx_request, list);
list_del_init(&req->list);
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
request_id = (req_isp->hw_update_data.packet_opcode_type ==
CAM_ISP_PACKET_INIT_DEV) ? 0 : req->request_id;
if (req_isp->num_fence_map_out != 0) {
list_add_tail(&req->list, &ctx->active_req_list);
ctx_isp->active_req_cnt++;
request_id = req->request_id;
CAM_DBG(CAM_REQ,
"move request %lld to active list(cnt = %d), ctx %u",
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
__cam_isp_ctx_update_event_record(ctx_isp,
CAM_ISP_CTX_EVENT_RUP, req);
} else {
/* no io config, so the request is completed. */
list_add_tail(&req->list, &ctx->free_req_list);
CAM_DBG(CAM_ISP,
"move active request %lld to free list(cnt = %d), ctx %u",
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
}
CAM_DBG(CAM_ISP, "next Substate[%s]",
__cam_isp_ctx_substate_val_to_type(
ctx_isp->substate_activated));
__cam_isp_ctx_update_event_record(ctx_isp,
CAM_ISP_CTX_EVENT_RUP, req);
return 0;
end:
__cam_isp_ctx_update_event_record(ctx_isp,
CAM_ISP_CTX_EVENT_RUP, NULL);
/*
* There is no request in the pending list, move the sub state machine
* to SOF sub state
*/
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
return 0;
}
static struct cam_isp_ctx_irq_ops
cam_isp_ctx_rdi_only_activated_state_machine_irq
[CAM_ISP_CTX_ACTIVATED_MAX] = {
@ -4324,7 +4383,7 @@ static struct cam_isp_ctx_irq_ops
.irq_ops = {
__cam_isp_ctx_handle_error,
__cam_isp_ctx_rdi_only_sof_in_applied_state,
NULL,
__cam_isp_ctx_rdi_only_reg_upd_in_applied_state,
NULL,
__cam_isp_ctx_notify_eof_in_activated_state,
__cam_isp_ctx_buf_done_in_applied,