diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index e0eadaea4c..a283a7c719 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -2826,6 +2826,8 @@ static int __cam_isp_ctx_sof_in_activated_state( struct cam_context *ctx = ctx_isp->base; uint64_t request_id = 0; + ctx_isp->last_sof_jiffies = jiffies; + /* First check if there is a valid request in active list */ list_for_each_entry(req, &ctx->active_req_list, list) { if (req->request_id > ctx_isp->reported_req_id) { @@ -2903,6 +2905,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, void *evt_data) { uint64_t request_id = 0; + uint32_t wait_req_cnt = 0; uint32_t sof_event_status = CAM_REQ_MGR_SOF_EVENT_SUCCESS; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; @@ -2932,6 +2935,26 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, goto end; } + if (ctx_isp->last_applied_jiffies >= ctx_isp->last_sof_jiffies) { + list_for_each_entry(req, &ctx->wait_req_list, list) { + wait_req_cnt++; + } + + /* + * The previous req is applied after SOF and there is only + * one applied req, we don't need to report bubble for this case. + */ + if (wait_req_cnt == 1) { + req = list_first_entry(&ctx->wait_req_list, + struct cam_ctx_request, list); + request_id = req->request_id; + CAM_INFO(CAM_ISP, + "ctx:%d Don't report the bubble for req:%lld", + ctx->ctx_id, request_id); + goto end; + } + } + /* Update state prior to notifying CRM */ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; @@ -3065,6 +3088,8 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, return -EINVAL; } + ctx_isp->last_sof_jiffies = jiffies; + if (atomic_read(&ctx_isp->apply_in_progress)) CAM_INFO(CAM_ISP, "Apply is in progress at the time of SOF"); @@ -4500,6 +4525,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( spin_lock_bh(&ctx->lock); ctx_isp->substate_activated = next_state; ctx_isp->last_applied_req_id = apply->request_id; + ctx_isp->last_applied_jiffies = jiffies; list_del_init(&req->list); if (atomic_read(&ctx_isp->internal_recovery_set)) __cam_isp_ctx_enqueue_request_in_order(ctx, req, false); @@ -7077,6 +7103,8 @@ static inline void __cam_isp_context_reset_ctx_params( ctx_isp->recovery_req_id = 0; ctx_isp->aeb_error_cnt = 0; ctx_isp->sof_dbg_irq_en = false; + ctx_isp->last_sof_jiffies = 0; + ctx_isp->last_applied_jiffies = 0; } static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index 0164006957..f7dc1570bb 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -295,6 +295,8 @@ struct cam_isp_context_event_record { * @v4l2_event_sub_ids contains individual bits representing subscribed v4l2 ids * @evt_inject_params: event injection parameters * @aeb_enabled: Indicate if stream is for AEB + * @last_sof_jiffies: Record the jiffies of last sof + * @last_applied_jiffies: Record the jiffiest of last applied req * */ struct cam_isp_context { @@ -353,6 +355,8 @@ struct cam_isp_context { uint32_t v4l2_event_sub_ids; struct cam_hw_inject_evt_param evt_inject_params; bool aeb_enabled; + uint64_t last_sof_jiffies; + uint64_t last_applied_jiffies; }; /**