From 69c67ebc90fbe9d712ac1bee8432f5b20175b6ac Mon Sep 17 00:00:00 2001 From: Alok Pandey Date: Thu, 31 Oct 2019 09:50:07 +0530 Subject: [PATCH] msm: camera: ife: calculate accurate boot timestamp at CSID SOF The boot timestamp is calculated in tasklet context. Due to system performance and scheduling delay, it may vary. It is somtimes causing failure for few time bound test cases. To handle above problem, This change also considers qtime difference to calculate accurate boot time at CSID each SOF. CRs-Fixed: 2557758 Change-Id: I36b21a0f2c12cc1c83c209ab01ea90c0ac226995 Signed-off-by: Alok Pandey --- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 63 ++++++++++--------- .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 22 ++++++- .../isp_hw/ife_csid_hw/cam_ife_csid_core.h | 4 ++ 3 files changed, 55 insertions(+), 34 deletions(-) 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 41d02f06aaf0..998dfd743087 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 @@ -5888,41 +5888,42 @@ static int cam_ife_mgr_cmd_get_sof_timestamp( struct cam_hw_intf *hw_intf; struct cam_csid_get_time_stamp_args csid_get_time; - list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) { - for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { - if (!hw_mgr_res->hw_res[i]) - continue; + hw_mgr_res = list_first_entry(&ife_ctx->res_list_ife_csid, + struct cam_ife_hw_mgr_res, list); + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + /* + * Get the SOF time stamp from left resource only. + * Left resource is master for dual vfe case and + * Rdi only context case left resource only hold + * the RDI resource + */ + + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_ops.process_cmd) { /* - * Get the SOF time stamp from left resource only. - * Left resource is master for dual vfe case and - * Rdi only context case left resource only hold - * the RDI resource + * Single VFE case, Get the time stamp from + * available one csid hw in the context + * Dual VFE case, get the time stamp from + * master(left) would be sufficient */ - hw_intf = hw_mgr_res->hw_res[i]->hw_intf; - if (hw_intf->hw_ops.process_cmd) { - /* - * Single VFE case, Get the time stamp from - * available one csid hw in the context - * Dual VFE case, get the time stamp from - * master(left) would be sufficient - */ - - csid_get_time.node_res = - hw_mgr_res->hw_res[i]; - rc = hw_intf->hw_ops.process_cmd( - hw_intf->hw_priv, - CAM_IFE_CSID_CMD_GET_TIME_STAMP, - &csid_get_time, - sizeof( - struct cam_csid_get_time_stamp_args)); - if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) { - *time_stamp = - csid_get_time.time_stamp_val; - *boot_time_stamp = - csid_get_time.boot_timestamp; - } + csid_get_time.node_res = + hw_mgr_res->hw_res[i]; + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_CMD_GET_TIME_STAMP, + &csid_get_time, + sizeof( + struct cam_csid_get_time_stamp_args)); + if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) { + *time_stamp = + csid_get_time.time_stamp_val; + *boot_time_stamp = + csid_get_time.boot_timestamp; } } } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index af9f67286d82..f21c47e5f56d 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -534,6 +534,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d", csid_hw->hw_intf->hw_idx, val); csid_hw->error_irq_count = 0; + csid_hw->prev_boot_timestamp = 0; return rc; } @@ -1329,6 +1330,7 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) spin_unlock_irqrestore(&csid_hw->lock_state, flags); csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->error_irq_count = 0; + csid_hw->prev_boot_timestamp = 0; return rc; } @@ -2928,6 +2930,7 @@ static int cam_ife_csid_get_time_stamp( const struct cam_ife_csid_udi_reg_offset *udi_reg; struct timespec64 ts; uint32_t time_32, id; + uint64_t time_delta; time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args; res = time_stamp->node_res; @@ -2999,9 +3002,22 @@ static int cam_ife_csid_get_time_stamp( CAM_IFE_CSID_QTIMER_MUL_FACTOR, CAM_IFE_CSID_QTIMER_DIV_FACTOR); - get_monotonic_boottime64(&ts); - time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) + - ts.tv_nsec); + if (!csid_hw->prev_boot_timestamp) { + get_monotonic_boottime64(&ts); + time_stamp->boot_timestamp = + (uint64_t)((ts.tv_sec * 1000000000) + + ts.tv_nsec); + csid_hw->prev_qtimer_ts = 0; + CAM_DBG(CAM_ISP, "timestamp:%lld", + time_stamp->boot_timestamp); + } else { + time_delta = time_stamp->time_stamp_val - + csid_hw->prev_qtimer_ts; + time_stamp->boot_timestamp = + csid_hw->prev_boot_timestamp + time_delta; + } + csid_hw->prev_qtimer_ts = time_stamp->time_stamp_val; + csid_hw->prev_boot_timestamp = time_stamp->boot_timestamp; return 0; } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index 7bfb0dac4231..863aec341899 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -550,6 +550,8 @@ struct cam_ife_csid_path_cfg { * @binning_enable Flag is set if hardware supports QCFA binning * @binning_supported Flag is set if sensor supports QCFA binning * + * @first_sof_ts first bootime stamp at the start + * @prev_qtimer_ts stores csid timestamp */ struct cam_ife_csid_hw { struct cam_hw_intf *hw_intf; @@ -581,6 +583,8 @@ struct cam_ife_csid_hw { spinlock_t lock_state; uint32_t binning_enable; uint32_t binning_supported; + uint64_t prev_boot_timestamp; + uint64_t prev_qtimer_ts; }; int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,