mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
Merge "msm: camera: tfe: Handle sof monotonic boot time stamp" into camera-kernel.lnx.4.0
This commit is contained in:
commit
10729c8cf2
3 changed files with 107 additions and 50 deletions
|
|
@ -4690,41 +4690,43 @@ static int cam_tfe_mgr_cmd_get_sof_timestamp(
|
|||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_tfe_csid_get_time_stamp_args csid_get_time;
|
||||
|
||||
list_for_each_entry(hw_mgr_res, &tfe_ctx->res_list_tfe_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(&tfe_ctx->res_list_tfe_csid,
|
||||
struct cam_isp_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 tfe 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 tfe case and
|
||||
* Rdi only context case left resource only hold
|
||||
* the RDI resource
|
||||
* Single TFE case, Get the time stamp from
|
||||
* available one csid hw in the context
|
||||
* Dual TFE 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 TFE case, Get the time stamp from
|
||||
* available one csid hw in the context
|
||||
* Dual TFE 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_TFE_CSID_CMD_GET_TIME_STAMP,
|
||||
&csid_get_time,
|
||||
sizeof(struct
|
||||
cam_tfe_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_TFE_CSID_CMD_GET_TIME_STAMP,
|
||||
&csid_get_time,
|
||||
sizeof(struct
|
||||
cam_tfe_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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_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;
|
||||
}
|
||||
|
|
@ -998,6 +999,7 @@ static int cam_tfe_csid_disable_hw(struct cam_tfe_csid_hw *csid_hw)
|
|||
spin_unlock_irqrestore(&csid_hw->spin_lock, 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;
|
||||
}
|
||||
|
|
@ -1669,16 +1671,36 @@ static int cam_tfe_csid_poll_stop_status(
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_tfe_csid_read_timestamp(void __iomem *base,
|
||||
uint32_t msb_offset, uint32_t lsb_offset, uint64_t *timestamp)
|
||||
{
|
||||
uint32_t lsb, msb, tmp, torn = 0;
|
||||
|
||||
msb = cam_io_r_mb(base + msb_offset);
|
||||
do {
|
||||
tmp = msb;
|
||||
torn++;
|
||||
lsb = cam_io_r_mb(base + lsb_offset);
|
||||
msb = cam_io_r_mb(base + msb_offset);
|
||||
} while (tmp != msb);
|
||||
|
||||
*timestamp = msb;
|
||||
*timestamp = (*timestamp << 32) | lsb;
|
||||
|
||||
return (torn > 1);
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_get_time_stamp(
|
||||
struct cam_tfe_csid_hw *csid_hw, void *cmd_args)
|
||||
{
|
||||
struct cam_tfe_csid_get_time_stamp_args *time_stamp;
|
||||
struct cam_tfe_csid_get_time_stamp_args *time_stamp;
|
||||
struct cam_isp_resource_node *res;
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
const struct cam_tfe_csid_rdi_reg_offset *rdi_reg;
|
||||
struct timespec64 ts;
|
||||
uint32_t time_32, id;
|
||||
uint32_t id, torn;
|
||||
uint64_t time_delta;
|
||||
|
||||
time_stamp = (struct cam_tfe_csid_get_time_stamp_args *)cmd_args;
|
||||
res = time_stamp->node_res;
|
||||
|
|
@ -1701,33 +1723,61 @@ static int cam_tfe_csid_get_time_stamp(
|
|||
}
|
||||
|
||||
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) {
|
||||
time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
csid_reg->ipp_reg->csid_pxl_timestamp_curr1_sof_addr);
|
||||
time_stamp->time_stamp_val = (uint64_t) time_32;
|
||||
time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
|
||||
time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
csid_reg->ipp_reg->csid_pxl_timestamp_curr0_sof_addr);
|
||||
torn = __cam_tfe_csid_read_timestamp(
|
||||
soc_info->reg_map[0].mem_base,
|
||||
csid_reg->ipp_reg->csid_pxl_timestamp_curr1_sof_addr,
|
||||
csid_reg->ipp_reg->csid_pxl_timestamp_curr0_sof_addr,
|
||||
&time_stamp->time_stamp_val);
|
||||
} else {
|
||||
id = res->res_id;
|
||||
rdi_reg = csid_reg->rdi_reg[id];
|
||||
time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
rdi_reg->csid_rdi_timestamp_curr1_sof_addr);
|
||||
time_stamp->time_stamp_val = (uint64_t) time_32;
|
||||
time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
|
||||
|
||||
time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
rdi_reg->csid_rdi_timestamp_curr0_sof_addr);
|
||||
torn = __cam_tfe_csid_read_timestamp(
|
||||
soc_info->reg_map[0].mem_base,
|
||||
rdi_reg->csid_rdi_timestamp_curr1_sof_addr,
|
||||
rdi_reg->csid_rdi_timestamp_curr0_sof_addr,
|
||||
&time_stamp->time_stamp_val);
|
||||
}
|
||||
|
||||
time_stamp->time_stamp_val |= (uint64_t) time_32;
|
||||
time_stamp->time_stamp_val = mul_u64_u32_div(
|
||||
time_stamp->time_stamp_val,
|
||||
CAM_TFE_CSID_QTIMER_MUL_FACTOR,
|
||||
CAM_TFE_CSID_QTIMER_DIV_FACTOR);
|
||||
|
||||
ktime_get_boottime_ts64(&ts);
|
||||
time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) +
|
||||
ts.tv_nsec);
|
||||
if (!csid_hw->prev_boot_timestamp) {
|
||||
ktime_get_boottime_ts64(&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;
|
||||
|
||||
if (csid_hw->prev_boot_timestamp >
|
||||
U64_MAX - time_delta) {
|
||||
CAM_WARN(CAM_ISP, "boottimestamp overflowed");
|
||||
CAM_INFO(CAM_ISP,
|
||||
"currQTimer %lx prevQTimer %lx prevBootTimer %lx torn %d",
|
||||
time_stamp->time_stamp_val,
|
||||
csid_hw->prev_qtimer_ts,
|
||||
csid_hw->prev_boot_timestamp, torn);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
time_stamp->boot_timestamp =
|
||||
csid_hw->prev_boot_timestamp + time_delta;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"currQTimer %lx prevQTimer %lx currBootTimer %lx prevBootTimer %lx torn %d",
|
||||
time_stamp->time_stamp_val,
|
||||
csid_hw->prev_qtimer_ts, time_stamp->boot_timestamp,
|
||||
csid_hw->prev_boot_timestamp, torn);
|
||||
|
||||
csid_hw->prev_qtimer_ts = time_stamp->time_stamp_val;
|
||||
csid_hw->prev_boot_timestamp = time_stamp->boot_timestamp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3142,6 +3192,7 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
|
|||
|
||||
tfe_csid_hw->csid_debug = 0;
|
||||
tfe_csid_hw->error_irq_count = 0;
|
||||
tfe_csid_hw->prev_boot_timestamp = 0;
|
||||
|
||||
rc = cam_tfe_csid_disable_soc_resources(
|
||||
&tfe_csid_hw->hw_info->soc_info);
|
||||
|
|
|
|||
|
|
@ -387,6 +387,8 @@ struct cam_tfe_csid_path_cfg {
|
|||
* @ppi_hw_intf interface to ppi hardware
|
||||
* @ppi_enabled flag to specify if the hardware has ppi bridge
|
||||
* or not
|
||||
* @prev_boot_timestamp previous frame bootime stamp
|
||||
* @prev_qtimer_ts previous frame qtimer csid timestamp
|
||||
*
|
||||
*/
|
||||
struct cam_tfe_csid_hw {
|
||||
|
|
@ -415,6 +417,8 @@ struct cam_tfe_csid_hw {
|
|||
void *event_cb_priv;
|
||||
struct cam_hw_intf *ppi_hw_intf[CAM_CSID_PPI_HW_MAX];
|
||||
bool ppi_enable;
|
||||
uint64_t prev_boot_timestamp;
|
||||
uint64_t prev_qtimer_ts;
|
||||
};
|
||||
|
||||
int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
|
||||
|
|
|
|||
Loading…
Reference in a new issue