|
@@ -42,10 +42,20 @@
|
|
#define CAM_ISP_GENERIC_BLOB_TYPE_MAX \
|
|
#define CAM_ISP_GENERIC_BLOB_TYPE_MAX \
|
|
(CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG + 1)
|
|
(CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG + 1)
|
|
|
|
|
|
-#define MAX_RETRY_ATTEMPTS 1
|
|
|
|
|
|
+#define MAX_INTERNAL_RECOVERY_ATTEMPTS 1
|
|
|
|
|
|
-#define CAM_ISP_CSID_ERROR_CAN_RECOVERY \
|
|
|
|
- CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW
|
|
|
|
|
|
+#define CAM_ISP_NON_RECOVERABLE_CSID_ERRORS \
|
|
|
|
+ (CAM_ISP_HW_ERROR_CSID_LANE_FIFO_OVERFLOW | \
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_PKT_HDR_CORRUPTED | \
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_MISSING_PKT_HDR_DATA | \
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_FATAL | \
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_UNBOUNDED_FRAME | \
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_MISSING_EOT | \
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_PKT_PAYLOAD_CORRUPTED)
|
|
|
|
+
|
|
|
|
+#define CAM_ISP_RECOVERABLE_CSID_ERRORS \
|
|
|
|
+ (CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR | \
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_SENSOR_FRAME_DROP)
|
|
|
|
|
|
static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = {
|
|
static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = {
|
|
CAM_ISP_HW_CMD_GET_HFR_UPDATE,
|
|
CAM_ISP_HW_CMD_GET_HFR_UPDATE,
|
|
@@ -12892,24 +12902,25 @@ end:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int cam_ife_hw_mgr_handle_csid_frame_drop(
|
|
|
|
|
|
+static int cam_ife_hw_mgr_handle_csid_secondary_err_evts(
|
|
|
|
+ uint32_t err_type,
|
|
struct cam_isp_hw_event_info *event_info,
|
|
struct cam_isp_hw_event_info *event_info,
|
|
struct cam_ife_hw_mgr_ctx *ctx)
|
|
struct cam_ife_hw_mgr_ctx *ctx)
|
|
{
|
|
{
|
|
- int rc = 0;
|
|
|
|
|
|
+ int rc = -EINVAL;
|
|
|
|
+ struct cam_isp_hw_secondary_event_data sec_evt_data = {0};
|
|
cam_hw_event_cb_func ife_hw_irq_cb = ctx->common.event_cb;
|
|
cam_hw_event_cb_func ife_hw_irq_cb = ctx->common.event_cb;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Support frame drop as secondary event
|
|
* Support frame drop as secondary event
|
|
*/
|
|
*/
|
|
- if (event_info->is_secondary_evt) {
|
|
|
|
- struct cam_isp_hw_secondary_event_data sec_evt_data;
|
|
|
|
|
|
+ if (err_type & CAM_ISP_HW_ERROR_CSID_SENSOR_FRAME_DROP) {
|
|
|
|
+ sec_evt_data.evt_type = CAM_ISP_HW_SEC_EVENT_OUT_OF_SYNC_FRAME_DROP;
|
|
|
|
|
|
CAM_DBG(CAM_ISP,
|
|
CAM_DBG(CAM_ISP,
|
|
- "Received CSID[%u] sensor sync frame drop res: %d as secondary evt",
|
|
|
|
- event_info->hw_idx, event_info->res_id);
|
|
|
|
|
|
+ "Received CSID[%u] sensor sync frame drop res: %d as secondary evt on ctx: %u",
|
|
|
|
+ event_info->hw_idx, event_info->res_id, ctx->ctx_index);
|
|
|
|
|
|
- sec_evt_data.evt_type = CAM_ISP_HW_SEC_EVENT_OUT_OF_SYNC_FRAME_DROP;
|
|
|
|
rc = ife_hw_irq_cb(ctx->common.cb_priv,
|
|
rc = ife_hw_irq_cb(ctx->common.cb_priv,
|
|
CAM_ISP_HW_SECONDARY_EVENT, (void *)&sec_evt_data);
|
|
CAM_ISP_HW_SECONDARY_EVENT, (void *)&sec_evt_data);
|
|
}
|
|
}
|
|
@@ -12922,6 +12933,7 @@ static int cam_ife_hw_mgr_handle_csid_error(
|
|
struct cam_isp_hw_event_info *event_info)
|
|
struct cam_isp_hw_event_info *event_info)
|
|
{
|
|
{
|
|
int rc = -EINVAL;
|
|
int rc = -EINVAL;
|
|
|
|
+ bool recoverable = true;
|
|
uint32_t err_type;
|
|
uint32_t err_type;
|
|
struct cam_isp_hw_error_event_info *err_evt_info;
|
|
struct cam_isp_hw_error_event_info *err_evt_info;
|
|
struct cam_isp_hw_error_event_data error_event_data = {0};
|
|
struct cam_isp_hw_error_event_data error_event_data = {0};
|
|
@@ -12940,72 +12952,68 @@ static int cam_ife_hw_mgr_handle_csid_error(
|
|
CAM_DBG(CAM_ISP, "Entry CSID[%u] error %d", event_info->hw_idx, err_type);
|
|
CAM_DBG(CAM_ISP, "Entry CSID[%u] error %d", event_info->hw_idx, err_type);
|
|
|
|
|
|
spin_lock(&g_ife_hw_mgr.ctx_lock);
|
|
spin_lock(&g_ife_hw_mgr.ctx_lock);
|
|
- if (err_type & CAM_ISP_HW_ERROR_CSID_SENSOR_FRAME_DROP)
|
|
|
|
- cam_ife_hw_mgr_handle_csid_frame_drop(event_info, ctx);
|
|
|
|
|
|
|
|
|
|
+ /* Secondary event handling */
|
|
|
|
+ if (event_info->is_secondary_evt) {
|
|
|
|
+ rc = cam_ife_hw_mgr_handle_csid_secondary_err_evts(err_type, event_info, ctx);
|
|
|
|
+ if (rc)
|
|
|
|
+ CAM_ERR(CAM_ISP,
|
|
|
|
+ "Failed to handle CSID[%u] sec event for res: %d err: 0x%x on ctx: %u",
|
|
|
|
+ event_info->hw_idx, event_info->res_id, err_type, ctx->ctx_index);
|
|
|
|
+ spin_unlock(&g_ife_hw_mgr.ctx_lock);
|
|
|
|
+ return rc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Default error types */
|
|
recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
|
|
recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
|
|
|
|
+ error_event_data.error_type = CAM_ISP_HW_ERROR_CSID_FATAL;
|
|
|
|
|
|
- if ((err_type & (CAM_ISP_HW_ERROR_CSID_LANE_FIFO_OVERFLOW |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_PKT_HDR_CORRUPTED |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_MISSING_PKT_HDR_DATA |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_FATAL |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_UNBOUNDED_FRAME |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_MISSING_EOT |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_PKT_PAYLOAD_CORRUPTED)) &&
|
|
|
|
- g_ife_hw_mgr.debug_cfg.enable_csid_recovery) {
|
|
|
|
|
|
+ /* Notify IFE/SFE devices, determine bus overflow */
|
|
|
|
+ if (err_type & (CAM_ISP_HW_ERROR_CSID_OUTPUT_FIFO_OVERFLOW |
|
|
|
|
+ CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW |
|
|
|
|
+ CAM_ISP_HW_ERROR_CSID_FRAME_SIZE))
|
|
|
|
+ cam_ife_hw_mgr_check_and_notify_overflow(event_info,
|
|
|
|
+ ctx, &is_bus_overflow);
|
|
|
|
|
|
|
|
+ if (err_type & CAM_ISP_NON_RECOVERABLE_CSID_ERRORS) {
|
|
error_event_data.error_type |= err_type;
|
|
error_event_data.error_type |= err_type;
|
|
recovery_data.error_type = err_type;
|
|
recovery_data.error_type = err_type;
|
|
- rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
|
|
|
|
- event_info->hw_idx, &recovery_data);
|
|
|
|
- goto end;
|
|
|
|
|
|
+ recoverable = false;
|
|
}
|
|
}
|
|
|
|
|
|
- if (err_type & (CAM_ISP_HW_ERROR_CSID_OUTPUT_FIFO_OVERFLOW |
|
|
|
|
- CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW |
|
|
|
|
- CAM_ISP_HW_ERROR_CSID_FRAME_SIZE)) {
|
|
|
|
|
|
+ if (recoverable && (is_bus_overflow ||
|
|
|
|
+ (err_type & CAM_ISP_RECOVERABLE_CSID_ERRORS))) {
|
|
|
|
+ if (ctx->try_recovery_cnt < MAX_INTERNAL_RECOVERY_ATTEMPTS) {
|
|
|
|
+ error_event_data.try_internal_recovery = true;
|
|
|
|
|
|
- cam_ife_hw_mgr_check_and_notify_overflow(event_info,
|
|
|
|
- ctx, &is_bus_overflow);
|
|
|
|
|
|
+ if (!atomic_read(&ctx->overflow_pending))
|
|
|
|
+ ctx->try_recovery_cnt++;
|
|
|
|
|
|
- /*
|
|
|
|
- * When CSID overflow IRQ comes, we need read bus overflow
|
|
|
|
- * status, to check if it's a bus overflow issue,
|
|
|
|
- * only do recovery in bus overflow cases.
|
|
|
|
- */
|
|
|
|
- if ((err_type & CAM_ISP_CSID_ERROR_CAN_RECOVERY) &&
|
|
|
|
- is_bus_overflow) {
|
|
|
|
- if (ctx->try_recovery_cnt < MAX_RETRY_ATTEMPTS) {
|
|
|
|
- error_event_data.try_internal_recovery = true;
|
|
|
|
- if (!atomic_read(&ctx->overflow_pending))
|
|
|
|
- ctx->try_recovery_cnt++;
|
|
|
|
- if (!ctx->recovery_req_id)
|
|
|
|
- ctx->recovery_req_id = ctx->applied_req_id;
|
|
|
|
- }
|
|
|
|
- CAM_DBG(CAM_ISP, "CSID[%u] Try recovery count %u on req %llu",
|
|
|
|
- event_info->hw_idx,
|
|
|
|
- ctx->try_recovery_cnt,
|
|
|
|
- ctx->recovery_req_id);
|
|
|
|
|
|
+ if (!ctx->recovery_req_id)
|
|
|
|
+ ctx->recovery_req_id = ctx->applied_req_id;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ CAM_DBG(CAM_ISP,
|
|
|
|
+ "CSID[%u] error: %u current_recovery_cnt: %u recovery_req: %llu on ctx: %u",
|
|
|
|
+ event_info->hw_idx, err_type, ctx->try_recovery_cnt,
|
|
|
|
+ ctx->recovery_req_id, ctx->ctx_index);
|
|
|
|
+
|
|
error_event_data.error_type |= err_type;
|
|
error_event_data.error_type |= err_type;
|
|
recovery_data.error_type = err_type;
|
|
recovery_data.error_type = err_type;
|
|
- rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
|
|
|
|
- event_info->hw_idx, &recovery_data);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-end:
|
|
|
|
-
|
|
|
|
|
|
+ rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
|
|
|
|
+ event_info->hw_idx, &recovery_data);
|
|
if (rc || !recovery_data.no_of_context)
|
|
if (rc || !recovery_data.no_of_context)
|
|
- goto skip_recovery;
|
|
|
|
|
|
+ goto end;
|
|
|
|
|
|
if (!error_event_data.try_internal_recovery)
|
|
if (!error_event_data.try_internal_recovery)
|
|
cam_ife_hw_mgr_do_error_recovery(&recovery_data);
|
|
cam_ife_hw_mgr_do_error_recovery(&recovery_data);
|
|
- CAM_DBG(CAM_ISP, "Exit CSID[%u] error %d", event_info->hw_idx,
|
|
|
|
- err_type);
|
|
|
|
|
|
|
|
-skip_recovery:
|
|
|
|
|
|
+ CAM_DBG(CAM_ISP, "Exit CSID[%u] error %d",
|
|
|
|
+ event_info->hw_idx, err_type);
|
|
|
|
+
|
|
|
|
+end:
|
|
spin_unlock(&g_ife_hw_mgr.ctx_lock);
|
|
spin_unlock(&g_ife_hw_mgr.ctx_lock);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|