Loading drivers/cam_cust/cam_custom_context.c +357 −31 Original line number Diff line number Diff line Loading @@ -27,6 +27,258 @@ static int __cam_custom_ctx_handle_irq_in_activated( static int __cam_custom_ctx_start_dev_in_ready( struct cam_context *ctx, struct cam_start_stop_dev_cmd *cmd); static int __cam_custom_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, uint32_t next_state); static int __cam_custom_ctx_apply_default_settings( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply); static int __cam_custom_ctx_apply_req_in_activated( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) { int rc = 0; struct cam_custom_context *custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; rc = __cam_custom_ctx_apply_req_in_activated_state( ctx, apply, CAM_CUSTOM_CTX_ACTIVATED_APPLIED); CAM_DBG(CAM_CUSTOM, "new substate %d", custom_ctx->substate_activated); if (rc) CAM_ERR(CAM_CUSTOM, "Apply failed in state %d rc %d", custom_ctx->substate_activated, rc); return rc; } static int __cam_custom_ctx_handle_error( struct cam_custom_context *custom_ctx, void *evt_data) { /* * Handle any HW error scenerios here, all the * requests in all the lists can be signaled error. * Notify UMD about this error if needed. */ return 0; } static int __cam_custom_ctx_reg_upd_in_sof( struct cam_custom_context *custom_ctx, void *evt_data) { struct cam_ctx_request *req = NULL; struct cam_custom_dev_ctx_req *req_custom; struct cam_context *ctx = custom_ctx->base; custom_ctx->frame_id++; /* * This is for the first update before streamon. * The initial setting will cause the reg_upd in the * first frame. */ if (!list_empty(&ctx->wait_req_list)) { req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); list_del_init(&req->list); req_custom = (struct cam_custom_dev_ctx_req *) req->req_priv; if (req_custom->num_fence_map_out == req_custom->num_acked) { list_add_tail(&req->list, &ctx->free_req_list); } else { list_add_tail(&req->list, &ctx->active_req_list); custom_ctx->active_req_cnt++; CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d), ctx %u", req->request_id, custom_ctx->active_req_cnt, ctx->ctx_id); } } return 0; } static int __cam_custom_ctx_reg_upd_in_applied_state( struct cam_custom_context *custom_ctx, void *evt_data) { struct cam_ctx_request *req; struct cam_context *ctx = custom_ctx->base; struct cam_custom_dev_ctx_req *req_custom; custom_ctx->frame_id++; if (list_empty(&ctx->wait_req_list)) { CAM_ERR(CAM_CUSTOM, "Reg upd ack with no waiting request"); goto end; } req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); list_del_init(&req->list); req_custom = (struct cam_custom_dev_ctx_req *) req->req_priv; if (req_custom->num_fence_map_out != 0) { list_add_tail(&req->list, &ctx->active_req_list); custom_ctx->active_req_cnt++; CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d), ctx %u", req->request_id, custom_ctx->active_req_cnt, ctx->ctx_id); } 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, custom_ctx->active_req_cnt, ctx->ctx_id); } custom_ctx->substate_activated = CAM_CUSTOM_CTX_ACTIVATED_SOF; CAM_DBG(CAM_CUSTOM, "next substate %d", custom_ctx->substate_activated); end: return 0; } static int __cam_custom_ctx_frame_done( struct cam_custom_context *custom_ctx, void *evt_data) { int rc = 0, i, j; uint64_t frame_done_req_id; struct cam_ctx_request *req; struct cam_custom_dev_ctx_req *req_custom; struct cam_context *ctx = custom_ctx->base; struct cam_custom_hw_done_event_data *done_data = (struct cam_custom_hw_done_event_data *)evt_data; if (list_empty(&ctx->active_req_list)) { CAM_DBG(CAM_CUSTOM, "Frame done with no active request"); return 0; } req = list_first_entry(&ctx->active_req_list, struct cam_ctx_request, list); req_custom = req->req_priv; for (i = 0; i < done_data->num_handles; i++) { for (j = 0; j < req_custom->num_fence_map_out; j++) { if (done_data->resource_handle[i] == req_custom->fence_map_out[j].resource_handle) break; } if (j == req_custom->num_fence_map_out) { CAM_ERR(CAM_CUSTOM, "Can not find matching rsrc handle 0x%x!", done_data->resource_handle[i]); rc = -EINVAL; continue; } if (req_custom->fence_map_out[j].sync_id == -1) { CAM_WARN(CAM_CUSTOM, "Duplicate frame done for req %lld", req->request_id); continue; } rc = cam_sync_signal(req_custom->fence_map_out[j].sync_id, CAM_SYNC_STATE_SIGNALED_SUCCESS); if (rc) CAM_ERR(CAM_CUSTOM, "Sync failed with rc = %d", rc); req_custom->num_acked++; req_custom->fence_map_out[j].sync_id = -1; } if (req_custom->num_acked > req_custom->num_fence_map_out) { CAM_ERR(CAM_CUSTOM, "WARNING: req_id %lld num_acked %d > map_out %d, ctx %u", req->request_id, req_custom->num_acked, req_custom->num_fence_map_out, ctx->ctx_id); } if (req_custom->num_acked != req_custom->num_fence_map_out) return rc; custom_ctx->active_req_cnt--; frame_done_req_id = req->request_id; list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", frame_done_req_id, custom_ctx->active_req_cnt, ctx->ctx_id); return rc; } static struct cam_ctx_ops cam_custom_ctx_activated_state_machine [CAM_CUSTOM_CTX_ACTIVATED_MAX] = { /* SOF */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_custom_ctx_apply_req_in_activated, .apply_default = __cam_custom_ctx_apply_default_settings, }, .irq_ops = NULL, }, /* APPLIED */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_custom_ctx_apply_req_in_activated, .apply_default = __cam_custom_ctx_apply_default_settings, }, .irq_ops = NULL, }, /* HW ERROR */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* HALT */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, }; static struct cam_custom_ctx_irq_ops cam_custom_ctx_activated_state_machine_irq [CAM_CUSTOM_CTX_ACTIVATED_MAX] = { /* SOF */ { .irq_ops = { __cam_custom_ctx_handle_error, __cam_custom_ctx_reg_upd_in_sof, __cam_custom_ctx_frame_done, }, }, /* APPLIED */ { .irq_ops = { __cam_custom_ctx_handle_error, __cam_custom_ctx_reg_upd_in_applied_state, __cam_custom_ctx_frame_done, }, }, /* HW ERROR */ { .irq_ops = { NULL, NULL, NULL, }, }, /* HALT */ { }, }; static int __cam_custom_ctx_enqueue_request_in_order( struct cam_context *ctx, struct cam_ctx_request *req) Loading Loading @@ -484,7 +736,8 @@ static int __cam_custom_ctx_apply_default_settings( } static int __cam_custom_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, uint32_t next_state) { int rc = 0; struct cam_ctx_request *req; Loading @@ -499,6 +752,9 @@ static int __cam_custom_ctx_apply_req_in_activated_state( goto end; } if (!list_empty(&ctx->wait_req_list)) CAM_WARN(CAM_CUSTOM, "Apply invoked with a req in wait list"); custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; spin_lock_bh(&ctx->lock); req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, Loading Loading @@ -531,19 +787,10 @@ static int __cam_custom_ctx_apply_req_in_activated_state( "Can not apply the configuration"); } else { spin_lock_bh(&ctx->lock); custom_ctx->substate_activated = next_state; list_del_init(&req->list); if (!req->num_out_map_entries) { list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->wait_req_list); spin_unlock_bh(&ctx->lock); } else { list_add_tail(&req->list, &ctx->active_req_list); spin_unlock_bh(&ctx->lock); /* * for test purposes only-this should be * triggered based on irq */ __cam_custom_ctx_handle_irq_in_activated(ctx, 0, NULL); } } end: Loading Loading @@ -610,6 +857,10 @@ static int __cam_custom_ctx_acquire_hw_v1( goto free_res; } ctx_custom->substate_machine_irq = cam_custom_ctx_activated_state_machine_irq; ctx_custom->substate_machine = cam_custom_ctx_activated_state_machine; ctx_custom->hw_ctx = param.ctxt_to_hw_map; ctx_custom->hw_acquired = true; ctx->ctxt_to_hw_map = param.ctxt_to_hw_map; Loading Loading @@ -808,7 +1059,9 @@ static int __cam_custom_ctx_config_dev(struct cam_context *ctx, cfg.packet = packet; cfg.ctxt_to_hw_map = ctx_custom->hw_ctx; cfg.out_map_entries = req_custom->fence_map_out; cfg.max_out_map_entries = CAM_CUSTOM_DEV_CTX_RES_MAX; cfg.in_map_entries = req_custom->fence_map_in; cfg.max_in_map_entries = CAM_CUSTOM_DEV_CTX_RES_MAX; cfg.priv = &req_custom->hw_update_data; cfg.pf_data = &(req->pf_data); Loading @@ -824,6 +1077,7 @@ static int __cam_custom_ctx_config_dev(struct cam_context *ctx, req_custom->num_fence_map_out = cfg.num_out_map_entries; req_custom->num_fence_map_in = cfg.num_in_map_entries; req_custom->num_acked = 0; req_custom->hw_update_data.num_cfg = cfg.num_out_map_entries; for (i = 0; i < req_custom->num_fence_map_out; i++) { rc = cam_sync_get_obj_ref(req_custom->fence_map_out[i].sync_id); Loading Loading @@ -1025,6 +1279,13 @@ static int __cam_custom_ctx_start_dev_in_ready(struct cam_context *ctx, else custom_start.start_only = false; ctx_custom->frame_id = 0; ctx_custom->active_req_cnt = 0; ctx_custom->substate_activated = (req_custom->num_fence_map_out) ? CAM_CUSTOM_CTX_ACTIVATED_APPLIED : CAM_CUSTOM_CTX_ACTIVATED_SOF; ctx->state = CAM_CTX_ACTIVATED; rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv, &custom_start); Loading @@ -1040,10 +1301,7 @@ static int __cam_custom_ctx_start_dev_in_ready(struct cam_context *ctx, spin_lock_bh(&ctx->lock); list_del_init(&req->list); if (req_custom->num_fence_map_out) list_add_tail(&req->list, &ctx->active_req_list); else list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->wait_req_list); spin_unlock_bh(&ctx->lock); end: Loading Loading @@ -1103,20 +1361,28 @@ static int __cam_custom_ctx_process_evt(struct cam_context *ctx, static int __cam_custom_ctx_handle_irq_in_activated(void *context, uint32_t evt_id, void *evt_data) { int rc; struct cam_context *ctx = (struct cam_context *)context; int rc = 0; struct cam_custom_ctx_irq_ops *custom_irq_ops = NULL; struct cam_context *ctx = (struct cam_context *)context; struct cam_custom_context *ctx_custom = (struct cam_custom_context *)ctx->ctx_priv; CAM_DBG(CAM_CUSTOM, "Enter %d", ctx->ctx_id); spin_lock(&ctx->lock); CAM_DBG(CAM_CUSTOM, "Enter: State %d, Substate %d, evt id %d", ctx->state, ctx_custom->substate_activated, evt_id); custom_irq_ops = &ctx_custom->substate_machine_irq[ ctx_custom->substate_activated]; if (custom_irq_ops->irq_ops[evt_id]) rc = custom_irq_ops->irq_ops[evt_id](ctx_custom, evt_data); else CAM_DBG(CAM_CUSTOM, "No handle function for substate %d", ctx_custom->substate_activated); /* * handle based on different irq's currently * triggering only buf done if there are fences */ rc = cam_context_buf_done_from_hw(ctx, evt_data, 0); if (rc) CAM_ERR(CAM_CUSTOM, "Failed in buf done, rc=%d", rc); CAM_DBG(CAM_CUSTOM, "Exit: State %d Substate %d", ctx->state, ctx_custom->substate_activated); spin_unlock(&ctx->lock); return rc; } Loading @@ -1141,6 +1407,67 @@ static int __cam_custom_ctx_acquire_hw_in_acquired( return rc; } static int __cam_custom_ctx_apply_req(struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) { int rc = 0; struct cam_ctx_ops *ctx_ops = NULL; struct cam_custom_context *custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; CAM_DBG(CAM_CUSTOM, "Enter: apply req in Substate %d request _id:%lld", custom_ctx->substate_activated, apply->request_id); ctx_ops = &custom_ctx->substate_machine[ custom_ctx->substate_activated]; if (ctx_ops->crm_ops.apply_req) { rc = ctx_ops->crm_ops.apply_req(ctx, apply); } else { CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "No handle function in activated substate %d", custom_ctx->substate_activated); rc = -EFAULT; } if (rc) CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "Apply failed in active substate %d rc %d", custom_ctx->substate_activated, rc); return rc; } static int __cam_custom_ctx_apply_default_req( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) { int rc = 0; struct cam_ctx_ops *ctx_ops = NULL; struct cam_custom_context *custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; CAM_DBG(CAM_CUSTOM, "Enter: apply req in Substate %d request _id:%lld", custom_ctx->substate_activated, apply->request_id); ctx_ops = &custom_ctx->substate_machine[ custom_ctx->substate_activated]; if (ctx_ops->crm_ops.apply_default) { rc = ctx_ops->crm_ops.apply_default(ctx, apply); } else { CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "No handle function in activated substate %d", custom_ctx->substate_activated); rc = -EFAULT; } if (rc) CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "Apply default failed in active substate %d rc %d", custom_ctx->substate_activated, rc); return rc; } /* top state machine */ static struct cam_ctx_ops cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = { Loading Loading @@ -1219,10 +1546,9 @@ static struct cam_ctx_ops }, .crm_ops = { .unlink = __cam_custom_ctx_unlink_in_activated, .apply_req = __cam_custom_ctx_apply_req_in_activated_state, .apply_req = __cam_custom_ctx_apply_req, .apply_default = __cam_custom_ctx_apply_default_settings, __cam_custom_ctx_apply_default_req, .flush_req = __cam_custom_ctx_flush_req_in_top_state, .process_evt = __cam_custom_ctx_process_evt, }, Loading drivers/cam_cust/cam_custom_context.h +44 −12 Original line number Diff line number Diff line Loading @@ -19,13 +19,39 @@ * output port resource. The current maximum resource number * is 2. */ #define CAM_CUSTOM_DEV_CTX_RES_MAX 2 #define CAM_CUSTOM_DEV_CTX_RES_MAX 1 #define CAM_CUSTOM_CTX_CFG_MAX 8 /* forward declaration */ struct cam_custom_context; /* cam custom context irq handling function type */ typedef int (*cam_custom_hw_event_cb_func)( struct cam_custom_context *custom_ctx, void *evt_data); /** * enum cam_custom_ctx_activated_substate - sub states for activated * */ enum cam_custom_ctx_activated_substate { CAM_CUSTOM_CTX_ACTIVATED_SOF, CAM_CUSTOM_CTX_ACTIVATED_APPLIED, CAM_CUSTOM_CTX_ACTIVATED_HW_ERROR, CAM_CUSTOM_CTX_ACTIVATED_HALT, CAM_CUSTOM_CTX_ACTIVATED_MAX, }; /** * struct cam_custom_ctx_irq_ops - Function table for handling IRQ callbacks * * @irq_ops: Array of handle function pointers. * */ struct cam_custom_ctx_irq_ops { cam_custom_hw_event_cb_func irq_ops[CAM_CUSTOM_HW_EVENT_MAX]; }; /** * struct cam_custom_dev_ctx_req - Custom context request object * Loading Loading @@ -69,6 +95,9 @@ struct cam_custom_dev_ctx_req { * @active_req_cnt: Counter for the active request * @frame_id: Frame id tracking for the custom context * @hw_acquired: Flag to indicate if HW is acquired for this context * @substate_actiavted: Current substate for the activated state. * @substate_machine: Custom substate machine for external interface * @substate_machine_irq: Custom substate machine for irq handling * @req_base: common request structure * @req_custom: custom request structure * Loading @@ -83,6 +112,9 @@ struct cam_custom_context { uint32_t active_req_cnt; int64_t frame_id; bool hw_acquired; uint32_t substate_activated; struct cam_ctx_ops *substate_machine; struct cam_custom_ctx_irq_ops *substate_machine_irq; struct cam_ctx_request req_base[CAM_CTX_REQ_MAX]; struct cam_custom_dev_ctx_req req_custom[CAM_CTX_REQ_MAX]; }; Loading drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_core.c +1 −3 Original line number Diff line number Diff line Loading @@ -283,8 +283,6 @@ irqreturn_t cam_custom_hw_sub_mod_irq(int irq_num, void *data) core_info->device_hw_info->irq_clear); spin_lock(&custom_dev->hw_lock); cb_args.irq_status = irq_status; cb_args.req_info = core_info->curr_req; core_info->curr_req = NULL; if (core_info->irq_cb.custom_hw_mgr_cb) core_info->irq_cb.custom_hw_mgr_cb( Loading Loading @@ -315,7 +313,7 @@ int cam_custom_hw_sub_mod_process_cmd(void *hw_priv, uint32_t cmd_type, switch (cmd_type) { case CAM_CUSTOM_SET_IRQ_CB: { struct cam_custom_sub_mod_set_irq_cb *irq_cb = cmd_args; /* This can be deprecated */ CAM_DBG(CAM_CUSTOM, "Setting irq cb"); spin_lock_irqsave(&hw->hw_lock, flag); core_info->irq_cb.custom_hw_mgr_cb = irq_cb->custom_hw_mgr_cb; Loading drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_core.h +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ enum cam_custom_hw_resource_type { struct cam_custom_sub_mod_acq { enum cam_custom_hw_resource_type rsrc_type; int32_t acq; cam_hw_mgr_event_cb_func event_cb; void *priv; struct cam_custom_resource_node *rsrc_node; }; Loading drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c +179 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
drivers/cam_cust/cam_custom_context.c +357 −31 Original line number Diff line number Diff line Loading @@ -27,6 +27,258 @@ static int __cam_custom_ctx_handle_irq_in_activated( static int __cam_custom_ctx_start_dev_in_ready( struct cam_context *ctx, struct cam_start_stop_dev_cmd *cmd); static int __cam_custom_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, uint32_t next_state); static int __cam_custom_ctx_apply_default_settings( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply); static int __cam_custom_ctx_apply_req_in_activated( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) { int rc = 0; struct cam_custom_context *custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; rc = __cam_custom_ctx_apply_req_in_activated_state( ctx, apply, CAM_CUSTOM_CTX_ACTIVATED_APPLIED); CAM_DBG(CAM_CUSTOM, "new substate %d", custom_ctx->substate_activated); if (rc) CAM_ERR(CAM_CUSTOM, "Apply failed in state %d rc %d", custom_ctx->substate_activated, rc); return rc; } static int __cam_custom_ctx_handle_error( struct cam_custom_context *custom_ctx, void *evt_data) { /* * Handle any HW error scenerios here, all the * requests in all the lists can be signaled error. * Notify UMD about this error if needed. */ return 0; } static int __cam_custom_ctx_reg_upd_in_sof( struct cam_custom_context *custom_ctx, void *evt_data) { struct cam_ctx_request *req = NULL; struct cam_custom_dev_ctx_req *req_custom; struct cam_context *ctx = custom_ctx->base; custom_ctx->frame_id++; /* * This is for the first update before streamon. * The initial setting will cause the reg_upd in the * first frame. */ if (!list_empty(&ctx->wait_req_list)) { req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); list_del_init(&req->list); req_custom = (struct cam_custom_dev_ctx_req *) req->req_priv; if (req_custom->num_fence_map_out == req_custom->num_acked) { list_add_tail(&req->list, &ctx->free_req_list); } else { list_add_tail(&req->list, &ctx->active_req_list); custom_ctx->active_req_cnt++; CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d), ctx %u", req->request_id, custom_ctx->active_req_cnt, ctx->ctx_id); } } return 0; } static int __cam_custom_ctx_reg_upd_in_applied_state( struct cam_custom_context *custom_ctx, void *evt_data) { struct cam_ctx_request *req; struct cam_context *ctx = custom_ctx->base; struct cam_custom_dev_ctx_req *req_custom; custom_ctx->frame_id++; if (list_empty(&ctx->wait_req_list)) { CAM_ERR(CAM_CUSTOM, "Reg upd ack with no waiting request"); goto end; } req = list_first_entry(&ctx->wait_req_list, struct cam_ctx_request, list); list_del_init(&req->list); req_custom = (struct cam_custom_dev_ctx_req *) req->req_priv; if (req_custom->num_fence_map_out != 0) { list_add_tail(&req->list, &ctx->active_req_list); custom_ctx->active_req_cnt++; CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d), ctx %u", req->request_id, custom_ctx->active_req_cnt, ctx->ctx_id); } 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, custom_ctx->active_req_cnt, ctx->ctx_id); } custom_ctx->substate_activated = CAM_CUSTOM_CTX_ACTIVATED_SOF; CAM_DBG(CAM_CUSTOM, "next substate %d", custom_ctx->substate_activated); end: return 0; } static int __cam_custom_ctx_frame_done( struct cam_custom_context *custom_ctx, void *evt_data) { int rc = 0, i, j; uint64_t frame_done_req_id; struct cam_ctx_request *req; struct cam_custom_dev_ctx_req *req_custom; struct cam_context *ctx = custom_ctx->base; struct cam_custom_hw_done_event_data *done_data = (struct cam_custom_hw_done_event_data *)evt_data; if (list_empty(&ctx->active_req_list)) { CAM_DBG(CAM_CUSTOM, "Frame done with no active request"); return 0; } req = list_first_entry(&ctx->active_req_list, struct cam_ctx_request, list); req_custom = req->req_priv; for (i = 0; i < done_data->num_handles; i++) { for (j = 0; j < req_custom->num_fence_map_out; j++) { if (done_data->resource_handle[i] == req_custom->fence_map_out[j].resource_handle) break; } if (j == req_custom->num_fence_map_out) { CAM_ERR(CAM_CUSTOM, "Can not find matching rsrc handle 0x%x!", done_data->resource_handle[i]); rc = -EINVAL; continue; } if (req_custom->fence_map_out[j].sync_id == -1) { CAM_WARN(CAM_CUSTOM, "Duplicate frame done for req %lld", req->request_id); continue; } rc = cam_sync_signal(req_custom->fence_map_out[j].sync_id, CAM_SYNC_STATE_SIGNALED_SUCCESS); if (rc) CAM_ERR(CAM_CUSTOM, "Sync failed with rc = %d", rc); req_custom->num_acked++; req_custom->fence_map_out[j].sync_id = -1; } if (req_custom->num_acked > req_custom->num_fence_map_out) { CAM_ERR(CAM_CUSTOM, "WARNING: req_id %lld num_acked %d > map_out %d, ctx %u", req->request_id, req_custom->num_acked, req_custom->num_fence_map_out, ctx->ctx_id); } if (req_custom->num_acked != req_custom->num_fence_map_out) return rc; custom_ctx->active_req_cnt--; frame_done_req_id = req->request_id; list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", frame_done_req_id, custom_ctx->active_req_cnt, ctx->ctx_id); return rc; } static struct cam_ctx_ops cam_custom_ctx_activated_state_machine [CAM_CUSTOM_CTX_ACTIVATED_MAX] = { /* SOF */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_custom_ctx_apply_req_in_activated, .apply_default = __cam_custom_ctx_apply_default_settings, }, .irq_ops = NULL, }, /* APPLIED */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_custom_ctx_apply_req_in_activated, .apply_default = __cam_custom_ctx_apply_default_settings, }, .irq_ops = NULL, }, /* HW ERROR */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* HALT */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, }; static struct cam_custom_ctx_irq_ops cam_custom_ctx_activated_state_machine_irq [CAM_CUSTOM_CTX_ACTIVATED_MAX] = { /* SOF */ { .irq_ops = { __cam_custom_ctx_handle_error, __cam_custom_ctx_reg_upd_in_sof, __cam_custom_ctx_frame_done, }, }, /* APPLIED */ { .irq_ops = { __cam_custom_ctx_handle_error, __cam_custom_ctx_reg_upd_in_applied_state, __cam_custom_ctx_frame_done, }, }, /* HW ERROR */ { .irq_ops = { NULL, NULL, NULL, }, }, /* HALT */ { }, }; static int __cam_custom_ctx_enqueue_request_in_order( struct cam_context *ctx, struct cam_ctx_request *req) Loading Loading @@ -484,7 +736,8 @@ static int __cam_custom_ctx_apply_default_settings( } static int __cam_custom_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, uint32_t next_state) { int rc = 0; struct cam_ctx_request *req; Loading @@ -499,6 +752,9 @@ static int __cam_custom_ctx_apply_req_in_activated_state( goto end; } if (!list_empty(&ctx->wait_req_list)) CAM_WARN(CAM_CUSTOM, "Apply invoked with a req in wait list"); custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; spin_lock_bh(&ctx->lock); req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, Loading Loading @@ -531,19 +787,10 @@ static int __cam_custom_ctx_apply_req_in_activated_state( "Can not apply the configuration"); } else { spin_lock_bh(&ctx->lock); custom_ctx->substate_activated = next_state; list_del_init(&req->list); if (!req->num_out_map_entries) { list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->wait_req_list); spin_unlock_bh(&ctx->lock); } else { list_add_tail(&req->list, &ctx->active_req_list); spin_unlock_bh(&ctx->lock); /* * for test purposes only-this should be * triggered based on irq */ __cam_custom_ctx_handle_irq_in_activated(ctx, 0, NULL); } } end: Loading Loading @@ -610,6 +857,10 @@ static int __cam_custom_ctx_acquire_hw_v1( goto free_res; } ctx_custom->substate_machine_irq = cam_custom_ctx_activated_state_machine_irq; ctx_custom->substate_machine = cam_custom_ctx_activated_state_machine; ctx_custom->hw_ctx = param.ctxt_to_hw_map; ctx_custom->hw_acquired = true; ctx->ctxt_to_hw_map = param.ctxt_to_hw_map; Loading Loading @@ -808,7 +1059,9 @@ static int __cam_custom_ctx_config_dev(struct cam_context *ctx, cfg.packet = packet; cfg.ctxt_to_hw_map = ctx_custom->hw_ctx; cfg.out_map_entries = req_custom->fence_map_out; cfg.max_out_map_entries = CAM_CUSTOM_DEV_CTX_RES_MAX; cfg.in_map_entries = req_custom->fence_map_in; cfg.max_in_map_entries = CAM_CUSTOM_DEV_CTX_RES_MAX; cfg.priv = &req_custom->hw_update_data; cfg.pf_data = &(req->pf_data); Loading @@ -824,6 +1077,7 @@ static int __cam_custom_ctx_config_dev(struct cam_context *ctx, req_custom->num_fence_map_out = cfg.num_out_map_entries; req_custom->num_fence_map_in = cfg.num_in_map_entries; req_custom->num_acked = 0; req_custom->hw_update_data.num_cfg = cfg.num_out_map_entries; for (i = 0; i < req_custom->num_fence_map_out; i++) { rc = cam_sync_get_obj_ref(req_custom->fence_map_out[i].sync_id); Loading Loading @@ -1025,6 +1279,13 @@ static int __cam_custom_ctx_start_dev_in_ready(struct cam_context *ctx, else custom_start.start_only = false; ctx_custom->frame_id = 0; ctx_custom->active_req_cnt = 0; ctx_custom->substate_activated = (req_custom->num_fence_map_out) ? CAM_CUSTOM_CTX_ACTIVATED_APPLIED : CAM_CUSTOM_CTX_ACTIVATED_SOF; ctx->state = CAM_CTX_ACTIVATED; rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv, &custom_start); Loading @@ -1040,10 +1301,7 @@ static int __cam_custom_ctx_start_dev_in_ready(struct cam_context *ctx, spin_lock_bh(&ctx->lock); list_del_init(&req->list); if (req_custom->num_fence_map_out) list_add_tail(&req->list, &ctx->active_req_list); else list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->wait_req_list); spin_unlock_bh(&ctx->lock); end: Loading Loading @@ -1103,20 +1361,28 @@ static int __cam_custom_ctx_process_evt(struct cam_context *ctx, static int __cam_custom_ctx_handle_irq_in_activated(void *context, uint32_t evt_id, void *evt_data) { int rc; struct cam_context *ctx = (struct cam_context *)context; int rc = 0; struct cam_custom_ctx_irq_ops *custom_irq_ops = NULL; struct cam_context *ctx = (struct cam_context *)context; struct cam_custom_context *ctx_custom = (struct cam_custom_context *)ctx->ctx_priv; CAM_DBG(CAM_CUSTOM, "Enter %d", ctx->ctx_id); spin_lock(&ctx->lock); CAM_DBG(CAM_CUSTOM, "Enter: State %d, Substate %d, evt id %d", ctx->state, ctx_custom->substate_activated, evt_id); custom_irq_ops = &ctx_custom->substate_machine_irq[ ctx_custom->substate_activated]; if (custom_irq_ops->irq_ops[evt_id]) rc = custom_irq_ops->irq_ops[evt_id](ctx_custom, evt_data); else CAM_DBG(CAM_CUSTOM, "No handle function for substate %d", ctx_custom->substate_activated); /* * handle based on different irq's currently * triggering only buf done if there are fences */ rc = cam_context_buf_done_from_hw(ctx, evt_data, 0); if (rc) CAM_ERR(CAM_CUSTOM, "Failed in buf done, rc=%d", rc); CAM_DBG(CAM_CUSTOM, "Exit: State %d Substate %d", ctx->state, ctx_custom->substate_activated); spin_unlock(&ctx->lock); return rc; } Loading @@ -1141,6 +1407,67 @@ static int __cam_custom_ctx_acquire_hw_in_acquired( return rc; } static int __cam_custom_ctx_apply_req(struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) { int rc = 0; struct cam_ctx_ops *ctx_ops = NULL; struct cam_custom_context *custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; CAM_DBG(CAM_CUSTOM, "Enter: apply req in Substate %d request _id:%lld", custom_ctx->substate_activated, apply->request_id); ctx_ops = &custom_ctx->substate_machine[ custom_ctx->substate_activated]; if (ctx_ops->crm_ops.apply_req) { rc = ctx_ops->crm_ops.apply_req(ctx, apply); } else { CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "No handle function in activated substate %d", custom_ctx->substate_activated); rc = -EFAULT; } if (rc) CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "Apply failed in active substate %d rc %d", custom_ctx->substate_activated, rc); return rc; } static int __cam_custom_ctx_apply_default_req( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) { int rc = 0; struct cam_ctx_ops *ctx_ops = NULL; struct cam_custom_context *custom_ctx = (struct cam_custom_context *) ctx->ctx_priv; CAM_DBG(CAM_CUSTOM, "Enter: apply req in Substate %d request _id:%lld", custom_ctx->substate_activated, apply->request_id); ctx_ops = &custom_ctx->substate_machine[ custom_ctx->substate_activated]; if (ctx_ops->crm_ops.apply_default) { rc = ctx_ops->crm_ops.apply_default(ctx, apply); } else { CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "No handle function in activated substate %d", custom_ctx->substate_activated); rc = -EFAULT; } if (rc) CAM_WARN_RATE_LIMIT(CAM_CUSTOM, "Apply default failed in active substate %d rc %d", custom_ctx->substate_activated, rc); return rc; } /* top state machine */ static struct cam_ctx_ops cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = { Loading Loading @@ -1219,10 +1546,9 @@ static struct cam_ctx_ops }, .crm_ops = { .unlink = __cam_custom_ctx_unlink_in_activated, .apply_req = __cam_custom_ctx_apply_req_in_activated_state, .apply_req = __cam_custom_ctx_apply_req, .apply_default = __cam_custom_ctx_apply_default_settings, __cam_custom_ctx_apply_default_req, .flush_req = __cam_custom_ctx_flush_req_in_top_state, .process_evt = __cam_custom_ctx_process_evt, }, Loading
drivers/cam_cust/cam_custom_context.h +44 −12 Original line number Diff line number Diff line Loading @@ -19,13 +19,39 @@ * output port resource. The current maximum resource number * is 2. */ #define CAM_CUSTOM_DEV_CTX_RES_MAX 2 #define CAM_CUSTOM_DEV_CTX_RES_MAX 1 #define CAM_CUSTOM_CTX_CFG_MAX 8 /* forward declaration */ struct cam_custom_context; /* cam custom context irq handling function type */ typedef int (*cam_custom_hw_event_cb_func)( struct cam_custom_context *custom_ctx, void *evt_data); /** * enum cam_custom_ctx_activated_substate - sub states for activated * */ enum cam_custom_ctx_activated_substate { CAM_CUSTOM_CTX_ACTIVATED_SOF, CAM_CUSTOM_CTX_ACTIVATED_APPLIED, CAM_CUSTOM_CTX_ACTIVATED_HW_ERROR, CAM_CUSTOM_CTX_ACTIVATED_HALT, CAM_CUSTOM_CTX_ACTIVATED_MAX, }; /** * struct cam_custom_ctx_irq_ops - Function table for handling IRQ callbacks * * @irq_ops: Array of handle function pointers. * */ struct cam_custom_ctx_irq_ops { cam_custom_hw_event_cb_func irq_ops[CAM_CUSTOM_HW_EVENT_MAX]; }; /** * struct cam_custom_dev_ctx_req - Custom context request object * Loading Loading @@ -69,6 +95,9 @@ struct cam_custom_dev_ctx_req { * @active_req_cnt: Counter for the active request * @frame_id: Frame id tracking for the custom context * @hw_acquired: Flag to indicate if HW is acquired for this context * @substate_actiavted: Current substate for the activated state. * @substate_machine: Custom substate machine for external interface * @substate_machine_irq: Custom substate machine for irq handling * @req_base: common request structure * @req_custom: custom request structure * Loading @@ -83,6 +112,9 @@ struct cam_custom_context { uint32_t active_req_cnt; int64_t frame_id; bool hw_acquired; uint32_t substate_activated; struct cam_ctx_ops *substate_machine; struct cam_custom_ctx_irq_ops *substate_machine_irq; struct cam_ctx_request req_base[CAM_CTX_REQ_MAX]; struct cam_custom_dev_ctx_req req_custom[CAM_CTX_REQ_MAX]; }; Loading
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_core.c +1 −3 Original line number Diff line number Diff line Loading @@ -283,8 +283,6 @@ irqreturn_t cam_custom_hw_sub_mod_irq(int irq_num, void *data) core_info->device_hw_info->irq_clear); spin_lock(&custom_dev->hw_lock); cb_args.irq_status = irq_status; cb_args.req_info = core_info->curr_req; core_info->curr_req = NULL; if (core_info->irq_cb.custom_hw_mgr_cb) core_info->irq_cb.custom_hw_mgr_cb( Loading Loading @@ -315,7 +313,7 @@ int cam_custom_hw_sub_mod_process_cmd(void *hw_priv, uint32_t cmd_type, switch (cmd_type) { case CAM_CUSTOM_SET_IRQ_CB: { struct cam_custom_sub_mod_set_irq_cb *irq_cb = cmd_args; /* This can be deprecated */ CAM_DBG(CAM_CUSTOM, "Setting irq cb"); spin_lock_irqsave(&hw->hw_lock, flag); core_info->irq_cb.custom_hw_mgr_cb = irq_cb->custom_hw_mgr_cb; Loading
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_core.h +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,8 @@ enum cam_custom_hw_resource_type { struct cam_custom_sub_mod_acq { enum cam_custom_hw_resource_type rsrc_type; int32_t acq; cam_hw_mgr_event_cb_func event_cb; void *priv; struct cam_custom_resource_node *rsrc_node; }; Loading
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw_mgr.c +179 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes