From a4a349c82fa78de4e09643b594e32114c655d3b9 Mon Sep 17 00:00:00 2001 From: Alok Pandey Date: Thu, 1 Apr 2021 15:17:18 +0530 Subject: [PATCH] msm: camera: req_mgr: Sending event_cause for frame error for shima When camnoc fill level for RDI port goes beyond 25%, notify UMD with BAD frames to take corrective actions. CRs-Fixed: 2913934 Change-Id: I5427ce94cdd2a48d8647ff4593cb1605a2f90a37 Signed-off-by: Alok Pandey --- drivers/cam_isp/cam_isp_context.c | 65 ++++++++++++----- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 1 + .../isp_hw_mgr/include/cam_isp_hw_mgr_intf.h | 5 +- .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 3 +- .../isp_hw/include/cam_vfe_hw_intf.h | 5 +- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c | 72 ++++++++++++++++--- .../vfe_hw/vfe_top/cam_vfe_camif_ver3.c | 21 +++++- include/uapi/camera/media/cam_sync.h | 1 + 8 files changed, 139 insertions(+), 34 deletions(-) diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index d4ba000210aa..6915cf20bc3d 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -899,8 +899,9 @@ static int __cam_isp_ctx_handle_buf_done_for_request( req_isp = (struct cam_isp_ctx_req *) req->req_priv; - CAM_DBG(CAM_ISP, "Enter with bubble_state %d, req_bubble_detected %d", - bubble_state, req_isp->bubble_detected); + CAM_DBG(CAM_ISP, + "Enter with bubble_state %d, req_bubble_detected %d evt_param = %d", + bubble_state, req_isp->bubble_detected, done->evt_param); done_next_req->num_handles = 0; done_next_req->timestamp = done->timestamp; @@ -956,18 +957,31 @@ static int __cam_isp_ctx_handle_buf_done_for_request( if (!req_isp->bubble_detected) { CAM_DBG(CAM_ISP, - "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", + "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u, Bad_frame %u", req->request_id, req_isp->fence_map_out[j].resource_handle, req_isp->fence_map_out[j].sync_id, - ctx->ctx_id); + ctx->ctx_id, done->evt_param); - rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, - CAM_SYNC_STATE_SIGNALED_SUCCESS, - CAM_SYNC_COMMON_EVENT_SUCCESS); + if (done->evt_param == 1) { + + CAM_WARN(CAM_ISP, + "Bad frame Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", + req->request_id, + req_isp->fence_map_out[j].resource_handle, + req_isp->fence_map_out[j].sync_id, + ctx->ctx_id); + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_ISP_EVENT_BAD_FRAME); + } else { + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + } if (rc) CAM_DBG(CAM_ISP, "Sync failed with rc = %d", - rc); + rc); } else if (!req_isp->bubble_report) { CAM_DBG(CAM_ISP, "Sync with failure: req %lld res 0x%x fd 0x%x, ctx %u", @@ -1104,13 +1118,15 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr( struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; const char *handle_type; + uint32_t event_cause = CAM_SYNC_COMMON_EVENT_SUCCESS; trace_cam_buf_done("ISP", ctx, req); req_isp = (struct cam_isp_ctx_req *) req->req_priv; - CAM_DBG(CAM_ISP, "Enter with bubble_state %d, req_bubble_detected %d", - bubble_state, req_isp->bubble_detected); + CAM_DBG(CAM_ISP, + "Enter with bubble_state %d, req_bubble_detected %d evt_param %d", + bubble_state, req_isp->bubble_detected, done->evt_param); for (i = 0; i < done->num_handles; i++) { for (j = 0; j < req_isp->num_fence_map_out; j++) { @@ -1185,24 +1201,37 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr( continue; } else if (!req_isp->bubble_detected) { CAM_DBG(CAM_ISP, - "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", + "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u isBadFrame %u", req->request_id, req_isp->fence_map_out[j].resource_handle, req_isp->fence_map_out[j].sync_id, - ctx->ctx_id); - - rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, - CAM_SYNC_STATE_SIGNALED_SUCCESS, - CAM_SYNC_COMMON_EVENT_SUCCESS); + ctx->ctx_id, done->evt_param); + if (done->evt_param == 1) { + CAM_WARN(CAM_ISP, + "Bad Frame Sync with success: req %lld res 0x%x fd 0x%x, ctx %u", + req->request_id, + req_isp->fence_map_out[j].resource_handle, + req_isp->fence_map_out[j].sync_id, + ctx->ctx_id); + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_ISP_EVENT_BAD_FRAME); + event_cause = CAM_SYNC_ISP_EVENT_BAD_FRAME; + } else { + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + event_cause = CAM_SYNC_COMMON_EVENT_SUCCESS; + } if (rc) { CAM_DBG(CAM_ISP, "Sync failed with rc = %d", - rc); + rc); } else if (req_isp->num_deferred_acks) { /* Process deferred buf_done acks */ __cam_isp_handle_deferred_buf_done(ctx_isp, req, false, CAM_SYNC_STATE_SIGNALED_SUCCESS, - CAM_SYNC_COMMON_EVENT_SUCCESS); + event_cause); } } else if (!req_isp->bubble_report) { CAM_DBG(CAM_ISP, diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index f0ea6fe8fb24..487f1eda3457 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -8022,6 +8022,7 @@ static int cam_ife_hw_mgr_handle_hw_buf_done( buf_done_event_data.resource_handle[0] = event_info->res_id; buf_done_event_data.last_consumed_addr[0] = event_info->reg_val; + buf_done_event_data.evt_param = event_info->evt_param; if (atomic_read(&ife_hw_mgr_ctx->overflow_pending)) return 0; diff --git a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h index d3f748e93c04..b04c3448b6b5 100644 --- a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h @@ -194,7 +194,7 @@ struct cam_isp_hw_epoch_event_data { * @resource_handle: Resource handle array * @last_consumed_addr: Last consumed addr * @timestamp: Timestamp for the buf done event - * + * @evt_param: Specific info about the frame */ struct cam_isp_hw_done_event_data { uint32_t num_handles; @@ -202,7 +202,8 @@ struct cam_isp_hw_done_event_data { CAM_NUM_OUT_PER_COMP_IRQ_MAX]; uint32_t last_consumed_addr[ CAM_NUM_OUT_PER_COMP_IRQ_MAX]; - uint64_t timestamp; + uint64_t timestamp; + uint32_t evt_param; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index ad5d25abe7fc..6638b9269a58 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -216,7 +216,7 @@ struct cam_isp_blanking_config { * @hw_idx: IFE hw index * @err_type: Error type if any * @reg_val: Any critical register value captured during irq handling - * + * @evt_param Specific info about frame */ struct cam_isp_hw_event_info { enum cam_isp_resource_type res_type; @@ -224,6 +224,7 @@ struct cam_isp_hw_event_info { uint32_t hw_idx; uint32_t err_type; uint32_t reg_val; + uint32_t evt_param; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h index 6c3213aec6c7..b2357032e704 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef _CAM_VFE_HW_INTF_H_ @@ -14,6 +14,7 @@ #define CAM_VFE_HW_NUM_MAX 7 #define VFE_CORE_BASE_IDX 0 +#define CAMNOC_CORE_BASE_IDX 1 #define RT_BASE_IDX 2 /* * VBIF and BUS do not exist on same HW. @@ -320,6 +321,7 @@ struct cam_vfe_top_irq_evt_payload { * handled * @error_type: Identify different errors * @ts: Timestamp + * @evt_param Specific info about frame */ struct cam_vfe_bus_irq_evt_payload { struct list_head list; @@ -331,6 +333,7 @@ struct cam_vfe_bus_irq_evt_payload { uint32_t evt_id; uint32_t irq_reg_val[CAM_IFE_BUS_IRQ_REGISTERS_MAX]; struct cam_isp_timestamp ts; + uint32_t evt_param; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c index 957539d28dfc..b11a9e285ff7 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ @@ -76,6 +76,9 @@ struct cam_vfe_bus_error_info { struct cam_vfe_bus_ver3_common_data { uint32_t core_index; void __iomem *mem_base; + void __iomem *camnoc_mem_base; + uint32_t cpas_version; + struct cam_hw_soc_info *soc_info; struct cam_hw_intf *hw_intf; void *bus_irq_controller; void *rup_irq_controller; @@ -950,6 +953,7 @@ static int cam_vfe_bus_ver3_handle_rup_bottom_half(void *handler_priv, evt_info.hw_idx = rsrc_data->common_data->core_index; evt_info.res_type = CAM_ISP_RESOURCE_VFE_IN; + evt_info.evt_param = payload->evt_param; if (!rsrc_data->common_data->is_lite) { if (irq_status & 0x1) { @@ -2309,13 +2313,17 @@ static int cam_vfe_bus_ver3_stop_vfe_out( static int cam_vfe_bus_ver3_handle_vfe_out_done_top_half(uint32_t evt_id, struct cam_irq_th_payload *th_payload) { - int32_t rc; - int i; - struct cam_isp_resource_node *vfe_out = NULL; - struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = NULL; - struct cam_vfe_bus_irq_evt_payload *evt_payload; - struct cam_vfe_bus_ver3_comp_grp_data *resource_data; - uint32_t status_0; + int32_t rc; + int i; + struct cam_isp_resource_node *vfe_out = NULL; + struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = NULL; + struct cam_vfe_bus_irq_evt_payload *evt_payload; + struct cam_vfe_bus_ver3_comp_grp_data *resource_data; + uint32_t status_0; + struct cam_vfe_bus_ver3_priv *bus_priv; + void __iomem *camnoc_mem_base = NULL; + uint32_t val0 = 0, val1 = 0, val2 = 0; + uint32_t comp_mask = 0; vfe_out = th_payload->handler_priv; if (!vfe_out) { @@ -2326,14 +2334,15 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_top_half(uint32_t evt_id, rsrc_data = vfe_out->res_priv; resource_data = rsrc_data->comp_grp->res_priv; + bus_priv = rsrc_data->bus_priv; + camnoc_mem_base = bus_priv->common_data.camnoc_mem_base; + CAM_DBG(CAM_ISP, "VFE:%d Bus IRQ status_0: 0x%X status_1: 0x%X", rsrc_data->common_data->core_index, th_payload->evt_status_arr[0], th_payload->evt_status_arr[1]); - rc = cam_vfe_bus_ver3_get_evt_payload(rsrc_data->common_data, &evt_payload); - if (rc) { CAM_INFO_RATE_LIMIT(CAM_ISP, "VFE:%d Bus IRQ status_0: 0x%X status_1: 0x%X", @@ -2347,10 +2356,47 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_top_half(uint32_t evt_id, evt_payload->core_index = rsrc_data->common_data->core_index; evt_payload->evt_id = evt_id; + evt_payload->evt_param = 0; for (i = 0; i < th_payload->num_registers; i++) evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i]; + if (bus_priv->common_data.cpas_version == CAM_CPAS_TITAN_570_V200) { + rc = cam_vfe_bus_ver3_handle_comp_done_bottom_half( + rsrc_data->comp_grp, evt_payload, &comp_mask); + + if ((comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI0)) || + (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI1)) || + (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI2)) || + (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI3))) { + + /* Read Fill Level */ + val0 = cam_io_r_mb(camnoc_mem_base + 0xA20); + val1 = cam_io_r_mb(camnoc_mem_base + 0x1420); + val2 = cam_io_r_mb(camnoc_mem_base + 0x1A20); + CAM_DBG(CAM_ISP, + "comp_mask %d: CAMNOC REG[Queued Pending] ife_niu_1[%d %d] ife_niu_3[%d %d] ife_niu_0[%d %d]", + comp_mask, + (val0 & 0x7FF), (val0 & 0x7F0000) >> 16, + (val1 & 0x7FF), (val1 & 0x7F0000) >> 16, + (val2 & 0x7FF), (val2 & 0x7F0000) >> 16); + + if ((val1 & 0x7FF) > 205) { + CAM_ERR(CAM_ISP, "VFE:%d, Potential Error!!!", + rsrc_data->common_data->core_index); + CAM_INFO(CAM_ISP, + "comp_mask %d: CAMNOC REG[Queued Pending] ife_niu_1[%d %d] ife_niu_3[%d %d] ife_niu_0[%d %d]", + comp_mask, + (val0 & 0x7FF), (val0 & 0x7F0000) >> 16, + (val1 & 0x7FF), (val1 & 0x7F0000) >> 16, + (val2 & 0x7FF), (val2 & 0x7F0000) >> 16); + + evt_payload->evt_param = 1; + } + + } + } + th_payload->evt_payload_priv = evt_payload; status_0 = th_payload->evt_status_arr[CAM_IFE_IRQ_BUS_VER3_REG_STATUS0]; @@ -2412,7 +2458,7 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half( struct cam_isp_hw_event_info evt_info; void *ctx = NULL; uint32_t evt_id = 0, comp_mask = 0; - uint32_t out_list[CAM_VFE_BUS_VER3_VFE_OUT_MAX]; + uint32_t out_list[CAM_VFE_BUS_VER3_VFE_OUT_MAX]; rc = cam_vfe_bus_ver3_handle_comp_done_bottom_half( rsrc_data->comp_grp, evt_payload_priv, &comp_mask); @@ -2429,6 +2475,7 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half( evt_info.res_type = vfe_out->res_type; evt_info.hw_idx = vfe_out->hw_intf->hw_idx; + evt_info.evt_param = evt_payload->evt_param; rc = cam_vfe_bus_ver3_get_comp_vfe_out_res_id_list( comp_mask, out_list, &num_out); @@ -3790,6 +3837,9 @@ int cam_vfe_bus_ver3_init( bus_priv->common_data.core_index = soc_info->index; bus_priv->common_data.mem_base = CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX); + bus_priv->common_data.camnoc_mem_base = + CAM_SOC_GET_REG_MAP_START(soc_info, CAMNOC_CORE_BASE_IDX); + bus_priv->common_data.cpas_version = soc_private->cpas_version; bus_priv->common_data.hw_intf = hw_intf; bus_priv->common_data.vfe_irq_controller = vfe_irq_controller; bus_priv->common_data.common_reg = &ver3_hw_info->common_reg; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c index 72f108d9621a..3529babc8823 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ #include @@ -1323,10 +1323,18 @@ static int cam_vfe_camif_ver3_handle_irq_top_half(uint32_t evt_id, struct cam_isp_resource_node *camif_node; struct cam_vfe_mux_camif_ver3_data *camif_priv; struct cam_vfe_top_irq_evt_payload *evt_payload; + struct cam_hw_soc_info *soc_info = NULL; + void __iomem *camnoc_mem_base = NULL; + struct cam_vfe_soc_private *soc_private = NULL; camif_node = th_payload->handler_priv; camif_priv = camif_node->res_priv; + soc_info = camif_priv->soc_info; + camnoc_mem_base = CAM_SOC_GET_REG_MAP_START(soc_info, 1); + soc_private = + (struct cam_vfe_soc_private *)soc_info->soc_private; + CAM_DBG(CAM_ISP, "VFE:%d CAMIF IRQ status_0: 0x%X status_1: 0x%X status_2: 0x%X", camif_node->hw_intf->hw_idx, th_payload->evt_status_arr[0], @@ -1364,6 +1372,17 @@ static int cam_vfe_camif_ver3_handle_irq_top_half(uint32_t evt_id, trace_cam_log_event("SOF", "TOP_HALF", th_payload->evt_status_arr[CAM_IFE_IRQ_CAMIF_REG_STATUS1], camif_node->hw_intf->hw_idx); + + switch (soc_private->cpas_version) { + case CAM_CPAS_TITAN_570_V200: + /* Reset Fill levels */ + cam_io_w_mb(0x1, camnoc_mem_base + 0x1A28); + cam_io_w_mb(0x1, camnoc_mem_base + 0xA28); + cam_io_w_mb(0x1, camnoc_mem_base + 0x1428); + break; + default: + break; + } } if (th_payload->evt_status_arr[CAM_IFE_IRQ_CAMIF_REG_STATUS1] diff --git a/include/uapi/camera/media/cam_sync.h b/include/uapi/camera/media/cam_sync.h index 9131afcacbb2..13b2e795c710 100644 --- a/include/uapi/camera/media/cam_sync.h +++ b/include/uapi/camera/media/cam_sync.h @@ -66,6 +66,7 @@ #define CAM_SYNC_ISP_EVENT_BUSIF_OVERFLOW (CAM_SYNC_ISP_EVENT_START + 5) #define CAM_SYNC_ISP_EVENT_FLUSH (CAM_SYNC_ISP_EVENT_START + 6) #define CAM_SYNC_ISP_EVENT_HW_STOP (CAM_SYNC_ISP_EVENT_START + 7) +#define CAM_SYNC_ISP_EVENT_BAD_FRAME (CAM_SYNC_ISP_EVENT_START + 8) #define CAM_SYNC_ISP_EVENT_END (CAM_SYNC_ISP_EVENT_START + 50) /* ICP Sync event reason types */