|
@@ -749,8 +749,8 @@ static void __cam_isp_ctx_send_sof_timestamp(
|
|
|
req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;
|
|
|
|
|
|
CAM_DBG(CAM_ISP,
|
|
|
- "request id:%lld frame number:%lld SOF time stamp:0x%llx status:%u",
|
|
|
- request_id, ctx_isp->frame_id,
|
|
|
+ "link hdl 0x%x request id:%lld frame number:%lld SOF time stamp:%lld status:%u",
|
|
|
+ ctx_isp->base->link_hdl, request_id, ctx_isp->frame_id,
|
|
|
ctx_isp->sof_timestamp_val, sof_event_status);
|
|
|
|
|
|
if (cam_req_mgr_notify_message(&req_msg,
|
|
@@ -1677,6 +1677,7 @@ static int __cam_isp_ctx_reg_upd_in_applied_state(
|
|
|
}
|
|
|
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;
|
|
@@ -1685,8 +1686,9 @@ static int __cam_isp_ctx_reg_upd_in_applied_state(
|
|
|
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);
|
|
|
+ "move request %lld to active list(cnt = %d), ctx %u link %x",
|
|
|
+ req->request_id, ctx_isp->active_req_cnt,
|
|
|
+ ctx->ctx_id, ctx->link_hdl);
|
|
|
__cam_isp_ctx_update_event_record(ctx_isp,
|
|
|
CAM_ISP_CTX_EVENT_RUP, req);
|
|
|
} else {
|
|
@@ -1828,6 +1830,7 @@ notify_only:
|
|
|
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;
|
|
|
+ notify.sof_boottime = ctx_isp->boot_timestamp;
|
|
|
notify.trigger_id = ctx_isp->trigger_id;
|
|
|
|
|
|
ctx->ctx_crm_intf->notify_trigger(¬ify);
|
|
@@ -1949,8 +1952,9 @@ static int __cam_isp_ctx_sof_in_activated_state(
|
|
|
__cam_isp_ctx_update_state_monitor_array(ctx_isp,
|
|
|
CAM_ISP_STATE_CHANGE_TRIGGER_SOF, request_id);
|
|
|
|
|
|
- CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u",
|
|
|
- ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id);
|
|
|
+ CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u link %x",
|
|
|
+ ctx_isp->frame_id, ctx_isp->sof_timestamp_val,
|
|
|
+ ctx->ctx_id, ctx->link_hdl);
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -1995,6 +1999,7 @@ end:
|
|
|
static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
|
|
|
void *evt_data)
|
|
|
{
|
|
|
+ bool rc = false;
|
|
|
uint64_t request_id = 0;
|
|
|
uint32_t sof_event_status = CAM_REQ_MGR_SOF_EVENT_SUCCESS;
|
|
|
struct cam_req_mgr_trigger_notify notify;
|
|
@@ -2036,8 +2041,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
|
|
|
req_isp->reapply = true;
|
|
|
req_isp->cdm_reset_before_apply = false;
|
|
|
|
|
|
- CAM_INFO_RATE_LIMIT(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld",
|
|
|
- ctx->ctx_id, req_isp->bubble_report, req->request_id);
|
|
|
+ CAM_INFO_RATE_LIMIT(CAM_ISP, "ctx:%d link %x Report Bubble flag %d req id:%lld",
|
|
|
+ ctx->ctx_id, ctx->link_hdl,
|
|
|
+ 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;
|
|
@@ -2051,12 +2057,25 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
|
|
|
notify.trigger = CAM_TRIGGER_POINT_SOF;
|
|
|
notify.frame_id = ctx_isp->frame_id;
|
|
|
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
|
|
|
+ notify.sof_boottime_val = ctx_isp->boot_timestamp;
|
|
|
+ notify.need_recovery = true;
|
|
|
CAM_WARN_RATE_LIMIT(CAM_ISP,
|
|
|
"Notify CRM about Bubble req %lld frame %lld, ctx %u",
|
|
|
req->request_id, ctx_isp->frame_id, ctx->ctx_id);
|
|
|
trace_cam_log_event("Bubble", "Rcvd epoch in applied state",
|
|
|
req->request_id, ctx->ctx_id);
|
|
|
- ctx->ctx_crm_intf->notify_err(¬ify);
|
|
|
+ rc = ctx->ctx_crm_intf->notify_err(¬ify);
|
|
|
+
|
|
|
+ CAM_DBG(CAM_CRM, "Need bubble recovery %d", rc);
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ req_isp->bubble_detected = false;
|
|
|
+ req_isp->reapply = false;
|
|
|
+ CAM_DBG(CAM_ISP, "Disable bubble for ctx %d link %d",
|
|
|
+ ctx->ctx_id, ctx->link_hdl);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
atomic_set(&ctx_isp->process_bubble, 1);
|
|
|
} else {
|
|
|
req_isp->bubble_report = 0;
|
|
@@ -2230,6 +2249,7 @@ static int __cam_isp_ctx_buf_done_in_bubble(
|
|
|
static int __cam_isp_ctx_epoch_in_bubble_applied(
|
|
|
struct cam_isp_context *ctx_isp, void *evt_data)
|
|
|
{
|
|
|
+ int rc = 0;
|
|
|
uint64_t request_id = 0;
|
|
|
struct cam_req_mgr_trigger_notify notify;
|
|
|
struct cam_ctx_request *req;
|
|
@@ -2287,10 +2307,17 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
|
|
|
notify.trigger = CAM_TRIGGER_POINT_SOF;
|
|
|
notify.frame_id = ctx_isp->frame_id;
|
|
|
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
|
|
|
+ notify.sof_boottime_val = ctx_isp->boot_timestamp;
|
|
|
+ notify.need_recovery = true;
|
|
|
CAM_WARN_RATE_LIMIT(CAM_REQ,
|
|
|
"Notify CRM about Bubble req_id %llu frame %lld, ctx %u",
|
|
|
req->request_id, ctx_isp->frame_id, ctx->ctx_id);
|
|
|
- ctx->ctx_crm_intf->notify_err(¬ify);
|
|
|
+ rc = ctx->ctx_crm_intf->notify_err(¬ify);
|
|
|
+ if (rc) {
|
|
|
+ req_isp->bubble_detected = false;
|
|
|
+ req_isp->reapply = false;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
atomic_set(&ctx_isp->process_bubble, 1);
|
|
|
} else {
|
|
|
req_isp->bubble_report = 0;
|
|
@@ -3167,10 +3194,10 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
|
|
|
goto end;
|
|
|
}
|
|
|
|
|
|
- CAM_DBG(CAM_REQ, "Apply request %lld in Substate[%s] ctx %u",
|
|
|
+ CAM_DBG(CAM_REQ, "Apply request %lld in Substate[%s] ctx %u link %x",
|
|
|
req->request_id,
|
|
|
__cam_isp_ctx_substate_val_to_type(ctx_isp->substate_activated),
|
|
|
- ctx->ctx_id);
|
|
|
+ ctx->ctx_id, ctx->link_hdl);
|
|
|
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
|
|
|
|
|
|
if (ctx_isp->active_req_cnt >= 2) {
|
|
@@ -3253,6 +3280,81 @@ end:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int __cam_isp_ctx_change_substate(
|
|
|
+ struct cam_context *ctx,
|
|
|
+ struct cam_req_mgr_request_change_state *state_info)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ uint64_t request_id = 0;
|
|
|
+ struct cam_ctx_request *req = NULL;
|
|
|
+ struct cam_ctx_request *req_temp = NULL;
|
|
|
+ struct cam_ctx_request *bubble_req = NULL;
|
|
|
+ struct cam_isp_ctx_req *req_isp = NULL;
|
|
|
+ struct cam_isp_context *ctx_isp =
|
|
|
+ (struct cam_isp_context *) ctx->ctx_priv;
|
|
|
+
|
|
|
+ if (!list_empty(&ctx->wait_req_list)) {
|
|
|
+ req = list_first_entry(&ctx->wait_req_list,
|
|
|
+ struct cam_ctx_request,
|
|
|
+ list);
|
|
|
+ if (req->request_id == state_info->req_id) {
|
|
|
+ req_isp = (struct cam_isp_ctx_req *)req->req_priv;
|
|
|
+ req_isp->bubble_detected = true;
|
|
|
+ req_isp->reapply = true;
|
|
|
+ bubble_req = req;
|
|
|
+ list_del_init(&req->list);
|
|
|
+ list_add_tail(&req->list, &ctx->active_req_list);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!bubble_req) {
|
|
|
+ list_for_each_entry_safe(req, req_temp,
|
|
|
+ &ctx->active_req_list, list) {
|
|
|
+ if (req->request_id == state_info->req_id) {
|
|
|
+ req_isp =
|
|
|
+ (struct cam_isp_ctx_req *)req->req_priv;
|
|
|
+ req_isp->bubble_detected = true;
|
|
|
+ req_isp->reapply = true;
|
|
|
+ bubble_req = req;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!bubble_req) {
|
|
|
+ CAM_ERR(CAM_ISP, "Req %lld not in active list ctx : %d",
|
|
|
+ state_info->req_id,
|
|
|
+ ctx->ctx_id);
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+end:
|
|
|
+
|
|
|
+ if (req_isp->bubble_report)
|
|
|
+ atomic_set(&ctx_isp->process_bubble, 1);
|
|
|
+
|
|
|
+ if ((req->request_id > ctx_isp->reported_req_id)
|
|
|
+ && !req_isp->bubble_report) {
|
|
|
+ request_id = req->request_id;
|
|
|
+ ctx_isp->reported_req_id = request_id;
|
|
|
+ }
|
|
|
+
|
|
|
+ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
|
|
|
+ CAM_REQ_MGR_SOF_EVENT_ERROR);
|
|
|
+
|
|
|
+ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
|
|
|
+
|
|
|
+ CAM_DBG(CAM_ISP, "next Substate[%s] ctx : %d",
|
|
|
+ __cam_isp_ctx_substate_val_to_type(
|
|
|
+ ctx_isp->substate_activated), ctx->ctx_id);
|
|
|
+
|
|
|
+done:
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_apply_req_in_sof(
|
|
|
struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
|
|
|
{
|
|
@@ -3313,8 +3415,8 @@ static int __cam_isp_ctx_apply_req_in_bubble(
|
|
|
ctx_isp->substate_activated));
|
|
|
rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
|
|
|
CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED);
|
|
|
- CAM_DBG(CAM_ISP, "new Substate[%s]",
|
|
|
- __cam_isp_ctx_substate_val_to_type(
|
|
|
+ CAM_DBG(CAM_ISP, "ctx %d link %x new Substate[%s]",
|
|
|
+ ctx->ctx_id, ctx->link_hdl, __cam_isp_ctx_substate_val_to_type(
|
|
|
ctx_isp->substate_activated));
|
|
|
|
|
|
if (rc)
|
|
@@ -3704,6 +3806,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
|
|
|
flush_req);
|
|
|
|
|
|
ctx_isp->active_req_cnt = 0;
|
|
|
+
|
|
|
spin_unlock_bh(&ctx->lock);
|
|
|
|
|
|
reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
|
|
@@ -3753,13 +3856,16 @@ static struct cam_ctx_ops
|
|
|
.apply_req = __cam_isp_ctx_apply_req_in_sof,
|
|
|
.notify_frame_skip =
|
|
|
__cam_isp_ctx_apply_default_req_settings,
|
|
|
+ .change_state = __cam_isp_ctx_change_substate,
|
|
|
},
|
|
|
.irq_ops = NULL,
|
|
|
},
|
|
|
/* APPLIED */
|
|
|
{
|
|
|
.ioctl_ops = {},
|
|
|
- .crm_ops = {},
|
|
|
+ .crm_ops = {
|
|
|
+ .change_state = __cam_isp_ctx_change_substate,
|
|
|
+ },
|
|
|
.irq_ops = NULL,
|
|
|
},
|
|
|
/* EPOCH */
|
|
@@ -3769,6 +3875,7 @@ static struct cam_ctx_ops
|
|
|
.apply_req = __cam_isp_ctx_apply_req_in_epoch,
|
|
|
.notify_frame_skip =
|
|
|
__cam_isp_ctx_apply_default_req_settings,
|
|
|
+ .change_state = __cam_isp_ctx_change_substate,
|
|
|
},
|
|
|
.irq_ops = NULL,
|
|
|
},
|
|
@@ -3779,13 +3886,16 @@ static struct cam_ctx_ops
|
|
|
.apply_req = __cam_isp_ctx_apply_req_in_bubble,
|
|
|
.notify_frame_skip =
|
|
|
__cam_isp_ctx_apply_default_req_settings,
|
|
|
+ .change_state = __cam_isp_ctx_change_substate,
|
|
|
},
|
|
|
.irq_ops = NULL,
|
|
|
},
|
|
|
/* Bubble Applied */
|
|
|
{
|
|
|
.ioctl_ops = {},
|
|
|
- .crm_ops = {},
|
|
|
+ .crm_ops = {
|
|
|
+ .change_state = __cam_isp_ctx_change_substate,
|
|
|
+ },
|
|
|
.irq_ops = NULL,
|
|
|
},
|
|
|
/* HW ERROR */
|
|
@@ -5506,6 +5616,33 @@ static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int __cam_isp_ctx_get_isp_info(int32_t dev_hdl, void *data)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ struct cam_context *ctx;
|
|
|
+ struct cam_req_mgr_dev_info *isp_dev = data;
|
|
|
+ struct cam_isp_context *isp_ctx = NULL;
|
|
|
+
|
|
|
+ ctx = (struct cam_context *)cam_get_device_priv(dev_hdl);
|
|
|
+
|
|
|
+ isp_ctx = (struct cam_isp_context *)ctx->ctx_priv;
|
|
|
+
|
|
|
+ isp_dev->state = isp_ctx->substate_activated;
|
|
|
+ isp_dev->timestamp = isp_ctx->sof_timestamp_val;
|
|
|
+ isp_dev->boot_time = isp_ctx->boot_timestamp;
|
|
|
+ isp_dev->frame_id = isp_ctx->frame_id;
|
|
|
+
|
|
|
+ if ((isp_ctx->substate_activated ==
|
|
|
+ CAM_ISP_CTX_ACTIVATED_APPLIED) ||
|
|
|
+ (isp_ctx->substate_activated ==
|
|
|
+ CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED))
|
|
|
+ isp_dev->is_applied = true;
|
|
|
+ else
|
|
|
+ isp_dev->is_applied = false;
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
|
|
|
struct cam_req_mgr_device_info *dev_info)
|
|
|
{
|
|
@@ -5517,6 +5654,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
|
|
|
dev_info->p_delay = 1;
|
|
|
dev_info->trigger = CAM_TRIGGER_POINT_SOF;
|
|
|
dev_info->trigger_on = true;
|
|
|
+ dev_info->sof_ts_cb = &__cam_isp_ctx_get_isp_info;
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -5574,6 +5712,8 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
|
|
|
atomic_set(&ctx_isp->process_bubble, 0);
|
|
|
atomic_set(&ctx_isp->rxd_epoch, 0);
|
|
|
ctx_isp->frame_id = 0;
|
|
|
+ ctx_isp->sof_timestamp_val = 0;
|
|
|
+ ctx_isp->boot_timestamp = 0;
|
|
|
ctx_isp->active_req_cnt = 0;
|
|
|
ctx_isp->reported_req_id = 0;
|
|
|
ctx_isp->bubble_frame_cnt = 0;
|
|
@@ -5923,6 +6063,33 @@ static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int __cam_isp_ctx_change_state_req(struct cam_context *ctx,
|
|
|
+ struct cam_req_mgr_request_change_state *state_info)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ struct cam_ctx_ops *ctx_ops = NULL;
|
|
|
+ struct cam_isp_context *ctx_isp =
|
|
|
+ (struct cam_isp_context *) ctx->ctx_priv;
|
|
|
+
|
|
|
+ CAM_DBG(CAM_ISP, "Enter: changes state ctx id %d link 0x%x",
|
|
|
+ ctx->ctx_id, ctx->link_hdl);
|
|
|
+ ctx_ops = &ctx_isp->substate_machine[ctx_isp->substate_activated];
|
|
|
+ if (ctx_ops->crm_ops.change_state) {
|
|
|
+ rc = ctx_ops->crm_ops.change_state(ctx, state_info);
|
|
|
+ } else {
|
|
|
+ CAM_WARN_RATE_LIMIT(CAM_ISP,
|
|
|
+ "No handle function in activated Substate[%s]",
|
|
|
+ __cam_isp_ctx_substate_val_to_type(
|
|
|
+ ctx_isp->substate_activated));
|
|
|
+ rc = -EFAULT;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rc)
|
|
|
+ CAM_WARN_RATE_LIMIT(CAM_ISP,
|
|
|
+ "changes state failed");
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
|
|
|
struct cam_req_mgr_apply_request *apply)
|
|
|
{
|
|
@@ -6109,6 +6276,7 @@ static struct cam_ctx_ops
|
|
|
.flush_req = __cam_isp_ctx_flush_req_in_top_state,
|
|
|
.process_evt = __cam_isp_ctx_process_evt,
|
|
|
.dump_req = __cam_isp_ctx_dump_in_top_state,
|
|
|
+ .change_state = __cam_isp_ctx_change_state_req,
|
|
|
},
|
|
|
.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
|
|
|
.pagefault_ops = cam_isp_context_dump_requests,
|
|
@@ -6305,6 +6473,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
|
|
|
|
|
|
ctx->base = ctx_base;
|
|
|
ctx->frame_id = 0;
|
|
|
+ ctx->sof_timestamp_val = 0;
|
|
|
+ ctx->boot_timestamp = 0;
|
|
|
ctx->custom_enabled = false;
|
|
|
ctx->use_frame_header_ts = false;
|
|
|
ctx->use_default_apply = false;
|