From 409a6016d4629f1067aa2b2933172bb178542a0e Mon Sep 17 00:00:00 2001 From: Wang Kan Date: Mon, 13 Mar 2023 15:24:48 +0800 Subject: [PATCH] msm: camera: isp: Get CDM callback done timestamp Get CDM callback done timestamp for LDAR to know if CDM write delay. And enlarge event monitor numbers to make sure dump 10+ frames info. CRs-Fixed: 3430787 Change-Id: If5a1bd925d5d82d1856d880ccb1f4ed9effc5251 Signed-off-by: Wang Kan --- drivers/cam_core/cam_context.h | 5 +- drivers/cam_isp/cam_isp_context.c | 51 ++++++++++++++++++- drivers/cam_isp/cam_isp_context.h | 3 +- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 3 ++ drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h | 3 +- .../isp_hw_mgr/include/cam_isp_hw_mgr_intf.h | 2 + drivers/cam_req_mgr/cam_req_mgr_core.h | 2 +- 7 files changed, 62 insertions(+), 7 deletions(-) diff --git a/drivers/cam_core/cam_context.h b/drivers/cam_core/cam_context.h index e97247aff8..7de919a465 100644 --- a/drivers/cam_core/cam_context.h +++ b/drivers/cam_core/cam_context.h @@ -1,7 +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. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_CONTEXT_H_ @@ -221,7 +221,7 @@ struct cam_ctx_ops { * @out_map_entries: Out map entry * @mini dump cb: Mini dump cb * @img_iommu_hdl: Image IOMMU handle - * + * @cdm_done_ts: CDM callback done timestamp */ struct cam_context { char dev_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; @@ -267,6 +267,7 @@ struct cam_context { struct cam_hw_fence_map_entry **out_map_entries; cam_ctx_mini_dump_cb_func mini_dump_cb; int img_iommu_hdl; + struct timespec64 cdm_done_ts; }; /** diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 917a630056..68d75da81d 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -463,6 +463,7 @@ static void __cam_isp_ctx_update_state_monitor_array( uint64_t req_id) { int iterator; + struct cam_context *ctx = ctx_isp->base; INC_HEAD(&ctx_isp->state_monitor_head, CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES, &iterator); @@ -475,7 +476,12 @@ static void __cam_isp_ctx_update_state_monitor_array( trigger_type; ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id = req_id; - ktime_get_clocktai_ts64(&ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp); + if (trigger_type == CAM_ISP_STATE_CHANGE_TRIGGER_CDM_DONE) + ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp = + ctx->cdm_done_ts; + else + ktime_get_clocktai_ts64( + &ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp); } static const char *__cam_isp_ctx_substate_val_to_type( @@ -517,6 +523,8 @@ static const char *__cam_isp_hw_evt_val_to_type( return "EPOCH"; case CAM_ISP_STATE_CHANGE_TRIGGER_EOF: return "EOF"; + case CAM_ISP_STATE_CHANGE_TRIGGER_CDM_DONE: + return "CDM_DONE"; case CAM_ISP_STATE_CHANGE_TRIGGER_DONE: return "DONE"; case CAM_ISP_STATE_CHANGE_TRIGGER_FLUSH: @@ -1250,6 +1258,35 @@ static int __cam_isp_ctx_get_hw_timestamp(struct cam_context *ctx, uint64_t *pre return 0; } +static int __cam_isp_ctx_get_cdm_done_timestamp(struct cam_context *ctx, + uint64_t *last_cdm_done_req) +{ + struct cam_hw_cmd_args hw_cmd_args; + struct cam_isp_hw_cmd_args isp_hw_cmd_args; + struct tm ts; + int rc; + + hw_cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map; + hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL; + hw_cmd_args.u.internal_args = &isp_hw_cmd_args; + + isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_GET_LAST_CDM_DONE; + rc = ctx->hw_mgr_intf->hw_cmd(ctx->ctxt_to_hw_map, &hw_cmd_args); + if (rc) + return rc; + + *last_cdm_done_req = isp_hw_cmd_args.u.last_cdm_done; + ctx->cdm_done_ts = isp_hw_cmd_args.cdm_done_ts; + time64_to_tm(isp_hw_cmd_args.cdm_done_ts.tv_sec, 0, &ts); + CAM_DBG(CAM_ISP, + "last_cdm_done req: %llu ctx: %u link: 0x%x time[%d-%d %d:%d:%d.%lld]", + last_cdm_done_req, ctx->ctx_id, ctx->link_hdl, + ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, + isp_hw_cmd_args.cdm_done_ts.tv_nsec / 1000000); + + return 0; +} + static int __cam_isp_ctx_recover_sof_timestamp(struct cam_context *ctx, uint64_t request_id) { struct cam_isp_context *ctx_isp = ctx->ctx_priv; @@ -2748,7 +2785,7 @@ static int __cam_isp_ctx_reg_upd_in_applied_state( goto end; } req = list_first_entry(&ctx->wait_req_list, - struct cam_ctx_request, list); + struct cam_ctx_request, list); list_del_init(&req->list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; @@ -2927,6 +2964,16 @@ static int __cam_isp_ctx_notify_eof_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; + struct cam_context *ctx = ctx_isp->base; + uint64_t last_cdm_done_req = 0; + + /* update last cdm done timestamp */ + rc = __cam_isp_ctx_get_cdm_done_timestamp(ctx, &last_cdm_done_req); + if (rc) + CAM_ERR(CAM_ISP, "ctx:%u link: 0x%x Failed to get timestamp from HW", + ctx->ctx_id, ctx->link_hdl); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_STATE_CHANGE_TRIGGER_CDM_DONE, last_cdm_done_req); /* notify reqmgr with eof signal */ rc = __cam_isp_ctx_notify_trigger_util(CAM_TRIGGER_POINT_EOF, ctx_isp); diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index 096b940d8b..6b5d095fc1 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -33,7 +33,7 @@ /* * Maximum entries in state monitoring array for error logging */ -#define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES 40 +#define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES 84 /* * Threshold response time in us beyond which a request is not expected @@ -113,6 +113,7 @@ enum cam_isp_state_change_trigger { CAM_ISP_STATE_CHANGE_TRIGGER_SEC_EVT_SOF, CAM_ISP_STATE_CHANGE_TRIGGER_SEC_EVT_EPOCH, CAM_ISP_STATE_CHANGE_TRIGGER_FRAME_DROP, + CAM_ISP_STATE_CHANGE_TRIGGER_CDM_DONE, CAM_ISP_STATE_CHANGE_TRIGGER_MAX }; 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 8a1cb9ff1c..589e3180b5 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 @@ -5026,6 +5026,7 @@ void cam_ife_cam_cdm_callback(uint32_t handle, void *userdata, "Called by CDM hdl=0x%x, udata=%pK, status=%d, cdm_req=%llu ctx_idx: %u", handle, userdata, status, ctx->cdm_userdata.request_id, ctx->ctx_index); } + ktime_get_clocktai_ts64(&ctx->cdm_done_ts); } static int cam_ife_mgr_acquire_get_unified_structure_v0( @@ -13008,6 +13009,8 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) CAM_ISP_PACKET_UPDATE_DEV; break; case CAM_ISP_HW_MGR_GET_LAST_CDM_DONE: + isp_hw_cmd_args->cdm_done_ts = + ctx->cdm_done_ts; isp_hw_cmd_args->u.last_cdm_done = ctx->last_cdm_done_req; break; diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h index 3f6be2dfa3..74d75f07a4 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h @@ -321,7 +321,7 @@ struct cam_isp_comp_record_query { * @try_recovery_cnt: Retry count for overflow recovery * @recovery_req_id: The request id on which overflow recovery happens * @drv_path_idle_en: Path idle enable value for DRV - * + * @cdm_done_ts: CDM callback done timestamp */ struct cam_ife_hw_mgr_ctx { struct list_head list; @@ -385,6 +385,7 @@ struct cam_ife_hw_mgr_ctx { uint32_t drv_path_idle_en; struct cam_isp_context_comp_record *vfe_bus_comp_grp; struct cam_isp_context_comp_record *sfe_bus_comp_grp; + struct timespec64 cdm_done_ts; }; /** 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 da0ba1ed7d..ea83cf619e 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 @@ -395,6 +395,7 @@ enum cam_isp_ctx_type { * @packet_op_code: Packet opcode * @last_cdm_done: Last cdm done request * @sof_ts: SOF timestamps (current, boot and previous) + * @cdm_done_ts: CDM callback done timestamp */ struct cam_isp_hw_cmd_args { uint32_t cmd_type; @@ -410,6 +411,7 @@ struct cam_isp_hw_cmd_args { uint64_t boot; } sof_ts; } u; + struct timespec64 cdm_done_ts; }; /** diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.h b/drivers/cam_req_mgr/cam_req_mgr_core.h index c68bc3ed66..d171ce2daf 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/cam_req_mgr/cam_req_mgr_core.h @@ -14,7 +14,7 @@ #define CAM_REQ_MGR_MAX_LINKED_DEV 16 #define MAX_REQ_SLOTS 48 -#define MAX_REQ_STATE_MONITOR_NUM 40 +#define MAX_REQ_STATE_MONITOR_NUM 108 #define CAM_REQ_MGR_WATCHDOG_TIMEOUT 1000 #define CAM_REQ_MGR_WATCHDOG_TIMEOUT_DEFAULT 5000