From 566ac7abf86cc3fe4fdf79d615c08762ae791b54 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Date: Thu, 8 Apr 2021 12:15:37 +0530 Subject: [PATCH] msm: camera: common: Multiple fixes for crm redesign This change help to resolve below issues :- 1. Update frame duration calculation Add frame duration calculation with the use of fps. In some cases where horizonal blanking is more, frame duration calculation based on sof epoch calculation is not accurate. 2. Corner case in bubble handling Add support to handle master link bubble even if ISP linked with slave link receive few buf done irq for bubble request before master sends slave link to bubble state. CRs-Fixed: 2783209 Change-Id: Ibf35f31f5263be7b6a6be6cd095447a2910a6878 Signed-off-by: Ayush Kumar --- drivers/cam_core/cam_context.c | 27 ++ drivers/cam_core/cam_context.h | 15 + drivers/cam_core/cam_node.c | 19 ++ drivers/cam_isp/cam_isp_context.c | 283 +++++++++++++++--- drivers/cam_isp/cam_isp_context.h | 9 +- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 22 ++ .../isp_hw_mgr/include/cam_isp_hw_mgr_intf.h | 2 + drivers/cam_req_mgr/cam_req_mgr_core.c | 209 ++++++++++--- drivers/cam_req_mgr/cam_req_mgr_core.h | 6 + drivers/cam_req_mgr/cam_req_mgr_interface.h | 56 +++- include/uapi/camera/media/cam_isp.h | 13 + 11 files changed, 566 insertions(+), 95 deletions(-) diff --git a/drivers/cam_core/cam_context.c b/drivers/cam_core/cam_context.c index b742152775..d435a163e1 100644 --- a/drivers/cam_core/cam_context.c +++ b/drivers/cam_core/cam_context.c @@ -182,6 +182,33 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx, return rc; } +int cam_context_handle_crm_signal_buf_done(struct cam_context *ctx, + struct cam_req_mgr_signal_info *state_info) +{ + int rc; + + if (!ctx->state_machine) { + CAM_ERR(CAM_CORE, "Context is not ready"); + return -EINVAL; + } + + if (!state_info) { + CAM_ERR(CAM_CORE, "Invalid change state payload"); + return -EINVAL; + } + + if (ctx->state_machine[ctx->state].crm_ops.signal_buf_done) { + rc = ctx->state_machine[ctx->state].crm_ops.signal_buf_done(ctx, + state_info); + } else { + CAM_ERR(CAM_CORE, "No crm change state req in dev %d, state %d", + ctx->dev_hdl, ctx->state); + rc = -EPROTO; + } + + return rc; +} + int cam_context_handle_crm_state_change(struct cam_context *ctx, struct cam_req_mgr_request_change_state *state_info) { diff --git a/drivers/cam_core/cam_context.h b/drivers/cam_core/cam_context.h index 1b3f1bb58f..731eef07eb 100644 --- a/drivers/cam_core/cam_context.h +++ b/drivers/cam_core/cam_context.h @@ -130,6 +130,7 @@ struct cam_ctx_ioctl_ops { * @process_evt: Handle event notification from CRM.(optional) * @dump_req: Dump information for the issue request * @change_state: Change sub-state of hw context layer to bubble + * @signal_buf_done Notify device to signal buf done * */ struct cam_ctx_crm_ops { @@ -151,6 +152,8 @@ struct cam_ctx_crm_ops { struct cam_req_mgr_dump_info *dump); int (*change_state)(struct cam_context *ctx, struct cam_req_mgr_request_change_state *change_state); + int (*signal_buf_done)(struct cam_context *ctx, + struct cam_req_mgr_signal_info *signal_info); }; @@ -342,6 +345,18 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx, int cam_context_handle_crm_state_change(struct cam_context *ctx, struct cam_req_mgr_request_change_state *state_info); +/** + * cam_context_handle_crm_signal_buf_done() + * + * @brief: Handle signal buf done command + * + * @ctx: Object pointer for cam_context + * @signal_info Signal buf done request command payload + * + */ +int cam_context_handle_crm_signal_buf_done(struct cam_context *ctx, + struct cam_req_mgr_signal_info *signal_info); + /** * cam_context_handle_crm_notify_frame_skip() * diff --git a/drivers/cam_core/cam_node.c b/drivers/cam_core/cam_node.c index 11ba559748..7d17f92b64 100644 --- a/drivers/cam_core/cam_node.c +++ b/drivers/cam_core/cam_node.c @@ -619,6 +619,24 @@ static int __cam_node_crm_flush_req(struct cam_req_mgr_flush_request *flush) return cam_context_handle_crm_flush_req(ctx, flush); } +static int __cam_req_mgr_signal_buf_done( + struct cam_req_mgr_signal_info *signal_buf_done_info) +{ + struct cam_context *ctx = NULL; + + if (!signal_buf_done_info) + return -EINVAL; + + ctx = (struct cam_context *) cam_get_device_priv(signal_buf_done_info->dev_hdl); + if (!ctx) { + CAM_ERR(CAM_CORE, "Can not get context for handle %d", + signal_buf_done_info->dev_hdl); + return -EINVAL; + } + + return cam_context_handle_crm_signal_buf_done(ctx, signal_buf_done_info); +} + static int __cam_node_crm_state_change_req( struct cam_req_mgr_request_change_state *state_info) { @@ -734,6 +752,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf, node->crm_node_intf.notify_frame_skip = __cam_node_crm_notify_frame_skip; node->crm_node_intf.change_state = __cam_node_crm_state_change_req; + node->crm_node_intf.signal_buf_done = __cam_req_mgr_signal_buf_done; mutex_init(&node->list_mutex); INIT_LIST_HEAD(&node->free_ctx_list); diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 3bf6429a5a..4eef2fb5b1 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -98,6 +98,87 @@ static void __cam_isp_ctx_update_event_record( ctx_isp->event_record[event][iterator].timestamp = cur_time; } +static int cam_isp_ctx_sync_signal_on_buf_done_ready( + struct cam_context *ctx, + struct cam_ctx_request *req, + uint32_t status, uint32_t event_cause) +{ + struct cam_isp_ctx_req *req_isp; + int k = 0, rc = 0; + + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + + if (!req_isp->buf_done_mask) + return rc; + + for (k = 0; k < req_isp->num_fence_map_out; k++) { + if (req_isp->buf_done_mask & (1 << k)) { + rc = cam_sync_signal(req_isp->fence_map_out[k].sync_id, + status, event_cause); + if (rc) { + CAM_ERR(CAM_ISP, + "ctx[%d] : Sync signal for Req %llu, sync_id %d status=%d failed with rc = %d", + ctx->ctx_id, req->request_id, + req_isp->fence_map_out[k].sync_id, + status, rc); + return rc; + } else { + CAM_DBG(CAM_ISP, + "ctx[%d] : Sync signal success for Req %llu, sync_id %d status=%d", + ctx->ctx_id, req->request_id, + req_isp->fence_map_out[k].sync_id, status); + req_isp->fence_map_out[k].sync_id = -1; + } + } + } + req_isp->buf_done_mask = 0; + + return rc; +} + +static int cam_isp_ctx_handle_sync_signal( + struct cam_context *ctx, + struct cam_ctx_request *req, int32_t sync_index, + uint32_t status, uint32_t event_cause) +{ + struct cam_isp_ctx_req *req_isp; + int32_t buf_done_ready = 0; + int rc = 0; + + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + buf_done_ready = atomic_read(&req_isp->buf_done_ready); + + if (buf_done_ready != INIT_BUF_DONE) { + rc = cam_isp_ctx_sync_signal_on_buf_done_ready( + ctx, req, status, event_cause); + if (rc) { + CAM_DBG(CAM_ISP, + "Sync failed with rc = %d", rc); + return rc; + } + rc = cam_sync_signal(req_isp->fence_map_out[sync_index].sync_id, + status, + event_cause); + if (rc) { + CAM_DBG(CAM_ISP, + "ctx[%d] :Sync failed Req %llu, sync_id %d status %d with rc = %d", + ctx->ctx_id, req->request_id, + req_isp->fence_map_out[sync_index].sync_id, + status, rc); + return rc; + } + CAM_DBG(CAM_ISP, + "ctx[%d] : Sync signal success for Req %llu, sync_id %d status %d", + ctx->ctx_id, req->request_id, + req_isp->fence_map_out[sync_index].sync_id, + status); + req_isp->fence_map_out[sync_index].sync_id = -1; + } else { + req_isp->buf_done_mask |= 1 << sync_index; + } + return rc; +} + static int __cam_isp_ctx_dump_event_record( struct cam_isp_context *ctx_isp, uintptr_t cpu_addr, @@ -836,6 +917,7 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list( atomic_set(&ctx_isp->process_bubble, 0); req_isp->cdm_reset_before_apply = false; ctx_isp->bubble_frame_cnt = 0; + atomic_set(&req_isp->buf_done_ready, 0); if (buf_done_req_id <= ctx->last_flush_req) { for (i = 0; i < req_isp->num_fence_map_out; i++) @@ -866,6 +948,11 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list( CAM_REQ_MGR_SOF_EVENT_SUCCESS); } } + + rc = cam_isp_ctx_sync_signal_on_buf_done_ready( + ctx, req, CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); req_isp->reapply = false; @@ -961,19 +1048,29 @@ static int __cam_isp_ctx_handle_buf_done_for_request( } if (!req_isp->bubble_detected) { - CAM_DBG(CAM_ISP, - "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", - req->request_id, - req_isp->fence_map_out[j].resource_handle, - req_isp->fence_map_out[j].sync_id, - ctx->ctx_id); - - rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, - CAM_SYNC_STATE_SIGNALED_SUCCESS, - CAM_SYNC_COMMON_EVENT_SUCCESS); - if (rc) - CAM_DBG(CAM_ISP, "Sync failed with rc = %d", - rc); + if (req_isp->is_sync_mode) { + CAM_DBG(CAM_ISP, + "Hold sync signal: req %lld res 0x%x fd 0x%x, ctx %u", + req->request_id, + req_isp->fence_map_out[j].resource_handle, + req_isp->fence_map_out[j].sync_id, + ctx->ctx_id); + rc = cam_isp_ctx_handle_sync_signal(ctx, req, j, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + } else { + CAM_DBG(CAM_ISP, + "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", + req->request_id, + req_isp->fence_map_out[j].resource_handle, + req_isp->fence_map_out[j].sync_id, + ctx->ctx_id); + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + if (rc) + CAM_DBG(CAM_ISP, "Sync failed with rc = %d", rc); + } } else if (!req_isp->bubble_report) { CAM_DBG(CAM_ISP, "Sync with failure: req %lld res 0x%x fd 0x%x, ctx %u", @@ -1075,18 +1172,21 @@ static int __cam_isp_handle_deferred_buf_done( "ctx[%d] : Req %llu, status=%d res=0x%x should never happen", ctx->ctx_id, req->request_id, status, req_isp->fence_map_out[j].resource_handle); - - rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, - status, event_cause); - if (rc) { - CAM_ERR(CAM_ISP, - "ctx[%d] : Sync signal for Req %llu, sync_id %d status=%d failed with rc = %d", - ctx->ctx_id, req->request_id, - req_isp->fence_map_out[j].sync_id, - status, rc); + if (req_isp->is_sync_mode) { + rc = cam_isp_ctx_handle_sync_signal( + ctx, req, j, status, event_cause); } else { - req_isp->num_acked++; - req_isp->fence_map_out[j].sync_id = -1; + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + status, event_cause); + if (rc) { + CAM_ERR(CAM_ISP, + "ctx[%d] : Sync signal for Req %llu, sync_id %d status=%d failed with rc = %d", + ctx->ctx_id, req->request_id, + req_isp->fence_map_out[j].sync_id, + status, rc); + } else { + req_isp->num_acked++; + } } } else { req_isp->num_acked++; @@ -1190,16 +1290,27 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr( req_isp->fence_map_out[j].sync_id); continue; } else if (!req_isp->bubble_detected) { - CAM_DBG(CAM_ISP, - "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", - req->request_id, - req_isp->fence_map_out[j].resource_handle, - req_isp->fence_map_out[j].sync_id, - ctx->ctx_id); - - rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, - CAM_SYNC_STATE_SIGNALED_SUCCESS, - CAM_SYNC_COMMON_EVENT_SUCCESS); + if (req_isp->is_sync_mode) { + CAM_DBG(CAM_ISP, + "Hold sync signal: req %lld res 0x%x fd 0x%x, ctx %u", + req->request_id, + req_isp->fence_map_out[j].resource_handle, + req_isp->fence_map_out[j].sync_id, + ctx->ctx_id); + rc = cam_isp_ctx_handle_sync_signal(ctx, req, j, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + } else { + CAM_DBG(CAM_ISP, + "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", + req->request_id, + req_isp->fence_map_out[j].resource_handle, + req_isp->fence_map_out[j].sync_id, + ctx->ctx_id); + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + } if (rc) { CAM_DBG(CAM_ISP, "Sync failed with rc = %d", rc); @@ -1258,7 +1369,6 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr( req_isp->fence_map_out[j].sync_id, ctx->ctx_id); if (!rc) { req_isp->num_acked++; - req_isp->fence_map_out[j].sync_id = -1; } if ((ctx_isp->use_frame_header_ts) && @@ -1666,10 +1776,11 @@ static int __cam_isp_ctx_reg_upd_in_applied_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; - struct cam_ctx_request *req; - struct cam_context *ctx = ctx_isp->base; - struct cam_isp_ctx_req *req_isp; - uint64_t request_id = 0; + struct cam_ctx_request *req; + struct cam_context *ctx = ctx_isp->base; + struct cam_isp_ctx_req *req_isp; + uint64_t request_id = 0; + struct cam_req_mgr_notify_rup notify_rup_info; if (list_empty(&ctx->wait_req_list)) { CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request"); @@ -1684,10 +1795,20 @@ static int __cam_isp_ctx_reg_upd_in_applied_state( 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; + + if (req_isp->is_sync_mode) { + request_id = req->request_id; + notify_rup_info.link_hdl = ctx->link_hdl; + notify_rup_info.req_id = request_id; + ctx->ctx_crm_intf->notify_rup(¬ify_rup_info); + atomic_set(&req_isp->buf_done_ready, notify_rup_info.state); + } + CAM_DBG(CAM_REQ, - "move request %lld to active list(cnt = %d), ctx %u link %x", + "move request %lld to active list(cnt = %d), state %d sync mode %d ctx %u link %x", req->request_id, ctx_isp->active_req_cnt, + notify_rup_info.state, + req_isp->is_sync_mode, ctx->ctx_id, ctx->link_hdl); __cam_isp_ctx_update_event_record(ctx_isp, CAM_ISP_CTX_EVENT_RUP, req); @@ -1823,6 +1944,7 @@ notify_only: */ 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) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; @@ -1833,6 +1955,15 @@ notify_only: notify.sof_boottime = ctx_isp->boot_timestamp; notify.trigger_id = ctx_isp->trigger_id; + if (!list_empty(&ctx->active_req_list)) { + req = list_first_entry(&ctx->active_req_list, + struct cam_ctx_request, list); + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + notify.fps = req_isp->hw_update_data.fps; + } else { + notify.fps = 0; + } + ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld ctx %u", ctx_isp->frame_id, ctx->ctx_id); @@ -2071,6 +2202,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, if (rc) { req_isp->bubble_detected = false; req_isp->reapply = false; + ctx_isp->substate_activated = + CAM_ISP_CTX_ACTIVATED_APPLIED; CAM_DBG(CAM_ISP, "Disable bubble for ctx %d link %d", ctx->ctx_id, ctx->link_hdl); return 0; @@ -3229,6 +3362,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( goto end; } req_isp->bubble_report = apply->report_if_bubble; + req_isp->is_sync_mode = apply->is_sync_mode; cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.request_id = req->request_id; @@ -3280,6 +3414,40 @@ end: return rc; } +static int __cam_isp_ctx_signal_buf_done( + struct cam_context *ctx, + struct cam_req_mgr_signal_info *signal_buf_done) +{ + struct cam_ctx_request *req = NULL; + struct cam_isp_ctx_req *req_isp = NULL; + + if (!list_empty(&ctx->wait_req_list)) { + req = list_first_entry(&ctx->wait_req_list, + struct cam_ctx_request, + list); + if (req->request_id == signal_buf_done->req_id) { + req_isp = (struct cam_isp_ctx_req *)req->req_priv; + atomic_set(&req_isp->buf_done_ready, signal_buf_done->state); + goto end; + } + } + + if (!list_empty(&ctx->active_req_list)) { + req = list_first_entry(&ctx->active_req_list, + struct cam_ctx_request, + list); + if (req->request_id == signal_buf_done->req_id) { + req_isp = (struct cam_isp_ctx_req *)req->req_priv; + atomic_set(&req_isp->buf_done_ready, signal_buf_done->state); + goto end; + } + } + + CAM_WARN(CAM_ISP, "Request %lld not found", signal_buf_done->req_id); +end: + return 0; +} + static int __cam_isp_ctx_change_substate( struct cam_context *ctx, struct cam_req_mgr_request_change_state *state_info) @@ -3865,6 +4033,7 @@ static struct cam_ctx_ops .ioctl_ops = {}, .crm_ops = { .change_state = __cam_isp_ctx_change_substate, + .signal_buf_done = __cam_isp_ctx_signal_buf_done, }, .irq_ops = NULL, }, @@ -3876,6 +4045,7 @@ static struct cam_ctx_ops .notify_frame_skip = __cam_isp_ctx_apply_default_req_settings, .change_state = __cam_isp_ctx_change_substate, + .signal_buf_done = __cam_isp_ctx_signal_buf_done, }, .irq_ops = NULL, }, @@ -3895,6 +4065,7 @@ static struct cam_ctx_ops .ioctl_ops = {}, .crm_ops = { .change_state = __cam_isp_ctx_change_substate, + .signal_buf_done = __cam_isp_ctx_signal_buf_done, }, .irq_ops = NULL, }, @@ -4789,6 +4960,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( cfg.pf_data = &(req->pf_data); cfg.num_out_map_entries = 0; cfg.num_in_map_entries = 0; + req_isp->hw_update_data.fps = -1; CAM_DBG(CAM_ISP, "try to prepare config packet......"); @@ -4808,6 +4980,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( req_isp->bubble_detected = false; req_isp->cdm_reset_before_apply = false; req_isp->hw_update_data.packet = packet; + atomic_set(&req_isp->buf_done_ready, INIT_BUF_DONE); for (i = 0; i < req_isp->num_fence_map_out; i++) { rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id); @@ -6063,6 +6236,33 @@ static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx, return rc; } +static int __cam_isp_ctx_signal_buf_done_req(struct cam_context *ctx, + struct cam_req_mgr_signal_info *signal_buf_done) +{ + 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: signal buf done 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.signal_buf_done) { + rc = ctx_ops->crm_ops.signal_buf_done(ctx, signal_buf_done); + } 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, + "signal buf done failed"); + return rc; +} + static int __cam_isp_ctx_change_state_req(struct cam_context *ctx, struct cam_req_mgr_request_change_state *state_info) { @@ -6277,6 +6477,7 @@ static struct cam_ctx_ops .process_evt = __cam_isp_ctx_process_evt, .dump_req = __cam_isp_ctx_dump_in_top_state, .change_state = __cam_isp_ctx_change_state_req, + .signal_buf_done = __cam_isp_ctx_signal_buf_done_req, }, .irq_ops = __cam_isp_ctx_handle_irq_in_activated, .pagefault_ops = cam_isp_context_dump_requests, diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index 3a1371a07b..e787498331 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -157,7 +157,9 @@ struct cam_isp_ctx_irq_ops { * @reapply: True if reapplying after bubble * @cdm_reset_before_apply: For bubble re-apply when buf done not coming set * to True - * + * @buf_done_ready Flag to check if ready to signal buf done when in sync mode + * @buf_done_mask Mask used to check number of buf done which is yet to be signaled + * @is_sync_mode If request need to be apply in sync with other link */ struct cam_isp_ctx_req { struct cam_ctx_request *base; @@ -177,6 +179,9 @@ struct cam_isp_ctx_req { bool bubble_detected; bool reapply; bool cdm_reset_before_apply; + atomic_t buf_done_ready; + int32_t buf_done_mask; + bool is_sync_mode; }; /** @@ -273,6 +278,7 @@ struct cam_isp_context_event_record { * @workq: Worker thread for offline ife * @trigger_id: ID provided by CRM for each ctx on the link * @last_bufdone_err_apply_req_id: last bufdone error apply request id + * @fps: Current FPS for the activated state. * */ struct cam_isp_context { @@ -321,6 +327,7 @@ struct cam_isp_context { struct cam_req_mgr_core_workq *workq; int32_t trigger_id; int64_t last_bufdone_err_apply_req_id; + uint32_t fps; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 7cf78a69ba..e61864b140 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -8767,6 +8767,27 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, "BW limit update failed for IFE rc: %d", rc); } break; + case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG: { + struct cam_fps_config *fps_config; + struct cam_isp_prepare_hw_update_data *prepare_hw_data; + + if (blob_size < sizeof(struct cam_fps_config)) { + CAM_ERR(CAM_ISP, "Invalid fps blob size %u expected %u", + blob_size, sizeof(struct cam_fps_config)); + return -EINVAL; + } + + fps_config = (struct cam_fps_config *)blob_data; + + prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) + prepare->priv; + if (fps_config->fps) { + prepare_hw_data->fps = fps_config->fps; + CAM_DBG(CAM_ISP, "FPS value %u", fps_config->fps); + } else + CAM_WARN(CAM_ISP, "FPS value 0"); + } + break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); break; @@ -9205,6 +9226,7 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data, case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG: case CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG: case CAM_ISP_GENERIC_BLOB_TYPE_DISCARD_INITIAL_FRAMES: + case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG: break; default: CAM_WARN(CAM_ISP, "Invalid blob type: %u", blob_type); diff --git a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h index 9322cd4fe8..2e9a6c6d8d 100644 --- a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h @@ -155,6 +155,7 @@ struct cam_isp_bw_config_internal { * @num_reg_dump_buf: Count of descriptors in reg_dump_buf_desc * @packet CSL packet from user mode driver * @mup_en Flag if dynamic sensor switch is enabled + * @fps: Fps vaue associated with this packet/request * */ struct cam_isp_prepare_hw_update_data { @@ -172,6 +173,7 @@ struct cam_isp_prepare_hw_update_data { uint32_t num_reg_dump_buf; struct cam_packet *packet; bool mup_en; + int32_t fps; }; diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index 68fe95964a..75fe950fc1 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -18,7 +18,10 @@ #include "cam_req_mgr_debug.h" #include "cam_common_util.h" -#define THRESHOLD_FACTOR 3 +#define THRESHOLD_FACTOR_3 3 +#define THRESHOLD_FACTOR_2 2 +#define MILLI_SECOND_CONVERSION_FACTOR 1000000 +#define CAM_REQ_MGR_DEFAULT_FPS 30 static struct cam_req_mgr_core_device *g_crm_core_dev; static struct cam_req_mgr_core_link g_links[MAXIMUM_LINKS_PER_SESSION]; @@ -69,6 +72,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->sync_frame_id = 0; link->is_sync_req = true; link->skip_sync_apply = false; + link->fps = CAM_REQ_MGR_DEFAULT_FPS; + link->num_isp_dev = 0; + link->retry_threshold = 0; atomic_set(&link->eof_event_cnt, 0); for (pd = 0; pd < CAM_PIPELINE_DELAY_MAX; pd++) { @@ -611,6 +617,7 @@ static void __cam_req_mgr_flush_req_slot( atomic_set(&link->eof_event_cnt, 0); in_q->wr_idx = 0; in_q->rd_idx = 0; + link->sync_frame_id = 0; link->trigger_cnt[0][0] = 0; link->trigger_cnt[0][1] = 0; link->trigger_cnt[1][0] = 0; @@ -898,6 +905,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, struct cam_req_mgr_link_evt_data evt_data; struct cam_req_mgr_tbl_slot *slot = NULL; struct cam_req_mgr_apply *apply_data = NULL; + struct cam_req_mgr_slot *in_q_slot = NULL; apply_req.link_hdl = link->link_hdl; apply_req.report_if_bubble = 0; @@ -1083,6 +1091,10 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, continue; apply_req.trigger_point = trigger; + in_q_slot = &link->req.in_q->slot[idx]; + apply_req.is_sync_mode = + (in_q_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) ? true : false; + CAM_DBG(CAM_REQ, "SEND: link_hdl %x dev %s pd %d req_id %lld", link->link_hdl, dev->dev_info.name, @@ -1522,7 +1534,8 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, } if (link->num_sync_link && - (link->initial_sync_req == slot->req_id)) { + ((link->initial_sync_req == slot->req_id) || + ((link->initial_sync_req < slot->req_id) && link->sync_frame_id == 0))) { link->sync_frame_id = trigger_data->frame_id; CAM_DBG(CAM_CRM, "link %x sync frame %lld", link->link_hdl, link->sync_frame_id); @@ -2795,12 +2808,6 @@ int cam_req_mgr_process_error(void *priv, void *data) __cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl); in_q->rd_idx = idx; in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED; - if (link->sync_link[0]) { - in_q->slot[idx].sync_mode = 0; - __cam_req_mgr_inc_idx(&idx, 1, - link->req.l_tbl->num_slots); - in_q->slot[idx].sync_mode = 0; - } /* The next req may also be applied */ idx = in_q->rd_idx; @@ -3081,6 +3088,44 @@ end: return rc; } +static int cam_req_mgr_cb_notify_rup( + struct cam_req_mgr_notify_rup *rup_info) +{ + int i, j, rc = 0; + struct cam_req_mgr_core_link *link = NULL; + struct cam_req_mgr_connected_device *dev = NULL; + struct cam_req_mgr_signal_info set_signal_flag; + + link = (struct cam_req_mgr_core_link *) + cam_get_device_priv(rup_info->link_hdl); + if (!link) { + CAM_DBG(CAM_CRM, "link ptr NULL %x", rup_info->link_hdl); + rc = -EINVAL; + goto end; + } + + if (link->is_master) { + for (i = 0; i < link->num_sync_link; i++) { + for (j = 0; j < link->sync_link[i]->num_devs; j++) { + dev = &link->sync_link[i]->l_dev[j]; + if (dev->ops->signal_buf_done) { + set_signal_flag.link_hdl = link->sync_link[i]->link_hdl; + set_signal_flag.dev_hdl = dev->dev_hdl; + set_signal_flag.req_id = rup_info->req_id; + set_signal_flag.state = SIGNAL_SYNC_BUF_DONE; + dev->ops->signal_buf_done(&set_signal_flag); + } + } + } + rup_info->state = SIGNAL_SYNC_BUF_DONE; + } else { + rup_info->state = INIT_BUF_DONE; + } + +end: + return rc; +} + /** * cam_req_mgr_cb_notify_err() * @@ -3096,7 +3141,7 @@ static bool cam_req_mgr_cb_notify_err( { bool rc = false; int i, j; - uint32_t idx; + int32_t idx; struct crm_workq_task *task = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_error_notify *notify_err; @@ -3164,6 +3209,7 @@ static bool cam_req_mgr_cb_notify_err( tmp_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) && !link->is_master) { crm_timer_reset(link->watchdog); + link->frame_id = err_info->frame_id; CAM_DBG(CAM_CRM, "Not processing bubble as it is slave link %x", link->link_hdl); return true; @@ -3220,6 +3266,7 @@ static bool cam_req_mgr_cb_notify_err( link->sync_link[i]->link_hdl; notify_err->dev_hdl = dev->dev_hdl; notify_err->error = err_info->error; + notify_err->trigger = err_info->trigger; task->process_cb = &cam_req_mgr_process_error; cam_req_mgr_workq_enqueue_task( @@ -3555,6 +3602,12 @@ static int cam_req_mgr_cb_notify_trigger( if (trigger_data->trigger == CAM_TRIGGER_POINT_SOF) crm_timer_reset(link->watchdog); + if (link->sof_timestamp == trigger_data->sof_timestamp_val) { + CAM_DBG(CAM_CRM, + "Irq delay, skipping apply"); + return 0; + } + link->prev_sof_timestamp = link->sof_timestamp; link->sof_timestamp = trigger_data->sof_timestamp_val; link->frame_id = trigger_data->frame_id; @@ -3582,7 +3635,6 @@ static int cam_req_mgr_cb_notify_trigger( link->link_hdl, slot->req_id, sync_id, slot->status); } - CAM_DBG(CAM_CRM, "link %x req %lld slot mode %d tmp slot mode %d init sync %lld", link->link_hdl, slot->req_id, @@ -3617,13 +3669,14 @@ static int cam_req_mgr_cb_notify_trigger( frame_duration = (curr_boot_timestamp - link->sof_boottime) * 2; + CAM_DBG(CAM_CRM, "[Master %x] epoch time %lld sof boottime %lld frame id %lld frame duration %d ms open cnt %d req id %lld", link->link_hdl, curr_boot_timestamp, link->sof_boottime, trigger_data->frame_id, - frame_duration/1000000, + frame_duration / MILLI_SECOND_CONVERSION_FACTOR, link->open_req_cnt, slot->req_id); @@ -3721,21 +3774,74 @@ static int cam_req_mgr_cb_notify_trigger( dev_data.timestamp - link->sof_timestamp : link->sof_timestamp - dev_data.timestamp; - threshold = frame_duration / THRESHOLD_FACTOR; /* Checking if master and sync links are in * same frame duration considering master frame * duration in calculating threshold value */ + + if (trigger_data->fps == 0) { + frame_duration = + link->fps * MILLI_SECOND_CONVERSION_FACTOR; + if (link->retry_threshold) { + /* Increase threshold value by dividing frame + * duration with 2, so that sync logic get chance + * to reduce sof time difference in next 3 requests. + */ + link->retry_threshold -= 1; + threshold = frame_duration / THRESHOLD_FACTOR_2; + } else { + /* Normal threshold calculation by dividing frame + * duration with 3 + */ + threshold = frame_duration / THRESHOLD_FACTOR_3; + } + } else if (trigger_data->fps == -1) { + //Frame duration based on epoch-sof calculation + if (link->retry_threshold) { + /* Increase threshold value by dividing frame + * duration with 2 + */ + link->retry_threshold -= 1; + threshold = frame_duration / THRESHOLD_FACTOR_2; + } else { + /* Normal threshold calculation by dividing frame + * duration with 3 + */ + threshold = frame_duration / THRESHOLD_FACTOR_3; + } + } else { + link->fps = trigger_data->fps; + frame_duration = + trigger_data->fps * MILLI_SECOND_CONVERSION_FACTOR; + if (link->retry_threshold) { + /* Increase threshold value by dividing frame + * duration with 2 + */ + link->retry_threshold -= 1; + threshold = frame_duration / THRESHOLD_FACTOR_2; + } else { + /* Normal threshold calculation by dividing frame + * duration with 3 + */ + threshold = frame_duration / THRESHOLD_FACTOR_3; + } + } + if (curr_sync_time > threshold) { struct cam_req_mgr_dump_link_data dump_info; - CAM_DBG(CAM_CRM, - "Master %x and slave %x are not in same time frame time diff %lld threshold %lld", + + link->retry_threshold = 3; + CAM_INFO_RATE_LIMIT(CAM_CRM, + "Master %x and slave %x sof diff is more than threshold: time diff %lld threshold %lld fps %d bootime %lld", link->link_hdl, link->sync_link[i]->link_hdl, - curr_sync_time/1000000, - threshold/1000000); + curr_sync_time / MILLI_SECOND_CONVERSION_FACTOR, + threshold / MILLI_SECOND_CONVERSION_FACTOR, + trigger_data->fps, + (curr_boot_timestamp / + MILLI_SECOND_CONVERSION_FACTOR)); dump_info.m_link = link; dump_info.s_link = link->sync_link[i]; @@ -3780,7 +3886,7 @@ static int cam_req_mgr_cb_notify_trigger( struct cam_req_mgr_dump_link_data dump_info; - CAM_DBG(CAM_CRM, + CAM_INFO_RATE_LIMIT(CAM_CRM, "Req diff %lld Master link %x req %lld slave link %x req %lld", req_diff, link->link_hdl, @@ -4003,7 +4109,7 @@ slave: tmp_slot->real_sync_mode != CAM_REQ_MGR_SYNC_MODE_SYNC)) { CAM_DBG(CAM_CRM, - "In sync mode req %lld tmp mode % real mode %d sync mode %d link %x ", + "In sync mode req %lld tmp mode %d real mode %d sync mode %d link %x ", slot->req_id, tmp_slot->sync_mode, tmp_slot->real_sync_mode, slot->sync_mode, link->link_hdl); @@ -4062,6 +4168,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = { .add_req = cam_req_mgr_cb_add_req, .notify_timer = cam_req_mgr_cb_notify_timer, .notify_stop = cam_req_mgr_cb_notify_stop, + .notify_rup = cam_req_mgr_cb_notify_rup, }; /** @@ -4770,43 +4877,47 @@ static void __cam_req_mgr_set_master_link( int32_t num_of_links) { int i = 0, j = 0, k = 0; - int idx = -1; - - idx = find_first_bit(g_crm_core_dev->bitmap, - MAXIMUM_LINKS_PER_SESSION); + int master_link_idx = 0; + int max_isp = -1, min_isp = MAX_LINKS_PER_SESSION + 1; + int min_isp_link_idx = 0, max_isp_link_idx = 0; + struct cam_req_mgr_connected_device *dev = NULL; for (i = 0; i < num_of_links; i++) { - - CAM_DBG(CAM_CRM, "idx %d, link%d 0x%x active seq %d", - idx, i, link[i]->link_hdl, - link[i]->activate_seq); - - if (link[i]->activate_seq == idx) { - - link[i]->is_master = true; - CAM_DBG(CAM_CRM, "Master link 0x%x num of links %d ", - link[i]->link_hdl, num_of_links); - - for (j = 0, k = 0; j < num_of_links; j++) { - if (link[i]->link_hdl != - link[j]->link_hdl) { - - link[i]->sync_link[k] = link[j]; - link[i]->num_sync_link++; - - link[j]->sync_link[0] = link[i]; - link[j]->num_sync_link = 1; - link[j]->is_master = false; - - k++; - } - } + for (j = 0; j < link[i]->num_devs; j++) { + dev = &link[i]->l_dev[j]; + if (strcmp("cam-isp", dev->dev_info.name) == 0) + link[i]->num_isp_dev++; } + if (max_isp < link[i]->num_isp_dev) { + max_isp = link[i]->num_isp_dev; + max_isp_link_idx = i; + } + if (min_isp > link[i]->num_isp_dev) { + min_isp = link[i]->num_isp_dev; + min_isp_link_idx = i; + } + + if (link[master_link_idx]->activate_seq > link[i]->activate_seq) + master_link_idx = i; + } + + if (max_isp != min_isp) + master_link_idx = min_isp_link_idx; + + link[master_link_idx]->is_master = true; + CAM_DBG(CAM_CRM, "Master link %x ", link[master_link_idx]->link_hdl); + + for (i = 0; i < num_of_links; i++) { + if (i != master_link_idx) { + link[i]->is_master = false; + link[i]->sync_link[0] = link[master_link_idx]; + link[i]->num_sync_link = 1; + link[master_link_idx]->sync_link[k++] = link[i]; + link[master_link_idx]->num_sync_link++; + } link[i]->initial_skip = g_crm_core_dev->max_delay - link[i]->max_delay; - CAM_DBG(CAM_CRM, "link %x initial skip %d", - link[i]->link_hdl, link[i]->initial_skip); } } diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.h b/drivers/cam_req_mgr/cam_req_mgr_core.h index 9808cb0b31..13ac9b5d87 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/cam_req_mgr/cam_req_mgr_core.h @@ -394,6 +394,9 @@ struct cam_req_mgr_connected_device { * @frame_id : current frame id * @sync_frame_id : current frame id of sync link * @bubble_skip : req to skip on bubble + * @num_isp_dev : number of isp dev in a link + * @retry_threshold : number of times to retry apply on increased threshold + * @fps : current frame rate */ struct cam_req_mgr_core_link { int32_t link_hdl; @@ -439,6 +442,9 @@ struct cam_req_mgr_core_link { uint64_t sync_frame_id; int32_t bubble_skip; bool skip_sync_apply; + uint32_t num_isp_dev; + uint32_t retry_threshold; + uint32_t fps; }; /** diff --git a/drivers/cam_req_mgr/cam_req_mgr_interface.h b/drivers/cam_req_mgr/cam_req_mgr_interface.h index e8e4f941a3..4be12ccf63 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_interface.h +++ b/drivers/cam_req_mgr/cam_req_mgr_interface.h @@ -12,6 +12,7 @@ #include "cam_req_mgr_util.h" struct cam_req_mgr_trigger_notify; +struct cam_req_mgr_notify_rup; struct cam_req_mgr_error_notify; struct cam_req_mgr_add_request; struct cam_req_mgr_timer_notify; @@ -23,19 +24,21 @@ struct cam_req_mgr_flush_request; struct cam_req_mgr_link_evt_data; struct cam_req_mgr_dump_info; struct cam_req_mgr_request_change_state; +struct cam_req_mgr_signal_info; /* Request Manager -- camera device driver interface */ /** * @brief: camera kernel drivers to cam req mgr communication * * @cam_req_mgr_notify_trigger: for device which generates trigger to inform CRM + * @cam_req_mgr_notify_rup : for device which generates reg update trigger to inform CRM * @cam_req_mgr_notify_err : device use this to inform about different errors * @cam_req_mgr_add_req : to info CRM about new rqeuest received from * userspace * @cam_req_mgr_notify_timer : start the timer */ -typedef int (*cam_req_mgr_notify_trigger)( - struct cam_req_mgr_trigger_notify *); +typedef int (*cam_req_mgr_notify_trigger)(struct cam_req_mgr_trigger_notify *); +typedef int (*cam_req_mgr_notify_rup)(struct cam_req_mgr_notify_rup *); typedef bool (*cam_req_mgr_notify_err)(struct cam_req_mgr_error_notify *); typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *); typedef int (*cam_req_mgr_notify_timer)(struct cam_req_mgr_timer_notify *); @@ -62,8 +65,8 @@ typedef int (*cam_req_mgr_notify_frame_skip)( typedef int (*cam_req_mgr_flush_req)(struct cam_req_mgr_flush_request *); typedef int (*cam_req_mgr_process_evt)(struct cam_req_mgr_link_evt_data *); typedef int (*cam_req_mgr_dump_req)(struct cam_req_mgr_dump_info *); -typedef int (*cam_req_mgr_change_state)( - struct cam_req_mgr_request_change_state *); +typedef int (*cam_req_mgr_change_state)(struct cam_req_mgr_request_change_state *); +typedef int (*cam_req_mgr_signal_buf_done)(struct cam_req_mgr_signal_info *); /** * @brief : cam_req_mgr_crm_cb - func table @@ -73,6 +76,7 @@ typedef int (*cam_req_mgr_change_state)( * @add_req : payload to inform which device and what request is received * @notify_timer : payload for timer start event * @notify_stop : payload to inform stop event + * @notify_rup : payload to inform reg update ack */ struct cam_req_mgr_crm_cb { cam_req_mgr_notify_trigger notify_trigger; @@ -80,6 +84,7 @@ struct cam_req_mgr_crm_cb { cam_req_mgr_add_req add_req; cam_req_mgr_notify_timer notify_timer; cam_req_mgr_notify_stop notify_stop; + cam_req_mgr_notify_rup notify_rup; }; /** @@ -103,6 +108,7 @@ struct cam_req_mgr_kmd_ops { cam_req_mgr_process_evt process_evt; cam_req_mgr_dump_req dump_req; cam_req_mgr_change_state change_state; + cam_req_mgr_signal_buf_done signal_buf_done; }; /** @@ -215,6 +221,17 @@ enum cam_req_mgr_link_evt_type { CAM_REQ_MGR_LINK_EVT_MAX, }; +/** + * enum cam_req_mgr_buf_done_state + * @INIT_BUF_DONE : Initial buf done state of a request + * @SIGNAL_SYNC_BUF_DONE : Ready to signal buf done of a request if in sync mode + * @SIGNAL_NON_SYNC_BUF_DONE : Ready to signal buf done of a request if in non sync mode + */ +enum cam_req_mgr_buf_done_state { + INIT_BUF_DONE, + SIGNAL_SYNC_BUF_DONE, +}; + /** * struct cam_req_mgr_trigger_notify * @link_hdl : link identifier @@ -226,6 +243,7 @@ enum cam_req_mgr_link_evt_type { * @sof_boottime : Captured boot time stamp value at sof hw event * @req_id : req id which returned buf_done * @trigger_id: ID to differentiate between the trigger devices + * @fps : Current fps value */ struct cam_req_mgr_trigger_notify { int32_t link_hdl; @@ -236,6 +254,19 @@ struct cam_req_mgr_trigger_notify { uint64_t sof_boottime; uint64_t req_id; int32_t trigger_id; + uint32_t fps; +}; + +/** + * struct cam_req_mgr_notify_rup + * @link_hdl : link identifier + * @req_id : req id which returned reg update ack + * @state : buf done ready state of the request + */ +struct cam_req_mgr_notify_rup { + int32_t link_hdl; + uint64_t req_id; + int32_t state; }; /** @@ -353,6 +384,7 @@ struct cam_req_mgr_core_dev_link_setup { * @report_if_bubble : report to crm if failure in applying * @trigger_point : the trigger point of this apply * @re_apply : to skip re_apply for buf_done request + * @is_sync_mode : if request need to be apply in sync with other link * */ struct cam_req_mgr_apply_request { @@ -362,6 +394,7 @@ struct cam_req_mgr_apply_request { int32_t report_if_bubble; uint32_t trigger_point; bool re_apply; + bool is_sync_mode; }; /** @@ -456,4 +489,19 @@ struct cam_req_mgr_request_change_state { uint64_t req_id; }; +/** + * struct cam_req_mgr_signal_info + * @link_hdl : link identifier + * @dev_hdl : device handle or identifier + * req_id : request id to be set for buf done ready + * state : Buf done ready state of a request + * + */ +struct cam_req_mgr_signal_info { + int32_t link_hdl; + int32_t dev_hdl; + uint64_t req_id; + int32_t state; +}; + #endif diff --git a/include/uapi/camera/media/cam_isp.h b/include/uapi/camera/media/cam_isp.h index 5716aea8bf..42a5071b3b 100644 --- a/include/uapi/camera/media/cam_isp.h +++ b/include/uapi/camera/media/cam_isp.h @@ -122,6 +122,7 @@ #define CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG 14 #define CAM_ISP_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH 15 #define CAM_ISP_GENERIC_BLOB_TYPE_BW_LIMITER_CFG 16 +#define CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG 17 #define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CLOCK_CONFIG 21 #define CAM_ISP_GENERIC_BLOB_TYPE_SFE_CORE_CONFIG 22 #define CAM_ISP_GENERIC_BLOB_TYPE_SFE_OUT_CONFIG 23 @@ -822,6 +823,18 @@ struct cam_isp_acquire_hw_info { __u64 data; }; +/** + * struct cam_fps_config - FPS info per request + * + * @fps : Fps value + * @reserved: : Reserved field for alignment + * + */ +struct cam_fps_config { + __u32 fps; + __u32 reserved_params[3]; +} __attribute__((packed)); + /** * struct cam_isp_vfe_wm_config - VFE write master config per port *