Loading drivers/cam_isp/cam_isp_context.c +8 −2 Original line number Diff line number Diff line Loading @@ -1818,8 +1818,14 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, if (notify.error == CRM_KMD_ERR_FATAL) { req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.err_msg.device_hdl = ctx_isp->base->dev_hdl; if (error_type == CAM_ISP_HW_ERROR_CSID_FATAL) req_msg.u.err_msg.error_type = CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY; else req_msg.u.err_msg.error_type = CAM_REQ_MGR_ERROR_TYPE_RECOVERY; req_msg.u.err_msg.link_hdl = ctx_isp->base->link_hdl; req_msg.u.err_msg.request_id = error_request_id; req_msg.u.err_msg.resource_size = 0x0; Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +64 −3 Original line number Diff line number Diff line Loading @@ -1918,6 +1918,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( csid_acquire.in_port = in_port; csid_acquire.out_port = in_port->data; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_ife_hw_mgr_event_handler; csid_acquire.priv = ife_ctx; csid_acquire.crop_enable = crop_enable; csid_acquire.drop_enable = false; Loading Loading @@ -2046,6 +2048,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( csid_acquire.in_port = in_port; csid_acquire.out_port = out_port; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_ife_hw_mgr_event_handler; csid_acquire.priv = ife_ctx; /* * Enable RDI pixel drop by default. CSID will enable only for Loading Loading @@ -6363,6 +6367,12 @@ static int cam_ife_hw_mgr_find_affected_ctx( affected_core, CAM_IFE_HW_NUM_MAX)) continue; if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) { CAM_INFO(CAM_ISP, "CTX:%d already error reported", ife_hwr_mgr_ctx->ctx_index); continue; } atomic_set(&ife_hwr_mgr_ctx->overflow_pending, 1); notify_err_cb = ife_hwr_mgr_ctx->common.event_cb[event_type]; Loading @@ -6378,8 +6388,13 @@ static int cam_ife_hw_mgr_find_affected_ctx( * In the call back function corresponding ISP context * will update CRM about fatal Error */ if (notify_err_cb) { notify_err_cb(ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_ERROR, error_event_data); } else { CAM_WARN(CAM_ISP, "Error call back is not set"); goto end; } } /* fill the affected_core in recovery data */ Loading @@ -6388,7 +6403,34 @@ static int cam_ife_hw_mgr_find_affected_ctx( CAM_DBG(CAM_ISP, "Vfe core %d is affected (%d)", i, recovery_data->affected_core[i]); } end: return 0; } static int cam_ife_hw_mgr_handle_csid_event( struct cam_isp_hw_event_info *event_info) { struct cam_isp_hw_error_event_data error_event_data = {0}; struct cam_ife_hw_event_recovery_data recovery_data = {0}; /* this can be extended based on the types of error * received from CSID */ switch (event_info->err_type) { case CAM_ISP_HW_ERROR_CSID_FATAL: { if (!g_ife_hw_mgr.debug_cfg.enable_csid_recovery) break; error_event_data.error_type = event_info->err_type; cam_ife_hw_mgr_find_affected_ctx(&error_event_data, event_info->hw_idx, &recovery_data); break; } default: break; } return 0; } Loading @@ -6408,6 +6450,13 @@ static int cam_ife_hw_mgr_handle_hw_err( else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT) error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW; spin_lock(&g_ife_hw_mgr.ctx_lock); if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) { rc = cam_ife_hw_mgr_handle_csid_event(event_info); spin_unlock(&g_ife_hw_mgr.ctx_lock); return rc; } core_idx = event_info->hw_idx; if (g_ife_hw_mgr.debug_cfg.enable_recovery) Loading @@ -6418,6 +6467,8 @@ static int cam_ife_hw_mgr_handle_hw_err( rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data, core_idx, &recovery_data); if (rc || !(recovery_data.no_of_context)) goto end; if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION) recovery_data.error_type = CAM_ISP_HW_ERROR_VIOLATION; Loading @@ -6425,7 +6476,8 @@ static int cam_ife_hw_mgr_handle_hw_err( recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW; cam_ife_hw_mgr_do_error_recovery(&recovery_data); end: spin_unlock(&g_ife_hw_mgr.ctx_lock); return rc; } Loading Loading @@ -6875,6 +6927,14 @@ static int cam_ife_hw_mgr_debug_register(void) goto err; } if (!debugfs_create_u32("enable_csid_recovery", 0644, g_ife_hw_mgr.debug_cfg.dentry, &g_ife_hw_mgr.debug_cfg.enable_csid_recovery)) { CAM_ERR(CAM_ISP, "failed to create enable_csid_recovery"); goto err; } if (!debugfs_create_bool("enable_req_dump", 0644, g_ife_hw_mgr.debug_cfg.dentry, Loading Loading @@ -6921,6 +6981,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) memset(&g_ife_hw_mgr, 0, sizeof(g_ife_hw_mgr)); mutex_init(&g_ife_hw_mgr.ctx_mutex); spin_lock_init(&g_ife_hw_mgr.ctx_lock); if (CAM_IFE_HW_NUM_MAX != CAM_IFE_CSID_HW_NUM_MAX) { CAM_ERR(CAM_ISP, "CSID num is different then IFE num"); Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ * @dentry: Debugfs entry * @csid_debug: csid debug information * @enable_recovery: enable recovery * @enable_csid_recovery: enable csid recovery * @enable_diag_sensor_status: enable sensor diagnosis status * @enable_req_dump: Enable request dump on HW errors * @per_req_reg_dump: Enable per request reg dump Loading @@ -33,6 +34,7 @@ struct cam_ife_hw_mgr_debug { struct dentry *dentry; uint64_t csid_debug; uint32_t enable_recovery; uint32_t enable_csid_recovery; uint32_t camif_debug; bool enable_req_dump; bool per_req_reg_dump; Loading Loading @@ -148,6 +150,7 @@ struct cam_ife_hw_mgr_ctx { * @ife_dev_caps ife device capability per core * @work q work queue for IFE hw manager * @debug_cfg debug configuration * @ctx_lock Spinlock for HW manager */ struct cam_ife_hw_mgr { struct cam_isp_hw_mgr mgr_common; Loading @@ -166,6 +169,7 @@ struct cam_ife_hw_mgr { struct cam_vfe_hw_get_hw_cap ife_dev_caps[CAM_IFE_HW_NUM_MAX]; struct cam_req_mgr_core_workq *workq; struct cam_ife_hw_mgr_debug debug_cfg; spinlock_t ctx_lock; }; /** Loading drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +64 −3 Original line number Diff line number Diff line Loading @@ -1458,6 +1458,8 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_rdi( csid_acquire.out_port = out_port; csid_acquire.sync_mode = CAM_ISP_HW_SYNC_NONE; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler; csid_acquire.event_cb_prv = tfe_ctx; if (tfe_ctx->is_tpg) { if (tfe_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx == Loading Loading @@ -4904,6 +4906,12 @@ static int cam_tfe_hw_mgr_find_affected_ctx( affected_core, CAM_TFE_HW_NUM_MAX)) continue; if (atomic_read(&tfe_hwr_mgr_ctx->overflow_pending)) { CAM_INFO(CAM_ISP, "CTX:%d already error reported", tfe_hwr_mgr_ctx->ctx_index); continue; } atomic_set(&tfe_hwr_mgr_ctx->overflow_pending, 1); notify_err_cb = tfe_hwr_mgr_ctx->common.event_cb[event_type]; Loading @@ -4919,8 +4927,13 @@ static int cam_tfe_hw_mgr_find_affected_ctx( * In the call back function corresponding ISP context * will update CRM about fatal Error */ if (notify_err_cb) { notify_err_cb(tfe_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_ERROR, error_event_data); } else { CAM_WARN(CAM_ISP, "Error call back is not set"); goto end; } } /* fill the affected_core in recovery data */ Loading @@ -4929,7 +4942,34 @@ static int cam_tfe_hw_mgr_find_affected_ctx( CAM_DBG(CAM_ISP, "tfe core %d is affected (%d)", i, recovery_data->affected_core[i]); } end: return 0; } static int cam_tfe_hw_mgr_handle_csid_event( struct cam_isp_hw_event_info *event_info) { struct cam_isp_hw_error_event_data error_event_data = {0}; struct cam_tfe_hw_event_recovery_data recovery_data = {0}; /* this can be extended based on the types of error * received from CSID */ switch (event_info->err_type) { case CAM_ISP_HW_ERROR_CSID_FATAL: { if (!g_tfe_hw_mgr.debug_cfg.enable_csid_recovery) break; error_event_data.error_type = event_info->err_type; cam_tfe_hw_mgr_find_affected_ctx(&error_event_data, event_info->hw_idx, &recovery_data); break; } default: break; } return 0; } Loading @@ -4950,6 +4990,13 @@ static int cam_tfe_hw_mgr_handle_hw_err( else if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW; spin_lock(&g_tfe_hw_mgr.ctx_lock); if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) { rc = cam_tfe_hw_mgr_handle_csid_event(event_info); spin_unlock(&g_tfe_hw_mgr.ctx_lock); return rc; } core_idx = event_info->hw_idx; if (g_tfe_hw_mgr.debug_cfg.enable_recovery) Loading @@ -4959,9 +5006,13 @@ static int cam_tfe_hw_mgr_handle_hw_err( rc = cam_tfe_hw_mgr_find_affected_ctx(&error_event_data, core_idx, &recovery_data); if (rc || !(recovery_data.no_of_context)) goto end; if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) { spin_unlock(&g_tfe_hw_mgr.ctx_lock); return rc; } if (g_tfe_hw_mgr.debug_cfg.enable_recovery) { /* Trigger for recovery */ Loading @@ -4974,7 +5025,8 @@ static int cam_tfe_hw_mgr_handle_hw_err( CAM_DBG(CAM_ISP, "recovery is not enabled"); rc = 0; } end: spin_unlock(&g_tfe_hw_mgr.ctx_lock); return rc; } Loading Loading @@ -5422,6 +5474,14 @@ static int cam_tfe_hw_mgr_debug_register(void) goto err; } if (!debugfs_create_u32("enable_csid_recovery", 0644, g_tfe_hw_mgr.debug_cfg.dentry, &g_tfe_hw_mgr.debug_cfg.enable_csid_recovery)) { CAM_ERR(CAM_ISP, "failed to create enable_csid_recovery"); goto err; } if (!debugfs_create_u32("enable_reg_dump", 0644, g_tfe_hw_mgr.debug_cfg.dentry, Loading Loading @@ -5469,6 +5529,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) memset(&g_tfe_hw_mgr, 0, sizeof(g_tfe_hw_mgr)); mutex_init(&g_tfe_hw_mgr.ctx_mutex); spin_lock_init(&g_tfe_hw_mgr.ctx_lock); if (CAM_TFE_HW_NUM_MAX != CAM_TFE_CSID_HW_NUM_MAX) { CAM_ERR(CAM_ISP, "CSID num is different then TFE num"); Loading drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ * @dentry: Debugfs entry * @csid_debug: csid debug information * @enable_recovery: enable recovery * @enable_csid_recovery: enable csid recovery * @camif_debug: enable sensor diagnosis status * @enable_reg_dump: enable reg dump on error; * @per_req_reg_dump: Enable per request reg dump Loading @@ -37,6 +38,7 @@ struct cam_tfe_hw_mgr_debug { struct dentry *dentry; uint64_t csid_debug; uint32_t enable_recovery; uint32_t enable_csid_recovery; uint32_t camif_debug; uint32_t enable_reg_dump; uint32_t per_req_reg_dump; Loading Loading @@ -152,6 +154,7 @@ struct cam_tfe_hw_mgr_ctx { * @tfe_dev_caps tfe device capability per core * @work q work queue for TFE hw manager * @debug_cfg debug configuration * @ctx_lock Spinlock for HW manager */ struct cam_tfe_hw_mgr { struct cam_isp_hw_mgr mgr_common; Loading @@ -170,6 +173,7 @@ struct cam_tfe_hw_mgr { struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX]; struct cam_req_mgr_core_workq *workq; struct cam_tfe_hw_mgr_debug debug_cfg; spinlock_t ctx_lock; }; /** Loading Loading
drivers/cam_isp/cam_isp_context.c +8 −2 Original line number Diff line number Diff line Loading @@ -1818,8 +1818,14 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, if (notify.error == CRM_KMD_ERR_FATAL) { req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.err_msg.device_hdl = ctx_isp->base->dev_hdl; if (error_type == CAM_ISP_HW_ERROR_CSID_FATAL) req_msg.u.err_msg.error_type = CAM_REQ_MGR_ERROR_TYPE_FULL_RECOVERY; else req_msg.u.err_msg.error_type = CAM_REQ_MGR_ERROR_TYPE_RECOVERY; req_msg.u.err_msg.link_hdl = ctx_isp->base->link_hdl; req_msg.u.err_msg.request_id = error_request_id; req_msg.u.err_msg.resource_size = 0x0; Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +64 −3 Original line number Diff line number Diff line Loading @@ -1918,6 +1918,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( csid_acquire.in_port = in_port; csid_acquire.out_port = in_port->data; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_ife_hw_mgr_event_handler; csid_acquire.priv = ife_ctx; csid_acquire.crop_enable = crop_enable; csid_acquire.drop_enable = false; Loading Loading @@ -2046,6 +2048,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( csid_acquire.in_port = in_port; csid_acquire.out_port = out_port; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_ife_hw_mgr_event_handler; csid_acquire.priv = ife_ctx; /* * Enable RDI pixel drop by default. CSID will enable only for Loading Loading @@ -6363,6 +6367,12 @@ static int cam_ife_hw_mgr_find_affected_ctx( affected_core, CAM_IFE_HW_NUM_MAX)) continue; if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) { CAM_INFO(CAM_ISP, "CTX:%d already error reported", ife_hwr_mgr_ctx->ctx_index); continue; } atomic_set(&ife_hwr_mgr_ctx->overflow_pending, 1); notify_err_cb = ife_hwr_mgr_ctx->common.event_cb[event_type]; Loading @@ -6378,8 +6388,13 @@ static int cam_ife_hw_mgr_find_affected_ctx( * In the call back function corresponding ISP context * will update CRM about fatal Error */ if (notify_err_cb) { notify_err_cb(ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_ERROR, error_event_data); } else { CAM_WARN(CAM_ISP, "Error call back is not set"); goto end; } } /* fill the affected_core in recovery data */ Loading @@ -6388,7 +6403,34 @@ static int cam_ife_hw_mgr_find_affected_ctx( CAM_DBG(CAM_ISP, "Vfe core %d is affected (%d)", i, recovery_data->affected_core[i]); } end: return 0; } static int cam_ife_hw_mgr_handle_csid_event( struct cam_isp_hw_event_info *event_info) { struct cam_isp_hw_error_event_data error_event_data = {0}; struct cam_ife_hw_event_recovery_data recovery_data = {0}; /* this can be extended based on the types of error * received from CSID */ switch (event_info->err_type) { case CAM_ISP_HW_ERROR_CSID_FATAL: { if (!g_ife_hw_mgr.debug_cfg.enable_csid_recovery) break; error_event_data.error_type = event_info->err_type; cam_ife_hw_mgr_find_affected_ctx(&error_event_data, event_info->hw_idx, &recovery_data); break; } default: break; } return 0; } Loading @@ -6408,6 +6450,13 @@ static int cam_ife_hw_mgr_handle_hw_err( else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT) error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW; spin_lock(&g_ife_hw_mgr.ctx_lock); if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) { rc = cam_ife_hw_mgr_handle_csid_event(event_info); spin_unlock(&g_ife_hw_mgr.ctx_lock); return rc; } core_idx = event_info->hw_idx; if (g_ife_hw_mgr.debug_cfg.enable_recovery) Loading @@ -6418,6 +6467,8 @@ static int cam_ife_hw_mgr_handle_hw_err( rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data, core_idx, &recovery_data); if (rc || !(recovery_data.no_of_context)) goto end; if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION) recovery_data.error_type = CAM_ISP_HW_ERROR_VIOLATION; Loading @@ -6425,7 +6476,8 @@ static int cam_ife_hw_mgr_handle_hw_err( recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW; cam_ife_hw_mgr_do_error_recovery(&recovery_data); end: spin_unlock(&g_ife_hw_mgr.ctx_lock); return rc; } Loading Loading @@ -6875,6 +6927,14 @@ static int cam_ife_hw_mgr_debug_register(void) goto err; } if (!debugfs_create_u32("enable_csid_recovery", 0644, g_ife_hw_mgr.debug_cfg.dentry, &g_ife_hw_mgr.debug_cfg.enable_csid_recovery)) { CAM_ERR(CAM_ISP, "failed to create enable_csid_recovery"); goto err; } if (!debugfs_create_bool("enable_req_dump", 0644, g_ife_hw_mgr.debug_cfg.dentry, Loading Loading @@ -6921,6 +6981,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) memset(&g_ife_hw_mgr, 0, sizeof(g_ife_hw_mgr)); mutex_init(&g_ife_hw_mgr.ctx_mutex); spin_lock_init(&g_ife_hw_mgr.ctx_lock); if (CAM_IFE_HW_NUM_MAX != CAM_IFE_CSID_HW_NUM_MAX) { CAM_ERR(CAM_ISP, "CSID num is different then IFE num"); Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ * @dentry: Debugfs entry * @csid_debug: csid debug information * @enable_recovery: enable recovery * @enable_csid_recovery: enable csid recovery * @enable_diag_sensor_status: enable sensor diagnosis status * @enable_req_dump: Enable request dump on HW errors * @per_req_reg_dump: Enable per request reg dump Loading @@ -33,6 +34,7 @@ struct cam_ife_hw_mgr_debug { struct dentry *dentry; uint64_t csid_debug; uint32_t enable_recovery; uint32_t enable_csid_recovery; uint32_t camif_debug; bool enable_req_dump; bool per_req_reg_dump; Loading Loading @@ -148,6 +150,7 @@ struct cam_ife_hw_mgr_ctx { * @ife_dev_caps ife device capability per core * @work q work queue for IFE hw manager * @debug_cfg debug configuration * @ctx_lock Spinlock for HW manager */ struct cam_ife_hw_mgr { struct cam_isp_hw_mgr mgr_common; Loading @@ -166,6 +169,7 @@ struct cam_ife_hw_mgr { struct cam_vfe_hw_get_hw_cap ife_dev_caps[CAM_IFE_HW_NUM_MAX]; struct cam_req_mgr_core_workq *workq; struct cam_ife_hw_mgr_debug debug_cfg; spinlock_t ctx_lock; }; /** Loading
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +64 −3 Original line number Diff line number Diff line Loading @@ -1458,6 +1458,8 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_rdi( csid_acquire.out_port = out_port; csid_acquire.sync_mode = CAM_ISP_HW_SYNC_NONE; csid_acquire.node_res = NULL; csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler; csid_acquire.event_cb_prv = tfe_ctx; if (tfe_ctx->is_tpg) { if (tfe_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx == Loading Loading @@ -4904,6 +4906,12 @@ static int cam_tfe_hw_mgr_find_affected_ctx( affected_core, CAM_TFE_HW_NUM_MAX)) continue; if (atomic_read(&tfe_hwr_mgr_ctx->overflow_pending)) { CAM_INFO(CAM_ISP, "CTX:%d already error reported", tfe_hwr_mgr_ctx->ctx_index); continue; } atomic_set(&tfe_hwr_mgr_ctx->overflow_pending, 1); notify_err_cb = tfe_hwr_mgr_ctx->common.event_cb[event_type]; Loading @@ -4919,8 +4927,13 @@ static int cam_tfe_hw_mgr_find_affected_ctx( * In the call back function corresponding ISP context * will update CRM about fatal Error */ if (notify_err_cb) { notify_err_cb(tfe_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_ERROR, error_event_data); } else { CAM_WARN(CAM_ISP, "Error call back is not set"); goto end; } } /* fill the affected_core in recovery data */ Loading @@ -4929,7 +4942,34 @@ static int cam_tfe_hw_mgr_find_affected_ctx( CAM_DBG(CAM_ISP, "tfe core %d is affected (%d)", i, recovery_data->affected_core[i]); } end: return 0; } static int cam_tfe_hw_mgr_handle_csid_event( struct cam_isp_hw_event_info *event_info) { struct cam_isp_hw_error_event_data error_event_data = {0}; struct cam_tfe_hw_event_recovery_data recovery_data = {0}; /* this can be extended based on the types of error * received from CSID */ switch (event_info->err_type) { case CAM_ISP_HW_ERROR_CSID_FATAL: { if (!g_tfe_hw_mgr.debug_cfg.enable_csid_recovery) break; error_event_data.error_type = event_info->err_type; cam_tfe_hw_mgr_find_affected_ctx(&error_event_data, event_info->hw_idx, &recovery_data); break; } default: break; } return 0; } Loading @@ -4950,6 +4990,13 @@ static int cam_tfe_hw_mgr_handle_hw_err( else if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW; spin_lock(&g_tfe_hw_mgr.ctx_lock); if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) { rc = cam_tfe_hw_mgr_handle_csid_event(event_info); spin_unlock(&g_tfe_hw_mgr.ctx_lock); return rc; } core_idx = event_info->hw_idx; if (g_tfe_hw_mgr.debug_cfg.enable_recovery) Loading @@ -4959,9 +5006,13 @@ static int cam_tfe_hw_mgr_handle_hw_err( rc = cam_tfe_hw_mgr_find_affected_ctx(&error_event_data, core_idx, &recovery_data); if (rc || !(recovery_data.no_of_context)) goto end; if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) if (event_info->res_type == CAM_ISP_RESOURCE_TFE_OUT) { spin_unlock(&g_tfe_hw_mgr.ctx_lock); return rc; } if (g_tfe_hw_mgr.debug_cfg.enable_recovery) { /* Trigger for recovery */ Loading @@ -4974,7 +5025,8 @@ static int cam_tfe_hw_mgr_handle_hw_err( CAM_DBG(CAM_ISP, "recovery is not enabled"); rc = 0; } end: spin_unlock(&g_tfe_hw_mgr.ctx_lock); return rc; } Loading Loading @@ -5422,6 +5474,14 @@ static int cam_tfe_hw_mgr_debug_register(void) goto err; } if (!debugfs_create_u32("enable_csid_recovery", 0644, g_tfe_hw_mgr.debug_cfg.dentry, &g_tfe_hw_mgr.debug_cfg.enable_csid_recovery)) { CAM_ERR(CAM_ISP, "failed to create enable_csid_recovery"); goto err; } if (!debugfs_create_u32("enable_reg_dump", 0644, g_tfe_hw_mgr.debug_cfg.dentry, Loading Loading @@ -5469,6 +5529,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) memset(&g_tfe_hw_mgr, 0, sizeof(g_tfe_hw_mgr)); mutex_init(&g_tfe_hw_mgr.ctx_mutex); spin_lock_init(&g_tfe_hw_mgr.ctx_lock); if (CAM_TFE_HW_NUM_MAX != CAM_TFE_CSID_HW_NUM_MAX) { CAM_ERR(CAM_ISP, "CSID num is different then TFE num"); Loading
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ * @dentry: Debugfs entry * @csid_debug: csid debug information * @enable_recovery: enable recovery * @enable_csid_recovery: enable csid recovery * @camif_debug: enable sensor diagnosis status * @enable_reg_dump: enable reg dump on error; * @per_req_reg_dump: Enable per request reg dump Loading @@ -37,6 +38,7 @@ struct cam_tfe_hw_mgr_debug { struct dentry *dentry; uint64_t csid_debug; uint32_t enable_recovery; uint32_t enable_csid_recovery; uint32_t camif_debug; uint32_t enable_reg_dump; uint32_t per_req_reg_dump; Loading Loading @@ -152,6 +154,7 @@ struct cam_tfe_hw_mgr_ctx { * @tfe_dev_caps tfe device capability per core * @work q work queue for TFE hw manager * @debug_cfg debug configuration * @ctx_lock Spinlock for HW manager */ struct cam_tfe_hw_mgr { struct cam_isp_hw_mgr mgr_common; Loading @@ -170,6 +173,7 @@ struct cam_tfe_hw_mgr { struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX]; struct cam_req_mgr_core_workq *workq; struct cam_tfe_hw_mgr_debug debug_cfg; spinlock_t ctx_lock; }; /** Loading