Selaa lähdekoodia

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 <[email protected]>
Wang Kan 2 vuotta sitten
vanhempi
sitoutus
409a6016d4

+ 3 - 2
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;
 };
 
 /**

+ 49 - 2
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);

+ 2 - 1
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
 };
 

+ 3 - 0
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;

+ 2 - 1
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;
 };
 
 /**

+ 2 - 0
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;
 };
 
 /**

+ 1 - 1
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