diff --git a/drivers/cam_core/cam_context.c b/drivers/cam_core/cam_context.c index b77b8d96c1..100ed22500 100644 --- a/drivers/cam_core/cam_context.c +++ b/drivers/cam_core/cam_context.c @@ -788,7 +788,7 @@ void cam_context_getref(struct cam_context *ctx) ctx->dev_name); } -int cam_context_add_err_inject(struct cam_context *ctx, void *err_param) +int cam_context_add_evt_inject(struct cam_context *ctx, void *evt_args) { int rc = 0; @@ -800,11 +800,11 @@ int cam_context_add_err_inject(struct cam_context *ctx, void *err_param) mutex_lock(&ctx->ctx_mutex); if ((ctx->state > CAM_CTX_AVAILABLE) && (ctx->state < CAM_CTX_STATE_MAX)) { - if (ctx->state_machine[ctx->state].err_inject_ops) { - rc = ctx->state_machine[ctx->state].err_inject_ops( - ctx, err_param); + if (ctx->state_machine[ctx->state].evt_inject_ops) { + rc = ctx->state_machine[ctx->state].evt_inject_ops( + ctx, evt_args); } else { - CAM_WARN(CAM_CORE, "No err inject ops in dev %d,state %d", + CAM_WARN(CAM_CORE, "No evt inject ops in dev %d, state %d", ctx->dev_hdl, ctx->state); } } else { diff --git a/drivers/cam_core/cam_context.h b/drivers/cam_core/cam_context.h index 035c5dab6d..e97247aff8 100644 --- a/drivers/cam_core/cam_context.h +++ b/drivers/cam_core/cam_context.h @@ -165,7 +165,7 @@ struct cam_ctx_crm_ops { * context info * @recovery_ops: Function to be invoked to try hardware recovery * @mini_dump_ops: Function for mini dump - * @err_inject_ops: Function for error injection + * @evt_inject_ops: Function for event injection * */ struct cam_ctx_ops { @@ -176,7 +176,7 @@ struct cam_ctx_ops { cam_ctx_info_dump_cb_func dumpinfo_ops; cam_ctx_recovery_cb_func recovery_ops; cam_ctx_mini_dump_cb_func mini_dump_ops; - cam_ctx_err_inject_cb_func err_inject_ops; + cam_ctx_err_inject_cb_func evt_inject_ops; }; @@ -601,16 +601,16 @@ void cam_context_putref(struct cam_context *ctx); void cam_context_getref(struct cam_context *ctx); /** - * cam_context_add_err_inject() + * cam_context_add_evt_inject() * - * @brief: Add error inject parameters through err_inject_ops. + * @brief: Add error inject parameters through evt_inject_ops. * - * @ctx: Context for which error is to be injected + * @ctx: Context for which error is to be injected * - * @err_param: Error injection parameters + * @inject_args: Event injection parameters * */ -int cam_context_add_err_inject(struct cam_context *ctx, - void *err_param); +int cam_context_add_evt_inject(struct cam_context *ctx, + void *inject_args); #endif /* _CAM_CONTEXT_H_ */ diff --git a/drivers/cam_core/cam_context_utils.c b/drivers/cam_core/cam_context_utils.c index 96c3cf34f1..18af013852 100644 --- a/drivers/cam_core/cam_context_utils.c +++ b/drivers/cam_core/cam_context_utils.c @@ -1744,21 +1744,126 @@ end: *bytes_updated = bytes_written; } -int cam_context_err_to_hw(struct cam_context *ctx, void *args) +static int cam_context_apply_buf_done_err_injection(struct cam_context *ctx, + struct cam_common_evt_inject_data *inject_evt) { - int rc = -EINVAL; + struct cam_hw_done_event_data *buf_done_data = inject_evt->buf_done_data; + int rc; - if (!ctx || !args) { - CAM_ERR(CAM_CTXT, "invalid params for error injection"); - return rc; + buf_done_data->evt_param = inject_evt->evt_params->u.buf_err_evt.sync_error; + rc = cam_context_buf_done_from_hw(ctx, buf_done_data, + CAM_CTX_EVT_ID_ERROR); + if (rc) + CAM_ERR(CAM_CTXT, + "Fail to apply buf done error injection with req id: %llu ctx id: %u rc: %d", + buf_done_data->request_id, ctx->ctx_id, rc); + + return rc; +} + +static int cam_context_apply_pf_evt_injection(struct cam_context *ctx, + struct cam_hw_inject_evt_param *evt_params) +{ + struct cam_hw_dump_pf_args pf_args = {0}; + struct cam_smmu_pf_info pf_info = {0}; + int rc; + + pf_args.pf_context_info.req_id = evt_params->req_id; + pf_args.pf_context_info.ctx_found = evt_params->u.evt_notify.u.pf_evt_params.ctx_found; + pf_args.pf_smmu_info = &pf_info; + + rc = cam_context_send_pf_evt(ctx, &pf_args); + if (rc) + CAM_ERR(CAM_CTXT, + "Fail to apply Page Fault event injection with req id: %llu ctx id: %u rc: %d", + evt_params->req_id, ctx->ctx_id, rc); + + return rc; +} + +static int cam_context_apply_node_event_injection(struct cam_context *ctx, + struct cam_hw_inject_evt_param *evt_params) +{ + struct cam_hw_inject_node_evt_param *node_evt_params = + &evt_params->u.evt_notify.u.node_evt_params; + struct cam_req_mgr_message req_msg = {0}; + int rc; + + req_msg.u.node_msg.request_id = evt_params->req_id; + req_msg.u.node_msg.link_hdl = ctx->link_hdl; + req_msg.u.node_msg.device_hdl = ctx->dev_hdl; + req_msg.u.node_msg.event_type = node_evt_params->event_type; + req_msg.u.node_msg.event_cause = node_evt_params->event_cause; + req_msg.session_hdl = ctx->session_hdl; + + rc = cam_req_mgr_notify_message(&req_msg, + V4L_EVENT_CAM_REQ_MGR_ERROR, V4L_EVENT_CAM_REQ_MGR_EVENT); + if (rc) + CAM_ERR(CAM_CTXT, + "Fail to apply error event injection with req id: %llu ctx id: %u rc: %d", + evt_params->req_id, ctx->ctx_id, rc); + + return rc; +} + +static int cam_context_apply_error_event_injection(struct cam_context *ctx, + struct cam_hw_inject_evt_param *evt_params) +{ + struct cam_hw_inject_err_evt_param *err_evt_params = + &evt_params->u.evt_notify.u.err_evt_params; + struct cam_req_mgr_message req_msg = {0}; + int rc; + + req_msg.u.err_msg.device_hdl = ctx->dev_hdl; + req_msg.u.err_msg.error_type = err_evt_params->err_type; + req_msg.u.err_msg.link_hdl = ctx->link_hdl; + req_msg.u.err_msg.request_id = evt_params->req_id; + req_msg.u.err_msg.resource_size = 0x0; + req_msg.u.err_msg.error_code = err_evt_params->err_code; + req_msg.session_hdl = ctx->session_hdl; + + rc = cam_req_mgr_notify_message(&req_msg, + V4L_EVENT_CAM_REQ_MGR_ERROR, V4L_EVENT_CAM_REQ_MGR_EVENT); + if (rc) + CAM_ERR(CAM_CTXT, + "Fail to apply V4L2 Node event injection with req id: %llu ctx id: %u rc: %d", + evt_params->req_id, ctx->ctx_id, rc); + + return rc; +} + +int cam_context_apply_evt_injection(struct cam_context *ctx, void *inject_evt_arg) +{ + struct cam_common_evt_inject_data *inject_evt; + struct cam_hw_inject_evt_param *evt_params; + uint32_t evt_notify_type; + int rc = 0; + + if (!ctx || !inject_evt_arg) { + CAM_ERR(CAM_CTXT, "Invalid parameters ctx %s inject evt args %s", + CAM_IS_NULL_TO_STR(ctx), CAM_IS_NULL_TO_STR(inject_evt_arg)); + return -EINVAL; } - if (ctx->hw_mgr_intf->hw_inject_err) { - ctx->hw_mgr_intf->hw_inject_err(ctx->ctxt_to_hw_map, args); - rc = 0; - } else { - CAM_ERR(CAM_CTXT, "hw_intf cb absent for dev hdl: %lld, ctx id: %lld", - ctx->dev_hdl, ctx->ctx_id); + inject_evt = inject_evt_arg; + evt_params = inject_evt->evt_params; + + switch (evt_params->inject_id) { + case CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE: + rc = cam_context_apply_buf_done_err_injection(ctx, inject_evt); + case CAM_COMMON_EVT_INJECT_NOTIFY_EVENT_TYPE: + evt_notify_type = evt_params->u.evt_notify.evt_notify_type; + switch (evt_notify_type) { + case V4L_EVENT_CAM_REQ_MGR_ERROR: + rc = cam_context_apply_error_event_injection(ctx, evt_params); + break; + case V4L_EVENT_CAM_REQ_MGR_PF_ERROR: + rc = cam_context_apply_pf_evt_injection(ctx, evt_params); + break; + case V4L_EVENT_CAM_REQ_MGR_NODE_EVENT: + rc = cam_context_apply_node_event_injection(ctx, evt_params); + break; + } } return rc; diff --git a/drivers/cam_core/cam_context_utils.h b/drivers/cam_core/cam_context_utils.h index 4b758352af..2832dff0bd 100644 --- a/drivers/cam_core/cam_context_utils.h +++ b/drivers/cam_core/cam_context_utils.h @@ -39,5 +39,5 @@ int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx, size_t cam_context_parse_config_cmd(struct cam_context *ctx, struct cam_config_dev_cmd *cmd, struct cam_packet **packet); int cam_context_mini_dump(struct cam_context *ctx, void *args); -int cam_context_err_to_hw(struct cam_context *ctx, void *args); +int cam_context_apply_evt_injection(struct cam_context *ctx, void *inject_evt_arg); #endif /* _CAM_CONTEXT_UTILS_H_ */ diff --git a/drivers/cam_core/cam_hw_mgr_intf.h b/drivers/cam_core/cam_hw_mgr_intf.h index 70b67f2ef4..bade63d31c 100644 --- a/drivers/cam_core/cam_hw_mgr_intf.h +++ b/drivers/cam_core/cam_hw_mgr_intf.h @@ -546,18 +546,76 @@ struct cam_hw_mini_dump_info { }; /** - * cam_hw_err_param - cam hHW error injection parameters + * cam_hw_inject_err_evt_param - error evt injection parameters * - * @err_type error type for the injected error - * @err_code error code for the injected error - * @err_req_id Req Id for which the error is injected - * @is_valid bool flag to indicate if error injection is enabled for a context + * @err_type: error type for the injected err evt + * @err_code: error code for the injected err evt */ -struct cam_hw_err_param { - uint32_t err_type; - uint32_t err_code; - uint64_t err_req_id; - bool is_valid; +struct cam_hw_inject_err_evt_param { + uint32_t err_type; + uint32_t err_code; +}; + +/** + * cam_hw_inject_node_evt_param - node evt injection parameters + * @event_type: event type for the injected node evt + * @event_cause: event cause for the injected node evt + */ +struct cam_hw_inject_node_evt_param { + uint32_t event_type; + uint32_t event_cause; +}; + +/** + * cam_hw_inject_pf_evt_param - pf evt injection parameters + * + * @ctx_found: flag to indicate if page fault notification sent with ctx or not + */ +struct cam_hw_inject_pf_evt_param { + bool ctx_found; +}; + +/** + * cam_hw_inject_evt_notification_param - notify event parameters + * + * @evt_notify_type: type of event notification + * @u: union which can be either error event/Page Fault event/Node event + */ + +struct cam_hw_inject_evt_notification_param { + uint32_t evt_notify_type; + union { + struct cam_hw_inject_err_evt_param err_evt_params; + struct cam_hw_inject_pf_evt_param pf_evt_params; + struct cam_hw_inject_node_evt_param node_evt_params; + } u; +}; + +/** + * cam_hw_inject_buffer_error_param - buffer error injection parameters + * + * @sync_error: sync error code + */ +struct cam_hw_inject_buffer_error_param { + uint32_t sync_error; +}; + +/** + * cam_hw_inject_evt_param - CRM event injection parameters + * + * @inject_id: generic inject identifier + * @req_id: Req Id for which the event is injected + * @u: union which can be either buffer done error/event notification + * @is_valid: bool flag to indicate if event injection is enabled for a context + */ +struct cam_hw_inject_evt_param { + uint8_t inject_id; + uint64_t req_id; + union { + struct cam_hw_inject_buffer_error_param buf_err_evt; + struct cam_hw_inject_evt_notification_param evt_notify; + } u; + bool is_valid; }; /** @@ -590,7 +648,7 @@ struct cam_hw_err_param { * @hw_reset: Function pointer for HW reset * @hw_dump: Function pointer for HW dump * @hw_recovery: Function pointer for HW recovery callback - * @hw_inject_err Function pointer for HW error injection callback + * @hw_inject_evt: Function pointer for HW event injection callback * */ struct cam_hw_mgr_intf { @@ -614,7 +672,7 @@ struct cam_hw_mgr_intf { int (*hw_reset)(void *hw_priv, void *hw_reset_args); int (*hw_dump)(void *hw_priv, void *hw_dump_args); int (*hw_recovery)(void *hw_priv, void *hw_recovery_args); - void (*hw_inject_err)(void *hw_priv, void *hw_err_inject_args); + void (*hw_inject_evt)(void *hw_priv, void *evt_args); }; #endif /* _CAM_HW_MGR_INTF_H_ */ diff --git a/drivers/cam_icp/cam_icp_context.c b/drivers/cam_icp/cam_icp_context.c index afc227b09c..d30da71c43 100644 --- a/drivers/cam_icp/cam_icp_context.c +++ b/drivers/cam_icp/cam_icp_context.c @@ -107,12 +107,12 @@ static int __cam_icp_release_dev_in_acquired(struct cam_context *ctx, { int rc; + cam_common_release_evt_params(ctx->dev_hdl); + rc = cam_context_release_dev_to_hw(ctx, cmd); if (rc) CAM_ERR(CAM_ICP, "Unable to release device"); - cam_common_release_err_params(ctx->dev_hdl); - ctx->state = CAM_CTX_AVAILABLE; trace_cam_context_state("ICP", ctx); return rc; @@ -303,13 +303,19 @@ static int cam_icp_ctx_handle_buf_done_in_ready(void *ctx, void *done_evt_data) return cam_context_buf_done_from_hw(ctx, buf_done->buf_done_data, buf_done->evt_id); } +static int cam_icp_ctx_handle_error_inducement(void *ctx, void *inject_evt_arg) +{ + return cam_context_apply_evt_injection(ctx, inject_evt_arg); +} + static int __cam_icp_ctx_handle_hw_event(void *ctx, uint32_t evt_id, void *evt_data) { int rc; if (!ctx || !evt_data) { - CAM_ERR(CAM_ICP, "Invalid ctx and event data"); + CAM_ERR(CAM_ICP, "Invalid ctx %s and event data %s", + CAM_IS_NULL_TO_STR(ctx), CAM_IS_NULL_TO_STR(evt_data)); return -EINVAL; } @@ -320,52 +326,120 @@ static int __cam_icp_ctx_handle_hw_event(void *ctx, case CAM_ICP_EVT_ID_ERROR: rc = cam_icp_ctx_handle_fatal_error(ctx, evt_data); break; + case CAM_ICP_EVT_ID_INJECT_EVENT: + rc = cam_icp_ctx_handle_error_inducement(ctx, evt_data); + break; default: - CAM_ERR(CAM_ICP, "Invalid event id: %d", evt_id); + CAM_ERR(CAM_ICP, "Invalid event id: %u", evt_id); rc = -EINVAL; } return rc; } -static int cam_icp_context_inject_error(void *context, void *err_param) +static int cam_icp_context_validate_event_notify_injection(struct cam_context *ctx, + struct cam_hw_inject_evt_param *evt_params) { int rc = 0; - uint32_t err_code; - uint32_t err_type; + uint32_t evt_type; uint64_t req_id; - struct cam_context *ctx = (struct cam_context *)context; - if (!err_param) { - CAM_ERR(CAM_ICP, "err_params is not valid"); - return -EINVAL; - } + req_id = evt_params->req_id; + evt_type = evt_params->u.evt_notify.evt_notify_type; - err_code = ((struct cam_err_inject_param *)err_param)->err_code; - err_type = ((struct cam_err_inject_param *)err_param)->err_type; - req_id = ((struct cam_err_inject_param *)err_param)->req_id; + switch (evt_type) { + case V4L_EVENT_CAM_REQ_MGR_ERROR: { + struct cam_hw_inject_err_evt_param *err_evt_params = + &evt_params->u.evt_notify.u.err_evt_params; - switch (err_type) { - case CAM_SYNC_STATE_SIGNALED_ERROR: - switch (err_code) { - case CAM_SYNC_ICP_EVENT_FRAME_PROCESS_FAILURE: - case CAM_SYNC_ICP_EVENT_CONFIG_ERR: + switch (err_evt_params->err_type) { + case CAM_REQ_MGR_ERROR_TYPE_RECOVERY: + case CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY: break; default: - CAM_ERR(CAM_ICP, "ICP Error code %d not supported!", err_code); + CAM_ERR(CAM_ICP, + "Invalid error type: %u for error event injection err code: %u req id: %llu ctx id: %u dev hdl: %d", + err_evt_params->err_type, err_evt_params->err_code, + req_id, ctx->ctx_id, ctx->dev_hdl); return -EINVAL; } + + CAM_INFO(CAM_ICP, + "Inject ERR evt: err code: %u err type: %u req id: %llu ctx id: %u dev hdl: %d", + err_evt_params->err_code, err_evt_params->err_type, + req_id, ctx->ctx_id, ctx->dev_hdl); break; + } + case V4L_EVENT_CAM_REQ_MGR_PF_ERROR: { + struct cam_hw_inject_pf_evt_param *pf_evt_params = + &evt_params->u.evt_notify.u.pf_evt_params; + bool non_fatal_en; + + rc = cam_smmu_is_cb_non_fatal_fault_en(ctx->img_iommu_hdl, &non_fatal_en); + if (rc) { + CAM_ERR(CAM_ICP, + "Fail to query whether device's cb has non-fatal enabled rc: %d", + rc); + return rc; + } + + if (!non_fatal_en) { + CAM_ERR(CAM_ICP, + "Fail to inject page fault event notification. Page fault is fatal for ICP"); + return -EINVAL; + } + + CAM_INFO(CAM_ICP, + "Inject PF evt: req_id: %llu ctx id: %u dev hdl: %d ctx found: %hhu", + req_id, ctx->ctx_id, ctx->dev_hdl, pf_evt_params->ctx_found); + break; + } default: - CAM_ERR(CAM_ICP, "ICP Error type: %d not supported!", err_code); + CAM_ERR(CAM_ICP, "Event notification type not supported: %u", evt_type); + rc = -EINVAL; + } + + return rc; +} + +static int cam_icp_context_inject_evt(void *context, void *evt_args) +{ + struct cam_context *ctx = context; + struct cam_hw_inject_evt_param *evt_params = NULL; + struct cam_hw_inject_buffer_error_param *buf_err_params = NULL; + int rc = 0; + + if (!ctx || !evt_args) { + CAM_ERR(CAM_ICP, + "invalid params ctx %s event args %s", + CAM_IS_NULL_TO_STR(ctx), CAM_IS_NULL_TO_STR(evt_args)); return -EINVAL; } - CAM_INFO(CAM_ICP, - "Err inject params: err_code: %u err_type: %u, to dev_hdl: %lld", - err_code, err_type, ctx->dev_hdl); + evt_params = (struct cam_hw_inject_evt_param *)evt_args; - rc = cam_context_err_to_hw(ctx, err_param); + if (evt_params->inject_id == CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE) { + buf_err_params = &evt_params->u.buf_err_evt; + if (buf_err_params->sync_error > CAM_SYNC_ICP_EVENT_START || + buf_err_params->sync_error < CAM_SYNC_ICP_EVENT_END) { + CAM_INFO(CAM_ICP, "Inject buffer sync error %u ctx id: %u req id %llu", + buf_err_params->sync_error, ctx->ctx_id, evt_params->req_id); + } else { + CAM_ERR(CAM_ICP, "Invalid buffer sync error %u ctx id: %u req id %llu", + buf_err_params->sync_error, ctx->ctx_id, evt_params->req_id); + return -EINVAL; + } + } else { + rc = cam_icp_context_validate_event_notify_injection(ctx, evt_params); + if (rc) { + CAM_ERR(CAM_ICP, + "Event notification injection failed validation rc: %d", rc); + return -EINVAL; + } + } + + if (ctx->hw_mgr_intf->hw_inject_evt) + ctx->hw_mgr_intf->hw_inject_evt(ctx->ctxt_to_hw_map, evt_args); return rc; } @@ -400,7 +474,7 @@ static struct cam_ctx_ops .irq_ops = __cam_icp_ctx_handle_hw_event, .pagefault_ops = cam_icp_context_dump_active_request, .mini_dump_ops = cam_icp_context_mini_dump, - .err_inject_ops = cam_icp_context_inject_error, + .evt_inject_ops = cam_icp_context_inject_evt, }, /* Ready */ { @@ -415,7 +489,7 @@ static struct cam_ctx_ops .irq_ops = __cam_icp_ctx_handle_hw_event, .pagefault_ops = cam_icp_context_dump_active_request, .mini_dump_ops = cam_icp_context_mini_dump, - .err_inject_ops = cam_icp_context_inject_error, + .evt_inject_ops = cam_icp_context_inject_evt, }, /* Flushed */ { @@ -428,7 +502,7 @@ static struct cam_ctx_ops .irq_ops = NULL, .pagefault_ops = cam_icp_context_dump_active_request, .mini_dump_ops = cam_icp_context_mini_dump, - .err_inject_ops = cam_icp_context_inject_error, + .evt_inject_ops = cam_icp_context_inject_evt, }, }; diff --git a/drivers/cam_icp/cam_icp_subdev.c b/drivers/cam_icp/cam_icp_subdev.c index 7761a09985..7cad9ef4b6 100644 --- a/drivers/cam_icp/cam_icp_subdev.c +++ b/drivers/cam_icp/cam_icp_subdev.c @@ -53,20 +53,20 @@ static const struct of_device_id cam_icp_dt_match[] = { {} }; -static int cam_icp_dev_err_inject_cb(void *err_param) +static int cam_icp_dev_evt_inject_cb(void *inject_args) { - int i = 0; + struct cam_common_inject_evt_param *inject_params = inject_args; + int i; for (i = 0; i < CAM_ICP_CTX_MAX; i++) { - if (g_icp_dev.ctx[i].dev_hdl == - ((struct cam_err_inject_param *)err_param)->dev_hdl) { - CAM_INFO(CAM_ICP, "ICP err inject dev_hdl found:%d", - g_icp_dev.ctx[i].dev_hdl); - cam_context_add_err_inject(&g_icp_dev.ctx[i], err_param); + if (g_icp_dev.ctx[i].dev_hdl == inject_params->dev_hdl) { + cam_context_add_evt_inject(&g_icp_dev.ctx[i], + &inject_params->evt_params); return 0; } } - CAM_ERR(CAM_ICP, "No dev hdl found"); + + CAM_ERR(CAM_ICP, "No dev hdl found %d", inject_params->dev_hdl); return -ENODEV; } @@ -261,8 +261,8 @@ static int cam_icp_component_bind(struct device *dev, goto ctx_fail; } - cam_common_register_err_inject_cb(cam_icp_dev_err_inject_cb, - CAM_COMMON_ERR_INJECT_HW_ICP); + cam_common_register_evt_inject_cb(cam_icp_dev_evt_inject_cb, + CAM_COMMON_EVT_INJECT_HW_ICP); node->sd_handler = cam_icp_subdev_close_internal; cam_smmu_set_client_page_fault_handler(iommu_hdl, diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 9d3c508ae7..a73d7fadcd 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -2232,31 +2232,24 @@ static const char *cam_icp_error_handle_id_to_type( return name; } -static inline void cam_icp_mgr_validate_inject_err(uint64_t current_req_id, uint32_t *event_id, - struct cam_hw_done_event_data *buf_data, struct cam_icp_hw_ctx_data *ctx_data) +static inline void cam_icp_mgr_apply_evt_injection(struct cam_hw_done_event_data *buf_done_data, + struct cam_icp_hw_ctx_data *ctx_data, bool *signal_fence_buffer) { - if (ctx_data->err_inject_params.err_req_id == current_req_id) { - switch (ctx_data->err_inject_params.err_code) { - case CAM_SYNC_ICP_EVENT_FRAME_PROCESS_FAILURE: - *event_id = CAM_CTX_EVT_ID_ERROR; - buf_data->evt_param = CAM_SYNC_ICP_EVENT_FRAME_PROCESS_FAILURE; - break; - case CAM_SYNC_ICP_EVENT_CONFIG_ERR: - *event_id = CAM_CTX_EVT_ID_ERROR; - buf_data->evt_param = CAM_SYNC_ICP_EVENT_CONFIG_ERR; - break; - default: - CAM_INFO(CAM_ICP, "ICP error code not supported: %d", - ctx_data->err_inject_params.err_code); - return; - } - } else - return; + struct cam_hw_inject_evt_param *evt_params = &ctx_data->evt_inject_params; + struct cam_common_evt_inject_data inject_evt; - CAM_INFO(CAM_ICP, "ICP Err Induced! err_code: %u, req_id: %llu", - ctx_data->err_inject_params.err_code, current_req_id); + inject_evt.buf_done_data = buf_done_data; + inject_evt.evt_params = evt_params; - memset(&(ctx_data->err_inject_params), 0, sizeof(struct cam_hw_err_param)); + if (ctx_data->ctxt_event_cb) + ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_INJECT_EVENT, + &inject_evt); + + if (ctx_data->evt_inject_params.inject_id == + CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE) + *signal_fence_buffer = false; + + evt_params->is_valid = false; } static void cam_icp_mgr_dump_active_req_info(void) @@ -2332,6 +2325,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) struct cam_icp_hw_error_evt_data icp_err_evt = {0}; uint32_t clk_type, event_id; struct cam_hangdump_mem_regions *mem_regions = NULL; + bool signal_fence_buffer = true; ioconfig_ack = (struct hfi_msg_dev_async_ack *)msg_ptr; request_id = ioconfig_ack->user_data2; @@ -2419,19 +2413,18 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) "[%s]: BufDone Req %llu event_id %d", ctx_data->ctx_id_string, hfi_frame_process->request_id[idx], event_id); - if (ctx_data->err_inject_params.is_valid) - cam_icp_mgr_validate_inject_err(request_id, &event_id, &buf_data, ctx_data); - buf_data.request_id = hfi_frame_process->request_id[idx]; - icp_done_evt.evt_id = event_id; - icp_done_evt.buf_done_data = &buf_data; - if (ctx_data->ctxt_event_cb) - ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE, - &icp_done_evt); - else - CAM_ERR(CAM_ICP, - "Event callback invalid for ctx: %u [%s] failed to signal req: %llu", - ctx_data->ctx_id, ctx_data->ctx_id_string, buf_data.request_id); + if ((ctx_data->evt_inject_params.is_valid) && + (ctx_data->evt_inject_params.req_id == request_id)) + cam_icp_mgr_apply_evt_injection(&buf_data, ctx_data, &signal_fence_buffer); + + if (signal_fence_buffer) { + icp_done_evt.evt_id = event_id; + icp_done_evt.buf_done_data = &buf_data; + if (ctx_data->ctxt_event_cb) + ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE, + &icp_done_evt); + } hfi_frame_process->request_id[idx] = 0; if (ctx_data->hfi_frame_process.in_resource[idx] > 0) { @@ -3992,8 +3985,9 @@ static int cam_icp_mgr_release_ctx(struct cam_icp_hw_mgr *hw_mgr, int ctx_id) hw_mgr->ctx_data[ctx_id].ctx_id_string, perf_stats->total_requests, perf_stats->total_requests ? (perf_stats->total_resp_time / perf_stats->total_requests) : 0); - memset(&(hw_mgr->ctx_data[ctx_id].err_inject_params), 0, - sizeof(struct cam_hw_err_param)); + + memset(&hw_mgr->ctx_data[ctx_id].evt_inject_params, 0, + sizeof(struct cam_hw_inject_evt_param)); cam_icp_remove_ctx_bw(hw_mgr, &hw_mgr->ctx_data[ctx_id]); if (hw_mgr->ctx_data[ctx_id].state != CAM_ICP_CTX_STATE_ACQUIRED) { @@ -6953,17 +6947,20 @@ static int cam_icp_mgr_cmd(void *hw_mgr_priv, void *cmd_args) return rc; } -static void cam_icp_mgr_inject_err(void *hw_mgr_priv, void *hw_err_inject_args) +static void cam_icp_mgr_inject_evt(void *hw_mgr_priv, void *evt_args) { - struct cam_icp_hw_ctx_data *ctx_data = hw_mgr_priv; + struct cam_icp_hw_ctx_data *ctx_data = hw_mgr_priv; + struct cam_hw_inject_evt_param *evt_params = evt_args; - ctx_data->err_inject_params.err_code = ((struct cam_err_inject_param *) - hw_err_inject_args)->err_code; - ctx_data->err_inject_params.err_type = ((struct cam_err_inject_param *) - hw_err_inject_args)->err_type; - ctx_data->err_inject_params.err_req_id = ((struct cam_err_inject_param *) - hw_err_inject_args)->req_id; - ctx_data->err_inject_params.is_valid = true; + if (!ctx_data || !evt_params) { + CAM_ERR(CAM_ICP, "Invalid params ctx data %s event params %s", + CAM_IS_NULL_TO_STR(ctx_data), CAM_IS_NULL_TO_STR(evt_params)); + return; + } + + memcpy(&ctx_data->evt_inject_params, evt_params, sizeof(struct cam_hw_inject_evt_param)); + + ctx_data->evt_inject_params.is_valid = true; } int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl, @@ -6995,7 +6992,7 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl, hw_mgr_intf->hw_flush = cam_icp_mgr_hw_flush; hw_mgr_intf->hw_cmd = cam_icp_mgr_cmd; hw_mgr_intf->hw_dump = cam_icp_mgr_hw_dump; - hw_mgr_intf->hw_inject_err = cam_icp_mgr_inject_err; + hw_mgr_intf->hw_inject_evt = cam_icp_mgr_inject_evt; icp_hw_mgr.secure_mode = CAM_SECURE_MODE_NON_SECURE; icp_hw_mgr.mini_dump_cb = mini_dump_cb; diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h index e3c86c1a2c..86f4173b3d 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h @@ -283,8 +283,8 @@ struct cam_ctx_clk_info { * @watch_dog_reset_counter: Counter for watch dog reset * @icp_dev_io_info: io config resource * @last_flush_req: last flush req for this ctx - * @err_inject_params: Error injection data for hw_mgr_ctx * @perf_stats: performance statistics info + * @evt_inject_params: Event injection data for hw_mgr_ctx * @unified_dev_type: Unified dev type which does not hold any priority info. * It's either IPE/BPS * @abort_timed_out: Indicates if abort timed out @@ -311,8 +311,8 @@ struct cam_icp_hw_ctx_data { struct cam_icp_acquire_dev_info icp_dev_io_info; uint64_t last_flush_req; char ctx_id_string[128]; - struct cam_hw_err_param err_inject_params; struct cam_icp_ctx_perf_stats perf_stats; + struct cam_hw_inject_evt_param evt_inject_params; uint32_t unified_dev_type; bool abort_timed_out; }; diff --git a/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h b/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h index 276fac1359..e1f2c38ca5 100644 --- a/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h +++ b/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h @@ -34,6 +34,7 @@ enum cam_icp_hw_event_type { CAM_ICP_EVT_ID_BUF_DONE, CAM_ICP_EVT_ID_ERROR, + CAM_ICP_EVT_ID_INJECT_EVENT, }; enum cam_icp_hw_error_type { diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index d3a4b95b7a..cc09a84e53 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -4301,22 +4301,22 @@ static struct cam_isp_ctx_irq_ops }, }; -static inline int cam_isp_context_apply_error(struct cam_hw_err_param *err_params, - uint64_t current_req_id, struct cam_context *ctx) +static inline int cam_isp_context_apply_evt_injection(struct cam_context *ctx) { - int rc = 0; + struct cam_isp_context *ctx_isp = ctx->ctx_priv; + struct cam_hw_inject_evt_param *evt_inject_params = &ctx_isp->evt_inject_params; + struct cam_common_evt_inject_data inject_evt = {0}; + int rc; - if (err_params->err_req_id == current_req_id) { - CAM_INFO(CAM_ISP, - "Err inject for req: %llu, err_code: %d, err_type: %d ctx id: %d", - current_req_id, err_params->err_code, err_params->err_type, ctx->ctx_id); + inject_evt.evt_params = evt_inject_params; + rc = cam_context_apply_evt_injection(ctx, &inject_evt); + if (rc) + CAM_ERR(CAM_ISP, "Fail to apply event injection ctx_id: %u req_id: %u", + ctx->ctx_id, evt_inject_params->req_id); - __cam_isp_ctx_notify_v4l2_error_event(err_params->err_type, err_params->err_code, - current_req_id, ctx); - memset(err_params, 0, sizeof(struct cam_hw_err_param)); - return rc; - } - return -EINVAL; + evt_inject_params->is_valid = false; + + return rc; } static int __cam_isp_ctx_apply_req_in_activated_state( @@ -4452,9 +4452,9 @@ static int __cam_isp_ctx_apply_req_in_activated_state( cfg.reapply_type = req_isp->reapply_type; cfg.cdm_reset_before_apply = req_isp->cdm_reset_before_apply; - if (ctx_isp->err_inject_params.is_valid) { - rc = cam_isp_context_apply_error(&(ctx_isp->err_inject_params), - req->request_id, ctx_isp->base); + if ((ctx_isp->evt_inject_params.is_valid) && + (req->request_id == ctx_isp->evt_inject_params.req_id)) { + rc = cam_isp_context_apply_evt_injection(ctx_isp->base); if (!rc) goto end; } @@ -5958,8 +5958,8 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx_isp->hw_ctx = NULL; } - cam_common_release_err_params(ctx->dev_hdl); - memset(&(ctx_isp->err_inject_params), 0, sizeof(struct cam_hw_err_param)); + cam_common_release_evt_params(ctx->dev_hdl); + memset(&ctx_isp->evt_inject_params, 0, sizeof(struct cam_hw_inject_evt_param)); ctx->session_hdl = -1; ctx->dev_hdl = -1; @@ -7779,65 +7779,106 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context, return rc; } -static int cam_isp_context_inject_error(void *context, void *err_param) +static int cam_isp_context_validate_event_notify_injection(struct cam_context *ctx, + struct cam_hw_inject_evt_param *evt_params) { int rc = 0; - struct cam_context *ctx = (struct cam_context *)context; - struct cam_isp_context *ctx_isp = ctx->ctx_priv; + uint32_t evt_type; uint64_t req_id; - uint32_t err_code; - uint32_t err_type; - if (!err_param) { - CAM_ERR(CAM_ISP, "err_param not valid"); - return -EINVAL; + req_id = evt_params->req_id; + evt_type = evt_params->u.evt_notify.evt_notify_type; + + switch (evt_type) { + case V4L_EVENT_CAM_REQ_MGR_ERROR: { + struct cam_hw_inject_err_evt_param *err_evt_params = + &evt_params->u.evt_notify.u.err_evt_params; + + switch (err_evt_params->err_type) { + case CAM_REQ_MGR_ERROR_TYPE_RECOVERY: + case CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE: + case CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY: + case CAM_REQ_MGR_WARN_TYPE_KMD_RECOVERY: + break; + default: + CAM_ERR(CAM_ISP, + "Invalid error type: %u for error event injection err type: %u req id: %llu ctx id: %u dev hdl: %d", + err_evt_params->err_type, err_evt_params->err_code, + req_id, ctx->ctx_id, ctx->dev_hdl); + return -EINVAL; + } + + CAM_INFO(CAM_ISP, + "Inject ERR evt: err code: %u err type: %u req id: %llu ctx id: %u dev hdl: %d", + err_evt_params->err_code, err_evt_params->err_type, + req_id, ctx->ctx_id, ctx->dev_hdl); + break; } + case V4L_EVENT_CAM_REQ_MGR_PF_ERROR: { + struct cam_hw_inject_pf_evt_param *pf_evt_params = + &evt_params->u.evt_notify.u.pf_evt_params; + bool non_fatal_en; - req_id = ((struct cam_err_inject_param *)err_param)->req_id; - err_type = ((struct cam_err_inject_param *)err_param)->err_type; - err_code = ((struct cam_err_inject_param *)err_param)->err_code; + rc = cam_smmu_is_cb_non_fatal_fault_en(ctx->img_iommu_hdl, &non_fatal_en); + if (rc) { + CAM_ERR(CAM_ISP, + "Fail to query whether device's cb has non-fatal enabled rc:%d", + rc); + return rc; + } - switch (err_type) { - case CAM_REQ_MGR_ERROR_TYPE_RECOVERY: - switch (err_code) { - case CAM_REQ_MGR_LINK_STALLED_ERROR: - case CAM_REQ_MGR_CSID_FIFO_OVERFLOW_ERROR: - case CAM_REQ_MGR_CSID_RECOVERY_OVERFLOW_ERROR: - case CAM_REQ_MGR_CSID_PIXEL_COUNT_MISMATCH: - case CAM_REQ_MGR_CSID_ERR_ON_SENSOR_SWITCHING: - break; - default: - CAM_ERR(CAM_ISP, "err code not supported %d", err_code); + if (!non_fatal_en) { + CAM_ERR(CAM_ISP, + "Fail to inject page fault event notification. Page fault is fatal for ISP"); return -EINVAL; } + + CAM_INFO(CAM_ISP, + "Inject PF evt: req_id: %llu ctx id: %u dev hdl: %d ctx found: %hhu", + req_id, ctx->ctx_id, ctx->dev_hdl, pf_evt_params->ctx_found); break; - case CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY: - switch (err_code) { - case CAM_REQ_MGR_CSID_FATAL_ERROR: - break; - default: - CAM_ERR(CAM_ISP, "err code not supported %d", err_code); - return -EINVAL; - } - break; - case CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE: - err_code = CAM_REQ_MGR_ISP_UNREPORTED_ERROR; - break; - case CAM_REQ_MGR_ERROR_TYPE_PAGE_FAULT: - err_code = CAM_REQ_MGR_ISP_UNREPORTED_ERROR; - break; + } default: - CAM_ERR(CAM_ISP, "err type not supported %d", err_type); + CAM_ERR(CAM_ISP, "Event notification type not supported: %u", evt_type); + rc = -EINVAL; + } + + return rc; +} + +static int cam_isp_context_inject_evt(void *context, void *evt_args) +{ + struct cam_context *ctx = context; + struct cam_isp_context *ctx_isp = NULL; + struct cam_hw_inject_evt_param *evt_params = evt_args; + int rc = 0; + + if (!ctx || !evt_args) { + CAM_ERR(CAM_ISP, + "Invalid params ctx %s event args %s", + CAM_IS_NULL_TO_STR(ctx), CAM_IS_NULL_TO_STR(evt_args)); return -EINVAL; } - CAM_DBG(CAM_ISP, "inject err isp code: %d type: %d ctx id: %d", - err_code, err_type, ctx->ctx_id); + ctx_isp = ctx->ctx_priv; + if (evt_params->inject_id == CAM_COMMON_EVT_INJECT_NOTIFY_EVENT_TYPE) { + rc = cam_isp_context_validate_event_notify_injection(ctx, evt_params); + if (rc) { + CAM_ERR(CAM_ISP, + "Event notification injection failed validation rc: %d", rc); + return rc; + } + } else { + CAM_ERR(CAM_ISP, "Buffer done err injection %u not supported by ISP", + evt_params->inject_id); + return -EINVAL; + } - ctx_isp->err_inject_params.err_code = err_code; - ctx_isp->err_inject_params.err_type = err_type; - ctx_isp->err_inject_params.err_req_id = req_id; - ctx_isp->err_inject_params.is_valid = true; + + memcpy(&ctx_isp->evt_inject_params, evt_params, + sizeof(struct cam_hw_inject_evt_param)); + + ctx_isp->evt_inject_params.is_valid = true; return rc; } @@ -7879,7 +7920,7 @@ static struct cam_ctx_ops .irq_ops = NULL, .pagefault_ops = cam_isp_context_dump_requests, .dumpinfo_ops = cam_isp_context_info_dump, - .err_inject_ops = cam_isp_context_inject_error, + .evt_inject_ops = cam_isp_context_inject_evt, }, /* Ready */ { @@ -7898,7 +7939,7 @@ static struct cam_ctx_ops .irq_ops = NULL, .pagefault_ops = cam_isp_context_dump_requests, .dumpinfo_ops = cam_isp_context_info_dump, - .err_inject_ops = cam_isp_context_inject_error, + .evt_inject_ops = cam_isp_context_inject_evt, }, /* Flushed */ { @@ -7916,7 +7957,7 @@ static struct cam_ctx_ops .irq_ops = NULL, .pagefault_ops = cam_isp_context_dump_requests, .dumpinfo_ops = cam_isp_context_info_dump, - .err_inject_ops = cam_isp_context_inject_error, + .evt_inject_ops = cam_isp_context_inject_evt, }, /* Activated */ { @@ -7940,7 +7981,7 @@ static struct cam_ctx_ops .pagefault_ops = cam_isp_context_dump_requests, .dumpinfo_ops = cam_isp_context_info_dump, .recovery_ops = cam_isp_context_hw_recovery, - .err_inject_ops = cam_isp_context_inject_error, + .evt_inject_ops = cam_isp_context_inject_evt, }, }; diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index e6a21972b2..b4d8c15675 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -288,6 +288,7 @@ struct cam_isp_context_event_record { * @trigger_id: ID provided by CRM for each ctx on the link * @last_bufdone_err_apply_req_id: last bufdone error apply request id * @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 * @do_internal_recovery: Enable KMD halt/reset/resume internal recovery * @@ -345,7 +346,7 @@ struct cam_isp_context { int32_t trigger_id; int64_t last_bufdone_err_apply_req_id; uint32_t v4l2_event_sub_ids; - struct cam_hw_err_param err_inject_params; + struct cam_hw_inject_evt_param evt_inject_params; bool aeb_enabled; bool do_internal_recovery; }; diff --git a/drivers/cam_isp/cam_isp_dev.c b/drivers/cam_isp/cam_isp_dev.c index 0f0a961b33..52b0658c2a 100644 --- a/drivers/cam_isp/cam_isp_dev.c +++ b/drivers/cam_isp/cam_isp_dev.c @@ -25,18 +25,20 @@ static struct cam_isp_dev g_isp_dev; -static int cam_isp_dev_err_inject_cb(void *err_param) +static int cam_isp_dev_evt_inject_cb(void *inject_args) { - int i = 0; + struct cam_common_inject_evt_param *inject_params = inject_args; + int i; for (i = 0; i < g_isp_dev.max_context; i++) { - if ((g_isp_dev.ctx[i].dev_hdl) == - ((struct cam_err_inject_param *)err_param)->dev_hdl) { - cam_context_add_err_inject(&g_isp_dev.ctx[i], err_param); + if (g_isp_dev.ctx[i].dev_hdl == inject_params->dev_hdl) { + cam_context_add_evt_inject(&g_isp_dev.ctx[i], + &inject_params->evt_params); return 0; } } - CAM_ERR(CAM_ISP, "no dev hdl found for IFE"); + + CAM_ERR(CAM_ISP, "No dev hdl found %d", inject_params->dev_hdl); return -ENODEV; } @@ -217,8 +219,8 @@ static int cam_isp_dev_component_bind(struct device *dev, } } - cam_common_register_err_inject_cb(cam_isp_dev_err_inject_cb, - CAM_COMMON_ERR_INJECT_HW_ISP); + cam_common_register_evt_inject_cb(cam_isp_dev_evt_inject_cb, + CAM_COMMON_EVT_INJECT_HW_ISP); rc = cam_node_init(node, &hw_mgr_intf, g_isp_dev.ctx, g_isp_dev.max_context, CAM_ISP_DEV_NAME); diff --git a/drivers/cam_jpeg/cam_jpeg_context.c b/drivers/cam_jpeg/cam_jpeg_context.c index 82a8dc7bc9..f4168bae4c 100644 --- a/drivers/cam_jpeg/cam_jpeg_context.c +++ b/drivers/cam_jpeg/cam_jpeg_context.c @@ -15,6 +15,7 @@ #include "cam_context_utils.h" #include "cam_debug_util.h" #include "cam_packet_util.h" +#include "cam_jpeg_hw_intf.h" static const char jpeg_dev_name[] = "cam-jpeg"; @@ -95,12 +96,12 @@ static int __cam_jpeg_ctx_release_dev_in_acquired(struct cam_context *ctx, { int rc; + cam_common_release_evt_params(ctx->dev_hdl); + rc = cam_context_release_dev_to_hw(ctx, cmd); if (rc) CAM_ERR(CAM_JPEG, "Unable to release device %d", rc); - cam_common_release_err_params(ctx->dev_hdl); - ctx->state = CAM_CTX_AVAILABLE; return rc; @@ -137,10 +138,43 @@ static int __cam_jpeg_ctx_config_dev_in_acquired(struct cam_context *ctx, return cam_context_prepare_dev_to_hw(ctx, cmd); } -static int __cam_jpeg_ctx_handle_buf_done_in_acquired(void *ctx, - uint32_t evt_id, void *done) +static int __cam_jpeg_ctx_handle_buf_done_in_acquired(void *ctx, void *done_evt_data) { - return cam_context_buf_done_from_hw(ctx, done, evt_id); + struct cam_jpeg_hw_buf_done_evt_data *buf_done = done_evt_data; + + return cam_context_buf_done_from_hw(ctx, buf_done->buf_done_data, + buf_done->evt_id); +} + +static int __cam_jpeg_ctx_handle_evt_inducement(void *ctx, void *inject_evt_arg) +{ + return cam_context_apply_evt_injection(ctx, inject_evt_arg); +} + +static int __cam_jpeg_ctx_handle_hw_event(void *ctx, + uint32_t evt_id, void *evt_data) +{ + int rc; + + if (!ctx || !evt_data) { + CAM_ERR(CAM_JPEG, "Invalid parameters ctx %s evt_data: %s", + CAM_IS_NULL_TO_STR(ctx), CAM_IS_NULL_TO_STR(evt_data)); + return -EINVAL; + } + + switch (evt_id) { + case CAM_JPEG_EVT_ID_BUF_DONE: + rc = __cam_jpeg_ctx_handle_buf_done_in_acquired(ctx, evt_data); + break; + case CAM_JPEG_EVT_ID_INDUCE_ERR: + rc = __cam_jpeg_ctx_handle_evt_inducement(ctx, evt_data); + break; + default: + CAM_ERR(CAM_JPEG, "Invalid event id: %u", evt_id); + rc = -EINVAL; + } + + return rc; } static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx, @@ -157,53 +191,108 @@ static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx, return rc; } -static int cam_jpeg_context_inject_error(void *context, void *err_param) +static int cam_jpeg_context_validate_event_notify_injection(struct cam_context *ctx, + struct cam_hw_inject_evt_param *evt_params) { int rc = 0; - struct cam_context *ctx = (struct cam_context *)context; + uint32_t evt_type; uint64_t req_id; - uint32_t err_code; - uint32_t err_type; - if (!err_param) { - CAM_ERR(CAM_ISP, "err_param not valid"); - return -EINVAL; + req_id = evt_params->req_id; + evt_type = evt_params->u.evt_notify.evt_notify_type; + + switch (evt_type) { + case V4L_EVENT_CAM_REQ_MGR_NODE_EVENT: { + struct cam_hw_inject_node_evt_param *node_evt_params = + &evt_params->u.evt_notify.u.node_evt_params; + + switch (node_evt_params->event_type) { + case CAM_REQ_MGR_RETRY_EVENT: + break; + default: + CAM_ERR(CAM_JPEG, + "Invalid event type %u for node event injection event cause: %u req id: %llu ctx id: %u dev hdl: %d", + node_evt_params->event_type, node_evt_params->event_cause, + req_id, ctx->ctx_id, ctx->dev_hdl); + return -EINVAL; + } + + CAM_INFO(CAM_JPEG, + "Inject Node evt: event type: %u event cause: %u req id: %llu ctx id: %u dev hdl: %d", + node_evt_params->event_type, node_evt_params->event_cause, + req_id, ctx->ctx_id, ctx->dev_hdl); + break; } + case V4L_EVENT_CAM_REQ_MGR_PF_ERROR: { + struct cam_hw_inject_pf_evt_param *pf_evt_params = + &evt_params->u.evt_notify.u.pf_evt_params; + bool non_fatal_en; - req_id = ((struct cam_err_inject_param *)err_param)->req_id; - err_code = ((struct cam_err_inject_param *)err_param)->err_code; - err_type = ((struct cam_err_inject_param *)err_param)->err_type; + rc = cam_smmu_is_cb_non_fatal_fault_en(ctx->img_iommu_hdl, &non_fatal_en); + if (rc) { + CAM_ERR(CAM_JPEG, + "Fail to query whether device's cb has non-fatal enabled rc: %d", + rc); + return rc; + } - switch (err_type) { - case CAM_REQ_MGR_RETRY_EVENT: - switch (err_code) { - case CAM_REQ_MGR_JPEG_THUBNAIL_SIZE_ERROR: - break; - default: - CAM_ERR(CAM_ISP, "err code not supported %d", err_code); - return -EINVAL; - } - break; - case CAM_SYNC_STATE_SIGNALED_ERROR: - switch (err_code) { - case CAM_SYNC_JPEG_EVENT_INVLD_CMD: - case CAM_SYNC_JPEG_EVENT_SET_IRQ_CB: - case CAM_SYNC_JPEG_EVENT_HW_RESET_FAILED: - case CAM_SYNC_JPEG_EVENT_CDM_CHANGE_BASE_ERR: - case CAM_SYNC_JPEG_EVENT_CDM_CONFIG_ERR: - case CAM_SYNC_JPEG_EVENT_START_HW_ERR: - break; - default: - CAM_ERR(CAM_ISP, "err code not supported %d", err_code); + if (!non_fatal_en) { + CAM_ERR(CAM_JPEG, + "Fail to inject page fault event notification. Page fault is fatal for JPEG"); return -EINVAL; } + + CAM_INFO(CAM_JPEG, + "Inject PF evt: req_id: %llu ctx id: %u dev hdl: %d ctx found: %hhu", + req_id, ctx->ctx_id, ctx->dev_hdl, pf_evt_params->ctx_found); break; + } default: - CAM_ERR(CAM_ISP, "err type not supported %d", err_type); + CAM_ERR(CAM_JPEG, "Event notification type not supported: %u", evt_type); + rc = -EINVAL; + } + + return rc; +} + +static int cam_jpeg_context_inject_evt(void *context, void *evt_args) +{ + struct cam_context *ctx = context; + struct cam_hw_inject_evt_param *evt_params = NULL; + struct cam_hw_inject_buffer_error_param *buf_err_params = NULL; + int rc = 0; + + if (!ctx || !evt_args) { + CAM_ERR(CAM_JPEG, + "invalid params ctx %s event args %s", + CAM_IS_NULL_TO_STR(ctx), CAM_IS_NULL_TO_STR(evt_args)); return -EINVAL; } - rc = cam_context_err_to_hw(ctx, err_param); + evt_params = (struct cam_hw_inject_evt_param *)evt_args; + + if (evt_params->inject_id == CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE) { + buf_err_params = &evt_params->u.buf_err_evt; + if (buf_err_params->sync_error > CAM_SYNC_JPEG_EVENT_START || + buf_err_params->sync_error < CAM_SYNC_JPEG_EVENT_END) { + CAM_INFO(CAM_JPEG, "Inject buffer sync error %u ctx id: %u req id %llu", + buf_err_params->sync_error, ctx->ctx_id, evt_params->req_id); + } else { + CAM_ERR(CAM_JPEG, "Invalid buffer sync error %u", + buf_err_params->sync_error); + return -EINVAL; + } + } else { + rc = cam_jpeg_context_validate_event_notify_injection(ctx, evt_params); + if (rc) { + CAM_ERR(CAM_JPEG, + "Event notification injection failed validation rc: %d", rc); + return rc; + } + } + + if (ctx->hw_mgr_intf->hw_inject_evt) + ctx->hw_mgr_intf->hw_inject_evt(ctx->ctxt_to_hw_map, evt_args); return rc; } @@ -236,10 +325,10 @@ static struct cam_ctx_ops .dump_dev = __cam_jpeg_ctx_dump_dev_in_acquired, }, .crm_ops = { }, - .irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired, + .irq_ops = __cam_jpeg_ctx_handle_hw_event, .pagefault_ops = cam_jpeg_context_dump_active_request, .mini_dump_ops = cam_jpeg_context_mini_dump, - .err_inject_ops = cam_jpeg_context_inject_error, + .evt_inject_ops = cam_jpeg_context_inject_evt, }, /* Ready */ { diff --git a/drivers/cam_jpeg/cam_jpeg_dev.c b/drivers/cam_jpeg/cam_jpeg_dev.c index ec5536fe52..6d48076cca 100644 --- a/drivers/cam_jpeg/cam_jpeg_dev.c +++ b/drivers/cam_jpeg/cam_jpeg_dev.c @@ -24,19 +24,20 @@ static struct cam_jpeg_dev g_jpeg_dev; -static int cam_jpeg_dev_err_inject_cb(void *err_param) +static int cam_jpeg_dev_evt_inject_cb(void *inject_args) { - int i = 0; + struct cam_common_inject_evt_param *inject_params = inject_args; + int i; for (i = 0; i < CAM_JPEG_CTX_MAX; i++) { - if (g_jpeg_dev.ctx[i].dev_hdl == - ((struct cam_err_inject_param *)err_param)->dev_hdl) { - CAM_INFO(CAM_ISP, "dev_hdl found:%d", g_jpeg_dev.ctx[i].dev_hdl); - cam_context_add_err_inject(&g_jpeg_dev.ctx[i], err_param); + if (g_jpeg_dev.ctx[i].dev_hdl == inject_params->dev_hdl) { + cam_context_add_evt_inject(&g_jpeg_dev.ctx[i], + &inject_params->evt_params); return 0; } } - CAM_ERR(CAM_ISP, "no dev hdl found jpeg"); + + CAM_ERR(CAM_JPEG, "No dev hdl found %d", inject_params->dev_hdl); return -EINVAL; } @@ -191,8 +192,8 @@ static int cam_jpeg_dev_component_bind(struct device *dev, } } - cam_common_register_err_inject_cb(cam_jpeg_dev_err_inject_cb, - CAM_COMMON_ERR_INJECT_HW_JPEG); + cam_common_register_evt_inject_cb(cam_jpeg_dev_evt_inject_cb, + CAM_COMMON_EVT_INJECT_HW_JPEG); rc = cam_node_init(node, &hw_mgr_intf, g_jpeg_dev.ctx, CAM_JPEG_CTX_MAX, CAM_JPEG_DEV_NAME); diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index e1fa9209e2..cb4daaa6f2 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -56,28 +56,23 @@ static int cam_jpeg_insert_cdm_change_base( struct cam_jpeg_hw_ctx_data *ctx_data, struct cam_jpeg_hw_mgr *hw_mgr); -static void cam_jpeg_inject_err(struct cam_jpeg_hw_ctx_data *ctx_data, - struct cam_hw_done_event_data *buf_data) +static void cam_jpeg_mgr_apply_evt_injection(struct cam_hw_done_event_data *buf_done_data, + struct cam_jpeg_hw_ctx_data *ctx_data, bool *signal_fence_buffer) { - struct cam_req_mgr_message v4l2_msg = {0}; - struct cam_context *cam_ctx = ctx_data->context_priv; + struct cam_hw_inject_evt_param *evt_inject_params = &ctx_data->evt_inject_params; + struct cam_common_evt_inject_data inject_evt; - if (ctx_data->err_inject_params.err_code == CAM_REQ_MGR_JPEG_THUBNAIL_SIZE_ERROR) { - v4l2_msg.session_hdl = cam_ctx->session_hdl; - v4l2_msg.u.node_msg.request_id = ctx_data->err_inject_params.err_req_id; - v4l2_msg.u.node_msg.link_hdl = cam_ctx->link_hdl; - v4l2_msg.u.node_msg.device_hdl = cam_ctx->dev_hdl; - v4l2_msg.u.node_msg.event_type = CAM_REQ_MGR_RETRY_EVENT; - v4l2_msg.u.node_msg.event_cause = - CAM_REQ_MGR_JPEG_THUBNAIL_SIZE_ERROR; - cam_req_mgr_notify_message(&v4l2_msg, - V4L_EVENT_CAM_REQ_MGR_NODE_EVENT, - V4L_EVENT_CAM_REQ_MGR_EVENT); - } else { - buf_data->evt_param = ctx_data->err_inject_params.err_code; - } + inject_evt.buf_done_data = buf_done_data; + inject_evt.evt_params = evt_inject_params; - memset(&(ctx_data->err_inject_params), 0, sizeof(struct cam_hw_err_param)); + if (ctx_data->ctxt_event_cb) + ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_JPEG_EVT_ID_INDUCE_ERR, + &inject_evt); + + if (evt_inject_params->inject_id == CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE) + *signal_fence_buffer = false; + + evt_inject_params->is_valid = false; } static int cam_jpeg_generic_blob_handler(void *user_data, @@ -389,6 +384,8 @@ static int cam_jpeg_mgr_bottom_half_irq(void *priv, void *data) struct cam_req_mgr_message v4l2_msg = {0}; struct cam_ctx_request *req; struct cam_jpeg_misr_dump_args misr_args; + struct cam_jpeg_hw_buf_done_evt_data jpeg_done_evt; + if (!data || !priv) { CAM_ERR(CAM_JPEG, "Invalid data"); return -EINVAL; @@ -513,8 +510,10 @@ static int cam_jpeg_mgr_bottom_half_irq(void *priv, void *data) } buf_data.request_id = jpeg_req->request_id; - ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_CTX_EVT_ID_SUCCESS, - &buf_data); + jpeg_done_evt.evt_id = CAM_CTX_EVT_ID_SUCCESS; + jpeg_done_evt.buf_done_data = &buf_data; + ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_JPEG_EVT_ID_BUF_DONE, + &jpeg_done_evt); exit: irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_sched_bottom_half; @@ -641,7 +640,8 @@ static int cam_jpeg_mgr_release_ctx( } ctx_data->in_use = false; - memset(&(ctx_data->err_inject_params), 0, sizeof(struct cam_hw_err_param)); + memset(&ctx_data->evt_inject_params, 0, sizeof(struct cam_hw_inject_evt_param)); + mutex_unlock(&ctx_data->ctx_mutex); return 0; @@ -727,6 +727,9 @@ static int cam_jpeg_mgr_process_hw_update_entries(void *priv, void *data) struct cam_jpeg_set_irq_cb irq_cb; struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL; struct cam_hw_done_event_data buf_data; + struct cam_jpeg_hw_buf_done_evt_data jpeg_done_evt; + bool event_inject = false; + bool signal_fence_buffer = true; task_data = (struct cam_jpeg_process_frame_work_data_t *)data; if (!hw_mgr || !task_data) { @@ -806,11 +809,12 @@ static int cam_jpeg_mgr_process_hw_update_entries(void *priv, void *data) goto end; } - if (ctx_data->err_inject_params.is_valid && - ctx_data->err_inject_params.err_req_id == request_id) { - cam_jpeg_inject_err(ctx_data, &buf_data); + if (ctx_data->evt_inject_params.is_valid && + ctx_data->evt_inject_params.req_id == request_id) { + event_inject = true; goto end_callcb; } + irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_sched_bottom_half; irq_cb.irq_cb_data.private_data = (void *)ctx_data; irq_cb.irq_cb_data.jpeg_req = jpeg_req; @@ -853,8 +857,16 @@ end_callcb: config_args->out_map_entries[i].resource_handle; } buf_data.request_id = (uintptr_t)jpeg_req->request_id; - ctx_data->ctxt_event_cb(ctx_data->context_priv, - CAM_CTX_EVT_ID_ERROR, &buf_data); + if (event_inject) + cam_jpeg_mgr_apply_evt_injection(&buf_data, ctx_data, + &signal_fence_buffer); + + if (signal_fence_buffer) { + jpeg_done_evt.evt_id = CAM_CTX_EVT_ID_ERROR; + jpeg_done_evt.buf_done_data = &buf_data; + ctx_data->ctxt_event_cb(ctx_data->context_priv, + CAM_JPEG_EVT_ID_BUF_DONE, &jpeg_done_evt); + } } end_unusedev: mutex_lock(&hw_mgr->hw_mgr_mutex); @@ -2193,17 +2205,21 @@ static int cam_jpeg_mgr_create_debugfs_entry(void) return rc; } -static void cam_jpeg_mgr_inject_err(void *hw_mgr_priv, void *hw_err_inject_args) +static void cam_jpeg_mgr_inject_evt(void *hw_mgr_priv, void *evt_args) { - struct cam_jpeg_hw_ctx_data *ctx_data = hw_mgr_priv; + struct cam_jpeg_hw_ctx_data *ctx_data = hw_mgr_priv; + struct cam_hw_inject_evt_param *evt_params = evt_args; - ctx_data->err_inject_params.err_code = ((struct cam_err_inject_param *) - hw_err_inject_args)->err_code; - ctx_data->err_inject_params.err_type = ((struct cam_err_inject_param *) - hw_err_inject_args)->err_type; - ctx_data->err_inject_params.err_req_id = ((struct cam_err_inject_param *) - hw_err_inject_args)->req_id; - ctx_data->err_inject_params.is_valid = true; + if (!ctx_data || !evt_params) { + CAM_ERR(CAM_JPEG, "Invalid parameters ctx data %s event params %s", + CAM_IS_NULL_TO_STR(ctx_data), CAM_IS_NULL_TO_STR(evt_params)); + return; + } + + memcpy(&ctx_data->evt_inject_params, evt_params, + sizeof(struct cam_hw_inject_evt_param)); + + ctx_data->evt_inject_params.is_valid = true; } int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl, @@ -2233,7 +2249,7 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl, hw_mgr_intf->hw_stop = cam_jpeg_mgr_hw_stop; hw_mgr_intf->hw_cmd = cam_jpeg_mgr_cmd; hw_mgr_intf->hw_dump = cam_jpeg_mgr_hw_dump; - hw_mgr_intf->hw_inject_err = cam_jpeg_mgr_inject_err; + hw_mgr_intf->hw_inject_evt = cam_jpeg_mgr_inject_evt; mutex_init(&g_jpeg_hw_mgr.hw_mgr_mutex); spin_lock_init(&g_jpeg_hw_mgr.hw_mgr_lock); diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h index 817b1ff84a..189543370d 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef CAM_JPEG_HW_MGR_H @@ -104,7 +105,7 @@ struct cam_jpeg_hw_cfg_req { * @wait_complete: Completion info * @cdm_cmd: Cdm cmd submitted for that context. * @mini_dump_cb: Mini dump cb - * @err_inject_params: Error injection params for hw_mgr_ctx + * @evt_inject_params: Event injection params for hw_mgr_ctx */ struct cam_jpeg_hw_ctx_data { void *context_priv; @@ -115,7 +116,7 @@ struct cam_jpeg_hw_ctx_data { struct completion wait_complete; struct cam_cdm_bl_request *cdm_cmd; cam_ctx_mini_dump_cb_func mini_dump_cb; - struct cam_hw_err_param err_inject_params; + struct cam_hw_inject_evt_param evt_inject_params; }; /** diff --git a/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h b/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h index 033982c8ea..5dd0793f5b 100644 --- a/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h +++ b/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef CAM_JPEG_HW_INTF_H @@ -82,6 +83,16 @@ struct cam_jpeg_misr_dump_args { bool enable_bug; }; +/** + * struct cam_jpeg_hw_buf_done_evt_data + * @buf_done_data: buf done payload + * @evt_id: event id (success/cancel/error) + */ +struct cam_jpeg_hw_buf_done_evt_data { + void *buf_done_data; + uint32_t evt_id; +}; + enum cam_jpeg_cmd_type { CAM_JPEG_CMD_CDM_CFG, CAM_JPEG_CMD_SET_IRQ_CB, @@ -94,4 +105,9 @@ enum cam_jpeg_cmd_type { CAM_JPEG_CMD_MAX, }; +enum cam_jpeg_hw_event_type { + CAM_JPEG_EVT_ID_BUF_DONE, + CAM_JPEG_EVT_ID_INDUCE_ERR, +}; + #endif diff --git a/drivers/cam_smmu/cam_smmu_api.c b/drivers/cam_smmu/cam_smmu_api.c index 6be14e0b26..58d1e09902 100644 --- a/drivers/cam_smmu/cam_smmu_api.c +++ b/drivers/cam_smmu/cam_smmu_api.c @@ -925,6 +925,27 @@ static int cam_smmu_iommu_fault_handler(struct iommu_domain *domain, return -ENOSYS; } +int cam_smmu_is_cb_non_fatal_fault_en(int smmu_hdl, bool *non_fatal_en) +{ + int idx; + + if (smmu_hdl == HANDLE_INIT) { + CAM_ERR(CAM_SMMU, "Invalid iommu handle %d", smmu_hdl); + return -EINVAL; + } + + idx = GET_SMMU_TABLE_IDX(smmu_hdl); + if (idx < 0 || idx >= iommu_cb_set.cb_num) { + CAM_ERR(CAM_SMMU, + "Invalid handle or idx. idx: %d, hdl: 0x%x", idx, smmu_hdl); + return -EINVAL; + } + + *non_fatal_en = iommu_cb_set.cb_info[idx].non_fatal_faults_en; + + return 0; +} + void cam_smmu_reset_cb_page_fault_cnt(void) { int idx; diff --git a/drivers/cam_smmu/cam_smmu_api.h b/drivers/cam_smmu/cam_smmu_api.h index ae11c3676f..66ef3edc54 100644 --- a/drivers/cam_smmu/cam_smmu_api.h +++ b/drivers/cam_smmu/cam_smmu_api.h @@ -468,4 +468,9 @@ bool cam_smmu_need_shared_buffer_padding(void); */ bool cam_smmu_is_expanded_memory(void); +/** + * @brief : API to query whether page fault non fatal is enable for a device's context bank + */ +int cam_smmu_is_cb_non_fatal_fault_en(int smmu_hdl, bool *non_fatal_en); + #endif /* _CAM_SMMU_API_H_ */ diff --git a/drivers/cam_utils/cam_common_util.c b/drivers/cam_utils/cam_common_util.c index 4da57d94e4..4203e236fb 100644 --- a/drivers/cam_utils/cam_common_util.c +++ b/drivers/cam_utils/cam_common_util.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -22,10 +23,13 @@ static struct cam_common_mini_dump_dev_info g_minidump_dev_info; #define CAM_PRESIL_POLL_DELAY 20 -static struct cam_common_err_inject_info g_err_inject_info; +static struct cam_common_inject_evt_info g_inject_evt_info; static uint timeout_multiplier = 1; module_param(timeout_multiplier, uint, 0644); +typedef int (*cam_common_evt_inject_cmd_parse_handler)( + struct cam_common_inject_evt_param *inject_params, + uint32_t param_counter, char *token); int cam_common_util_get_string_index(const char **strings, uint32_t num_strings, const char *matching_string, uint32_t *index) @@ -339,201 +343,483 @@ int cam_common_user_dump_helper( return 0; } -int cam_common_register_err_inject_cb( - cam_common_err_inject_cb err_inject_cb, - enum cam_common_err_inject_hw_id hw_id) +int cam_common_register_evt_inject_cb(cam_common_evt_inject_cb evt_inject_cb, + enum cam_common_evt_inject_hw_id hw_id) { int rc = 0; - if (g_err_inject_info.num_hw_registered >= CAM_COMMON_ERR_INJECT_HW_MAX) { + if (g_inject_evt_info.num_hw_registered >= CAM_COMMON_EVT_INJECT_HW_MAX) { CAM_ERR(CAM_UTIL, "No free index available"); return -EINVAL; } - if (!err_inject_cb || hw_id >= CAM_COMMON_ERR_INJECT_HW_MAX) { - CAM_ERR(CAM_UTIL, "Invalid params"); + if (!evt_inject_cb || hw_id >= CAM_COMMON_EVT_INJECT_HW_MAX) { + CAM_ERR(CAM_UTIL, "Invalid params evt_inject_cb %s hw_id: %d", + CAM_IS_NULL_TO_STR(evt_inject_cb), hw_id); return -EINVAL; } - g_err_inject_info.err_inject_cb[hw_id] = err_inject_cb; - g_err_inject_info.num_hw_registered++; - CAM_DBG(CAM_UTIL, "err inject cb registered for HW_id:%d, total registered: %d", hw_id, - g_err_inject_info.num_hw_registered); + g_inject_evt_info.evt_inject_cb[hw_id] = evt_inject_cb; + g_inject_evt_info.num_hw_registered++; + CAM_DBG(CAM_UTIL, "Evt inject cb registered for HW_id: %d, total registered: %d", hw_id, + g_inject_evt_info.num_hw_registered); return rc; } -int cam_common_release_err_params(uint64_t dev_hdl) +void cam_common_release_evt_params(int32_t dev_hdl) { - int rc = 0; struct list_head *pos = NULL, *pos_next = NULL; - struct cam_err_inject_param *err_param; + struct cam_common_inject_evt_param *inject_params; - if (!g_err_inject_info.is_list_initialised) - return -EINVAL; + if (!g_inject_evt_info.is_list_initialised) + return; - if (list_empty(&g_err_inject_info.active_err_ctx_list)) { - CAM_ERR(CAM_UTIL, "list is empty"); - return -EINVAL; + if (list_empty(&g_inject_evt_info.active_evt_ctx_list)) { + CAM_DBG(CAM_UTIL, "Event injection list is initialized but empty"); + return; } - list_for_each_safe(pos, pos_next, &g_err_inject_info.active_err_ctx_list) { - err_param = list_entry(pos, struct cam_err_inject_param, list); - if (err_param->dev_hdl == dev_hdl) { - CAM_INFO(CAM_UTIL, "entry deleted for %llu dev hdl", dev_hdl); + + list_for_each_safe(pos, pos_next, &g_inject_evt_info.active_evt_ctx_list) { + inject_params = list_entry(pos, struct cam_common_inject_evt_param, list); + if (inject_params->dev_hdl == dev_hdl) { + CAM_INFO(CAM_UTIL, "entry deleted for %d dev hdl", dev_hdl); list_del(pos); - kfree(err_param); + kfree(inject_params); } } +} + +static inline int cam_common_evt_inject_get_hw_id(uint8_t *hw_id, char *token) +{ + if (strcmp(token, CAM_COMMON_IFE_NODE) == 0) + *hw_id = CAM_COMMON_EVT_INJECT_HW_ISP; + else if (strcmp(token, CAM_COMMON_ICP_NODE) == 0) + *hw_id = CAM_COMMON_EVT_INJECT_HW_ICP; + else if (strcmp(token, CAM_COMMON_JPEG_NODE) == 0) + *hw_id = CAM_COMMON_EVT_INJECT_HW_JPEG; + else { + CAM_ERR(CAM_UTIL, "Invalid camera hardware [ %s ]", token); + return -EINVAL; + } + + return 0; +} + +static inline int cam_common_evt_inject_get_str_id_type(uint8_t *id_type, char *token) +{ + if (!strcmp(token, CAM_COMMON_EVT_INJECT_BUFFER_ERROR)) + *id_type = CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE; + else if (!strcmp(token, CAM_COMMON_EVT_INJECT_NOTIFY_EVENT)) + *id_type = CAM_COMMON_EVT_INJECT_NOTIFY_EVENT_TYPE; + else { + CAM_ERR(CAM_UTIL, "Invalid string id: %s", token); + return -EINVAL; + } + + return 0; +} + +static int cam_common_evt_inject_parse_buffer_error_evt_params( + struct cam_common_inject_evt_param *inject_params, + uint32_t param_counter, char *token) +{ + struct cam_hw_inject_buffer_error_param *buf_err_params = + &inject_params->evt_params.u.buf_err_evt; + int rc = 0; + + switch (param_counter) { + case SYNC_ERROR_CAUSE: + if (kstrtou32(token, 0, &buf_err_params->sync_error)) { + CAM_ERR(CAM_UTIL, "Invalid event type %s", token); + rc = -EINVAL; + } + break; + default: + CAM_ERR(CAM_UTIL, "Invalid extra parameters: %s", token); + rc = -EINVAL; + } + return rc; } -static int cam_err_inject_set(const char *kmessage, +static int cam_common_evt_inject_parse_node_evt_params( + struct cam_common_inject_evt_param *inject_params, + uint32_t param_counter, char *token) +{ + struct cam_hw_inject_node_evt_param *node_params = + &inject_params->evt_params.u.evt_notify.u.node_evt_params; + int rc = 0; + + switch (param_counter) { + case EVENT_TYPE: + if (kstrtou32(token, 0, &node_params->event_type)) { + CAM_ERR(CAM_UTIL, "Invalid event type %s", token); + rc = -EINVAL; + } + break; + case EVENT_CAUSE: + if (kstrtou32(token, 0, &node_params->event_cause)) { + CAM_ERR(CAM_UTIL, "Invalid event cause %s", token); + rc = -EINVAL; + } + break; + default: + CAM_ERR(CAM_UTIL, "Invalid extra parameters: %s", token); + rc = -EINVAL; + } + + return rc; +} + +static int cam_common_evt_inject_parse_pf_params( + struct cam_common_inject_evt_param *inject_params, + uint32_t param_counter, char *token) +{ + struct cam_hw_inject_pf_evt_param *pf_params = + &inject_params->evt_params.u.evt_notify.u.pf_evt_params; + int rc = 0; + + switch (param_counter) { + case PF_PARAM_CTX_FOUND: + if (kstrtobool(token, &pf_params->ctx_found)) { + CAM_ERR(CAM_UTIL, "Invalid context found value %s", token); + rc = -EINVAL; + } + break; + default: + CAM_ERR(CAM_UTIL, "Invalid extra parameters %s", token); + rc = -EINVAL; + } + + return rc; +} + +static int cam_common_evt_inject_parse_err_evt_params( + struct cam_common_inject_evt_param *inject_params, + uint32_t param_counter, char *token) +{ + struct cam_hw_inject_err_evt_param *err_params = + &inject_params->evt_params.u.evt_notify.u.err_evt_params; + int rc = 0; + + switch (param_counter) { + case ERR_PARAM_ERR_TYPE: + if (kstrtou32(token, 0, &err_params->err_type)) { + CAM_ERR(CAM_UTIL, "Invalid error type %s", token); + rc = -EINVAL; + } + break; + case ERR_PARAM_ERR_CODE: + if (kstrtou32(token, 0, &err_params->err_code)) { + CAM_ERR(CAM_UTIL, "Invalid error code %s", token); + rc = -EINVAL; + } + break; + default: + CAM_ERR(CAM_UTIL, "Invalid extra parameters: %s", token); + rc = -EINVAL; + } + + return rc; +} + +static int cam_common_evt_inject_parse_event_notify( + struct cam_common_inject_evt_param *inject_params, + uint32_t param_counter, char *token) +{ + int rc = 0; + + switch (param_counter) { + case EVT_NOTIFY_TYPE: + if (kstrtou32(token, 0, + &inject_params->evt_params.u.evt_notify.evt_notify_type)) { + CAM_ERR(CAM_UTIL, "Invalid Event notify type %s", token); + rc = -EINVAL; + } + break; + default: + CAM_ERR(CAM_UTIL, "Invalid extra parameters: %s", token); + rc = -EINVAL; + } + + return rc; +} + +static int cam_common_evt_inject_parse_common_params( + struct cam_common_inject_evt_param *inject_params, + uint32_t param_counter, char *token) +{ + int rc = 0; + struct cam_hw_inject_evt_param *evt_param = &inject_params->evt_params; + + switch (param_counter) { + case STRING_ID: + rc = cam_common_evt_inject_get_str_id_type(&evt_param->inject_id, token); + break; + case HW_NAME: + rc = cam_common_evt_inject_get_hw_id(&inject_params->hw_id, token); + break; + case DEV_HDL: + if (kstrtos32(token, 0, &inject_params->dev_hdl)) { + CAM_ERR(CAM_UTIL, "Invalid device handle %s", token); + rc = -EINVAL; + } + break; + case REQ_ID: + if (kstrtou64(token, 0, &evt_param->req_id)) { + CAM_ERR(CAM_UTIL, "Invalid request id %s", token); + rc = -EINVAL; + } + break; + default: + CAM_ERR(CAM_UTIL, "Invalid extra parameter: %s", token); + rc = -EINVAL; + } + + return rc; +} + +static int cam_common_evt_inject_generic_command_parser( + struct cam_common_inject_evt_param *inject_params, + char **msg, uint32_t max_params, cam_common_evt_inject_cmd_parse_handler cmd_parse_cb) +{ + char *token = NULL; + int rc = 0, param_counter = 0; + + token = strsep(msg, ":"); + while (token != NULL) { + rc = cmd_parse_cb(inject_params, param_counter, token); + if (rc) { + CAM_ERR(CAM_UTIL, "Parsed Command failed rc: %d", rc); + return rc; + } + + param_counter++; + if (param_counter == max_params) + break; + token = strsep(msg, ":"); + } + + if (param_counter < max_params) { + CAM_ERR(CAM_UTIL, + "Insufficient parameters passed for total parameters: %u", + param_counter); + return -EINVAL; + } + + return rc; +} + +static int cam_common_evt_inject_set(const char *kmessage, const struct kernel_param *kp) { - int rc = 0; - char tmp_buff[CAM_COMMON_ERR_INJECT_BUFFER_LEN] = {'\0'}; - char *token_start, *token_end; - struct cam_err_inject_param *err_params = NULL; - uint8_t param_counter = 0; + struct cam_common_inject_evt_param *inject_params = NULL; + struct cam_hw_inject_evt_param *hw_evt_params = NULL; + cam_common_evt_inject_cmd_parse_handler parse_handler = NULL; + int rc = 0; + char tmp_buff[CAM_COMMON_EVT_INJECT_BUFFER_LEN]; + char *msg = NULL; + uint32_t param_output = 0; - err_params = kzalloc(sizeof(struct cam_err_inject_param), GFP_KERNEL); - if (!err_params) { + inject_params = kzalloc(sizeof(struct cam_common_inject_evt_param), GFP_KERNEL); + if (!inject_params) { CAM_ERR(CAM_UTIL, "no free memory"); return -ENOMEM; } - memset(tmp_buff, 0, CAM_COMMON_ERR_INJECT_BUFFER_LEN); - rc = strscpy(tmp_buff, kmessage, CAM_COMMON_ERR_INJECT_BUFFER_LEN); + rc = strscpy(tmp_buff, kmessage, CAM_COMMON_EVT_INJECT_BUFFER_LEN); if (rc == -E2BIG) goto free; - token_start = tmp_buff; - token_end = tmp_buff; + CAM_INFO(CAM_UTIL, "parsing input param for cam event injection: %s", tmp_buff); - CAM_INFO(CAM_UTIL, "parsing input param for cam_err_inject: %s", tmp_buff); - while (token_start != NULL) { - strsep(&token_end, ":"); - switch (param_counter) { - case HW_NAME: - if (strcmp(token_start, CAM_COMMON_IFE_NODE) == 0) - err_params->hw_id = CAM_COMMON_ERR_INJECT_HW_ISP; - else if (strcmp(token_start, CAM_COMMON_ICP_NODE) == 0) - err_params->hw_id = CAM_COMMON_ERR_INJECT_HW_ICP; - else if (strcmp(token_start, CAM_COMMON_JPEG_NODE) == 0) - err_params->hw_id = CAM_COMMON_ERR_INJECT_HW_JPEG; - else { - CAM_ERR(CAM_UTIL, "invalid camera hardware [ %s ]", token_start); - goto free; - } + msg = tmp_buff; + hw_evt_params = &inject_params->evt_params; + + rc = cam_common_evt_inject_generic_command_parser(inject_params, &msg, + COMMON_PARAM_MAX, cam_common_evt_inject_parse_common_params); + if (rc) { + CAM_ERR(CAM_UTIL, "Fail to parse common params %d", rc); + goto free; + } + + switch (hw_evt_params->inject_id) { + case CAM_COMMON_EVT_INJECT_NOTIFY_EVENT_TYPE: + rc = cam_common_evt_inject_generic_command_parser(inject_params, &msg, + EVT_NOTIFY_PARAM_MAX, cam_common_evt_inject_parse_event_notify); + if (rc) { + CAM_ERR(CAM_UTIL, "Fail to parse event notify type param %d", rc); + goto free; + } + + switch (hw_evt_params->u.evt_notify.evt_notify_type) { + case V4L_EVENT_CAM_REQ_MGR_ERROR: + parse_handler = cam_common_evt_inject_parse_err_evt_params; + param_output = ERR_PARAM_MAX; break; - case REQ_ID: - if (kstrtou64(token_start, 0, &(err_params->req_id))) - goto free; + case V4L_EVENT_CAM_REQ_MGR_NODE_EVENT: + parse_handler = cam_common_evt_inject_parse_node_evt_params; + param_output = NODE_PARAM_MAX; break; - case ERR_TYPE: - if (kstrtou32(token_start, 0, &(err_params->err_type))) - goto free; - break; - case ERR_CODE: - if (kstrtou32(token_start, 0, &(err_params->err_code))) - goto free; - break; - case DEV_HDL: - if (kstrtou64(token_start, 0, &(err_params->dev_hdl))) - goto free; + case V4L_EVENT_CAM_REQ_MGR_PF_ERROR: + parse_handler = cam_common_evt_inject_parse_pf_params; + param_output = PF_PARAM_MAX; break; default: - CAM_ERR(CAM_UTIL, "Insuffiecient parameter count [%d] ", param_counter); + CAM_ERR(CAM_UTIL, "Invalid event notification type: %u", + hw_evt_params->u.evt_notify.evt_notify_type); goto free; } - - param_counter++; - token_start = token_end; + break; + case CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE: + parse_handler = cam_common_evt_inject_parse_buffer_error_evt_params; + param_output = BUFFER_ERROR_PARAM_MAX; + break; + default: + CAM_ERR(CAM_UTIL, "Invalid Injection id: %u", hw_evt_params->inject_id); } - if (param_counter < CAM_COMMON_ERR_INJECT_PARAM_NUM) { - CAM_ERR(CAM_UTIL, "Insuffiecient parameter count [%d]", param_counter); + rc = cam_common_evt_inject_generic_command_parser(inject_params, &msg, + param_output, parse_handler); + if (rc) { + CAM_ERR(CAM_UTIL, "Command Parsed failed with Inject id: %u rc: %d", + hw_evt_params->inject_id, rc); goto free; } - CAM_INFO(CAM_UTIL, "parsed params: req_id: %llu err_type: %u, err_code: %u dev_hdl: %llu", - err_params->req_id, err_params->err_type, err_params->err_code, - err_params->dev_hdl); - - if (g_err_inject_info.err_inject_cb[err_params->hw_id]) { - rc = g_err_inject_info.err_inject_cb[err_params->hw_id](err_params); + if (g_inject_evt_info.evt_inject_cb[inject_params->hw_id]) { + rc = g_inject_evt_info.evt_inject_cb[inject_params->hw_id](inject_params); if (rc) goto free; - else { - if (!g_err_inject_info.is_list_initialised) { - INIT_LIST_HEAD(&g_err_inject_info.active_err_ctx_list); - g_err_inject_info.is_list_initialised = true; - } - - list_add(&err_params->list, &g_err_inject_info.active_err_ctx_list); - } } else { - CAM_ERR(CAM_UTIL, "Handler for HW_id [%d] not registered", err_params->hw_id); + CAM_ERR(CAM_UTIL, "Handler for HW_id [%hhu] not registered", inject_params->hw_id); goto free; } - if (rc) - CAM_ERR(CAM_UTIL, "No Dev_hdl found: [%d]", err_params->dev_hdl); - - return rc; -free: - kfree(err_params); - return -EINVAL; -} - -static int cam_err_inject_get(char *buffer, - const struct kernel_param *kp) -{ - uint8_t hw_name[10]; - uint16_t buff_max_size = CAM_COMMON_ERR_MODULE_PARAM_MAX_LENGTH; - struct cam_err_inject_param *err_param; - int ret = 0; - - if (!g_err_inject_info.is_list_initialised) - return scnprintf(buffer, buff_max_size, "uninitialised"); - - else if (!list_empty(&g_err_inject_info.active_err_ctx_list)) { - list_for_each_entry(err_param, &g_err_inject_info.active_err_ctx_list, list) { - switch (err_param->hw_id) { - case CAM_COMMON_ERR_INJECT_HW_ISP: - strscpy(hw_name, CAM_COMMON_IFE_NODE, 10); - break; - case CAM_COMMON_ERR_INJECT_HW_ICP: - strscpy(hw_name, CAM_COMMON_ICP_NODE, 10); - break; - case CAM_COMMON_ERR_INJECT_HW_JPEG: - strscpy(hw_name, CAM_COMMON_JPEG_NODE, 10); - break; - default: - strscpy(hw_name, "undef", 10); - } - ret += scnprintf(buffer+ret, buff_max_size, - "hw_name: %s req_id: %u err_type: %u err_code: %u dev_hdl: %d\n", - hw_name, err_param->req_id, err_param->err_type, - err_param->err_code, err_param->dev_hdl); - - CAM_DBG(CAM_UTIL, "output buffer: %s", buffer); - - if (ret < buff_max_size) { - buff_max_size = buff_max_size - ret; - } else { - CAM_WARN(CAM_UTIL, "out buff max limit reached"); - break; - } - } - return ret; + if (!g_inject_evt_info.is_list_initialised) { + INIT_LIST_HEAD(&g_inject_evt_info.active_evt_ctx_list); + g_inject_evt_info.is_list_initialised = true; } - return scnprintf(buffer, buff_max_size, "uninitialised"); + list_add(&inject_params->list, &g_inject_evt_info.active_evt_ctx_list); + + return rc; + +free: + kfree(inject_params); + return rc; } -static const struct kernel_param_ops cam_error_inject_ops = { - .set = cam_err_inject_set, - .get = cam_err_inject_get +static int cam_common_evt_inject_get(char *buffer, + const struct kernel_param *kp) +{ + uint8_t hw_name[16], string_id[16]; + uint16_t buff_max_size = CAM_COMMON_EVT_INJECT_MODULE_PARAM_MAX_LENGTH; + struct cam_common_inject_evt_param *inject_params = NULL; + struct cam_hw_inject_evt_param *evt_params = NULL; + uint32_t ret = 0; + + if (!g_inject_evt_info.is_list_initialised) + return scnprintf(buffer, buff_max_size, "uninitialised"); + + if (list_empty(&g_inject_evt_info.active_evt_ctx_list)) + return scnprintf(buffer, buff_max_size, "Active err inject list is empty"); + + list_for_each_entry(inject_params, &g_inject_evt_info.active_evt_ctx_list, list) { + evt_params = &inject_params->evt_params; + + switch (inject_params->hw_id) { + case CAM_COMMON_EVT_INJECT_HW_ISP: + strscpy(hw_name, CAM_COMMON_IFE_NODE, sizeof(hw_name)); + break; + case CAM_COMMON_EVT_INJECT_HW_ICP: + strscpy(hw_name, CAM_COMMON_ICP_NODE, sizeof(hw_name)); + break; + case CAM_COMMON_EVT_INJECT_HW_JPEG: + strscpy(hw_name, CAM_COMMON_JPEG_NODE, sizeof(hw_name)); + break; + default: + ret += scnprintf(buffer+ret, buff_max_size, "Undefined HW id\n"); + goto undefined_param; + } + + switch (evt_params->inject_id) { + case CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE: + strscpy(string_id, CAM_COMMON_EVT_INJECT_BUFFER_ERROR, sizeof(string_id)); + break; + case CAM_COMMON_EVT_INJECT_NOTIFY_EVENT_TYPE: + strscpy(string_id, CAM_COMMON_EVT_INJECT_NOTIFY_EVENT, sizeof(string_id)); + break; + default: + ret += scnprintf(buffer+ret, buff_max_size, "Undefined string id\n"); + goto undefined_param; + } + + ret += scnprintf(buffer+ret, buff_max_size, + "string_id: %s hw_name: %s dev_hdl: %d req_id: %llu ", + string_id, hw_name, + inject_params->dev_hdl, evt_params->req_id); + + if (buff_max_size > ret) { + buff_max_size -= ret; + } else { + CAM_WARN(CAM_UTIL, "out buff max limit reached"); + break; + } + + if (evt_params->inject_id == + CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE) { + ret += scnprintf(buffer+ret, buff_max_size, + "sync_error: %u\n", evt_params->u.buf_err_evt.sync_error); + } else { + switch (evt_params->u.evt_notify.evt_notify_type) { + case V4L_EVENT_CAM_REQ_MGR_ERROR: { + struct cam_hw_inject_err_evt_param *err_evt_params = + &evt_params->u.evt_notify.u.err_evt_params; + ret += scnprintf(buffer+ret, buff_max_size, + "Error event: error type: %u error code: %u\n", + err_evt_params->err_type, err_evt_params->err_code); + break; + } + case V4L_EVENT_CAM_REQ_MGR_NODE_EVENT: { + struct cam_hw_inject_node_evt_param *node_evt_params = + &evt_params->u.evt_notify.u.node_evt_params; + ret += scnprintf(buffer+ret, buff_max_size, + "Node event: event type: %u event cause: %u\n", + node_evt_params->event_type, node_evt_params->event_cause); + break; + } + case V4L_EVENT_CAM_REQ_MGR_PF_ERROR: { + struct cam_hw_inject_pf_evt_param *pf_evt_params = + &evt_params->u.evt_notify.u.pf_evt_params; + ret += scnprintf(buffer+ret, buff_max_size, + "PF event: ctx found %hhu\n", + pf_evt_params->ctx_found); + break; + } + default: + ret += scnprintf(buffer+ret, buff_max_size, + "Undefined notification event\n"); + } + } + +undefined_param: + CAM_DBG(CAM_UTIL, "output buffer: %s", buffer); + + if (buff_max_size > ret) { + buff_max_size -= ret; + } else { + CAM_WARN(CAM_UTIL, "out buff max limit reached"); + break; + } + } + + return ret; +} + +static const struct kernel_param_ops cam_common_evt_inject = { + .set = cam_common_evt_inject_set, + .get = cam_common_evt_inject_get }; -module_param_cb(cam_error_inject, &cam_error_inject_ops, NULL, 0644); +module_param_cb(cam_event_inject, &cam_common_evt_inject, NULL, 0644); diff --git a/drivers/cam_utils/cam_common_util.h b/drivers/cam_utils/cam_common_util.h index 5a941b4af8..3d87ed4b99 100644 --- a/drivers/cam_utils/cam_common_util.h +++ b/drivers/cam_utils/cam_common_util.h @@ -10,6 +10,8 @@ #include #include +#include "cam_hw_mgr_intf.h" + #define CAM_BITS_MASK_SHIFT(x, mask, shift) (((x) & (mask)) >> shift) #define CAM_36BIT_INTF_GET_IOVA_BASE(iova) ((iova) >> 8) #define CAM_36BIT_INTF_GET_IOVA_OFFSET(iova) ((iova) & 0xff) @@ -21,12 +23,12 @@ #define CAM_COMMON_HW_DUMP_TAG_MAX_LEN 64 #define CAM_MAX_NUM_CCI_PAYLOAD_BYTES 11 -#define CAM_COMMON_ERR_MODULE_PARAM_MAX_LENGTH 4096 -#define CAM_COMMON_ERR_INJECT_BUFFER_LEN 200 -#define CAM_COMMON_ERR_INJECT_DEV_MAX 5 -#define CAM_COMMON_ERR_INJECT_PARAM_NUM 5 -#define CAM_COMMON_IFE_NODE "IFE" -#define CAM_COMMON_ICP_NODE "IPE" +#define CAM_COMMON_EVT_INJECT_MODULE_PARAM_MAX_LENGTH 4096 +#define CAM_COMMON_EVT_INJECT_BUFFER_LEN 200 +#define CAM_COMMON_EVT_INJECT_BUFFER_ERROR "Buffer_Error" +#define CAM_COMMON_EVT_INJECT_NOTIFY_EVENT "Notify_Event" +#define CAM_COMMON_IFE_NODE "IFE" +#define CAM_COMMON_ICP_NODE "IPE" #define CAM_COMMON_JPEG_NODE "JPEG" #define CAM_COMMON_NS_PER_MS 1000000ULL @@ -110,49 +112,91 @@ struct cam_common_mini_dump_data { }; -typedef int (*cam_common_err_inject_cb) (void *err_param); -int cam_common_release_err_params(uint64_t dev_hdl); +typedef int (*cam_common_evt_inject_cb) (void *inject_args); -enum cam_common_err_inject_hw_id { - CAM_COMMON_ERR_INJECT_HW_ISP, - CAM_COMMON_ERR_INJECT_HW_ICP, - CAM_COMMON_ERR_INJECT_HW_JPEG, - CAM_COMMON_ERR_INJECT_HW_MAX +enum cam_common_evt_inject_str_id_type { + CAM_COMMON_EVT_INJECT_BUFFER_ERROR_TYPE, + CAM_COMMON_EVT_INJECT_NOTIFY_EVENT_TYPE }; -enum cam_common_err_inject_input_param_pos { - HW_NAME = 0, +enum cam_common_evt_inject_hw_id { + CAM_COMMON_EVT_INJECT_HW_ISP, + CAM_COMMON_EVT_INJECT_HW_ICP, + CAM_COMMON_EVT_INJECT_HW_JPEG, + CAM_COMMON_EVT_INJECT_HW_MAX +}; + +enum cam_common_evt_inject_common_param_pos { + STRING_ID, + HW_NAME, + DEV_HDL, REQ_ID, - ERR_TYPE, - ERR_CODE, - DEV_HDL + COMMON_PARAM_MAX +}; + +enum cam_common_evt_inject_notify_event_pos { + EVT_NOTIFY_TYPE, + EVT_NOTIFY_PARAM_MAX +}; + +enum cam_evt_inject_buffer_error_event { + SYNC_ERROR_CAUSE, + BUFFER_ERROR_PARAM_MAX +}; + +enum cam_evt_inject_error_param_pos { + ERR_PARAM_ERR_TYPE, + ERR_PARAM_ERR_CODE, + ERR_PARAM_MAX +}; + +enum cam_evt_inject_node_param_pos { + EVENT_TYPE, + EVENT_CAUSE, + NODE_PARAM_MAX, +}; + +enum cam_evt_inject_pf_params_pos { + PF_PARAM_CTX_FOUND, + PF_PARAM_MAX }; /** - * @req_id : req id for err to be injected - * @dev_hdl : dev_hdl for the context - * @err_type: error type for error request - * @err_code: error code for error request - * @hw_id : hw id representing hw nodes of type cam_common_err_inject_hw_id + * struct cam_common_evt_inject_data + * @buf_done_data: buf done data + * @evt_params : event params for the injected event */ -struct cam_err_inject_param { - struct list_head list; - uint64_t req_id; - uint64_t dev_hdl; - uint32_t err_type; - uint32_t err_code; - uint8_t hw_id; +struct cam_common_evt_inject_data { + void *buf_done_data; + struct cam_hw_inject_evt_param *evt_params; }; + +typedef int (*cam_common_evt_inject_ops) (void *cam_ctx, + struct cam_common_evt_inject_data *inject_evt); + /** - * struct cam_common_err_inject_info - * @err_inject_cb : address of callback - * @active_err_ctx_list: list containing active err inject requests - * @num_hw_registered : number of callbacks registered - * @is_list_initialised: bool to check init for err_inject list + * struct cam_common_inject_evt_param + * @evt_params : injection event params + * @dev_hdl : device handle to match with ctx's dev_hdl + * @hw_id : hw to be injected with the event */ -struct cam_common_err_inject_info { - cam_common_err_inject_cb err_inject_cb[CAM_COMMON_ERR_INJECT_HW_MAX]; - struct list_head active_err_ctx_list; +struct cam_common_inject_evt_param { + struct list_head list; + struct cam_hw_inject_evt_param evt_params; + int32_t dev_hdl; + uint8_t hw_id; +}; + +/** + * struct cam_common_inject_evt_info + * @evt_inject_cb : address of callback + * @active_err_ctx_list: list containing active evt inject requests + * @num_hw_registered : number of callbacks registered + * @is_list_initialised: bool to check init for evt_inject list + */ +struct cam_common_inject_evt_info { + cam_common_evt_inject_cb evt_inject_cb[CAM_COMMON_EVT_INJECT_HW_MAX]; + struct list_head active_evt_ctx_list; uint8_t num_hw_registered; bool is_list_initialised; }; @@ -189,6 +233,13 @@ struct cam_common_hw_dump_header { uint32_t word_size; }; +/** + * @brief release all event inject params in the g_inject_evt_info + * for a specific dev_hdl + * @dev_hdl: device handle to which the evt inject params belong to + */ +void cam_common_release_evt_params(int32_t dev_hdl); + /** * cam_common_util_get_string_index() * @@ -338,17 +389,17 @@ int cam_common_user_dump_helper( ...); /** - * cam_common_register_err_inject_cb() + * cam_common_register_evt_inject_cb() * - * @brief common interface to register error inject cb + * @brief common interface to register evt inject cb * - * @err_inject_cb: Pointer to err_inject_cb + * @evt_inject_cb: Pointer to evt_inject_cb * @hw_id: HW id of the HW driver registering * * @return: 0 if success in register non-zero if failes */ -int cam_common_register_err_inject_cb( - cam_common_err_inject_cb err_inject_cb, - enum cam_common_err_inject_hw_id hw_id); +int cam_common_register_evt_inject_cb( + cam_common_evt_inject_cb evt_inject_cb, + enum cam_common_evt_inject_hw_id hw_id); #endif /* _CAM_COMMON_UTIL_H_ */