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 <akumarpa@codeaurora.org>
This commit is contained in:
Alok Pandey 2019-10-31 09:50:07 +05:30 коммит произвёл Gerrit - the friendly Code Review server
Родитель 22c15f22e1
Коммит 69c67ebc90
3 изменённых файлов: 55 добавлений и 34 удалений

Просмотреть файл

@ -5888,41 +5888,42 @@ static int cam_ife_mgr_cmd_get_sof_timestamp(
struct cam_hw_intf *hw_intf; struct cam_hw_intf *hw_intf;
struct cam_csid_get_time_stamp_args csid_get_time; struct cam_csid_get_time_stamp_args csid_get_time;
list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) { hw_mgr_res = list_first_entry(&ife_ctx->res_list_ife_csid,
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { struct cam_ife_hw_mgr_res, list);
if (!hw_mgr_res->hw_res[i])
continue;
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. * Single VFE case, Get the time stamp from
* Left resource is master for dual vfe case and * available one csid hw in the context
* Rdi only context case left resource only hold * Dual VFE case, get the time stamp from
* the RDI resource * master(left) would be sufficient
*/ */
hw_intf = hw_mgr_res->hw_res[i]->hw_intf; csid_get_time.node_res =
if (hw_intf->hw_ops.process_cmd) { hw_mgr_res->hw_res[i];
/* rc = hw_intf->hw_ops.process_cmd(
* Single VFE case, Get the time stamp from hw_intf->hw_priv,
* available one csid hw in the context CAM_IFE_CSID_CMD_GET_TIME_STAMP,
* Dual VFE case, get the time stamp from &csid_get_time,
* master(left) would be sufficient sizeof(
*/ struct cam_csid_get_time_stamp_args));
if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) {
csid_get_time.node_res = *time_stamp =
hw_mgr_res->hw_res[i]; csid_get_time.time_stamp_val;
rc = hw_intf->hw_ops.process_cmd( *boot_time_stamp =
hw_intf->hw_priv, csid_get_time.boot_timestamp;
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;
}
} }
} }
} }

Просмотреть файл

@ -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", CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d",
csid_hw->hw_intf->hw_idx, val); csid_hw->hw_intf->hw_idx, val);
csid_hw->error_irq_count = 0; csid_hw->error_irq_count = 0;
csid_hw->prev_boot_timestamp = 0;
return rc; 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); spin_unlock_irqrestore(&csid_hw->lock_state, flags);
csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
csid_hw->error_irq_count = 0; csid_hw->error_irq_count = 0;
csid_hw->prev_boot_timestamp = 0;
return rc; return rc;
} }
@ -2928,6 +2930,7 @@ static int cam_ife_csid_get_time_stamp(
const struct cam_ife_csid_udi_reg_offset *udi_reg; const struct cam_ife_csid_udi_reg_offset *udi_reg;
struct timespec64 ts; struct timespec64 ts;
uint32_t time_32, id; uint32_t time_32, id;
uint64_t time_delta;
time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args; time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
res = time_stamp->node_res; 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_MUL_FACTOR,
CAM_IFE_CSID_QTIMER_DIV_FACTOR); CAM_IFE_CSID_QTIMER_DIV_FACTOR);
get_monotonic_boottime64(&ts); if (!csid_hw->prev_boot_timestamp) {
time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) + get_monotonic_boottime64(&ts);
ts.tv_nsec); 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; return 0;
} }

Просмотреть файл

@ -550,6 +550,8 @@ struct cam_ife_csid_path_cfg {
* @binning_enable Flag is set if hardware supports QCFA binning * @binning_enable Flag is set if hardware supports QCFA binning
* @binning_supported Flag is set if sensor 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_ife_csid_hw {
struct cam_hw_intf *hw_intf; struct cam_hw_intf *hw_intf;
@ -581,6 +583,8 @@ struct cam_ife_csid_hw {
spinlock_t lock_state; spinlock_t lock_state;
uint32_t binning_enable; uint32_t binning_enable;
uint32_t binning_supported; 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, int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,