Loading drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +33 −31 Original line number Diff line number Diff line Loading @@ -4469,7 +4469,9 @@ 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) { 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; Loading Loading @@ -4503,7 +4505,7 @@ static int cam_tfe_mgr_cmd_get_sof_timestamp( csid_get_time.time_stamp_val; *boot_time_stamp = csid_get_time.boot_timestamp; } break; } } } Loading drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c +70 −19 Original line number Diff line number Diff line Loading @@ -343,6 +343,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; } Loading Loading @@ -966,6 +967,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; } Loading Loading @@ -1580,6 +1582,25 @@ 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) { Loading @@ -1589,7 +1610,8 @@ static int cam_tfe_csid_get_time_stamp( 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; Loading @@ -1612,33 +1634,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); if (!csid_hw->prev_boot_timestamp) { get_monotonic_boottime64(&ts); time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) + 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; } Loading Loading @@ -2936,6 +2986,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; return 0; err: Loading drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h +4 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,8 @@ struct cam_tfe_csid_path_cfg { * @lock_state csid spin lock * @event_cb: Callback function to hw mgr in case of hw events * @event_cb_priv: Context data * @prev_boot_timestamp previous frame bootime stamp * @prev_qtimer_ts previous frame qtimer csid timestamp * */ struct cam_tfe_csid_hw { Loading @@ -409,6 +411,8 @@ struct cam_tfe_csid_hw { spinlock_t spin_lock; cam_hw_mgr_event_cb_func event_cb; void *event_cb_priv; 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 Loading
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +33 −31 Original line number Diff line number Diff line Loading @@ -4469,7 +4469,9 @@ 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) { 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; Loading Loading @@ -4503,7 +4505,7 @@ static int cam_tfe_mgr_cmd_get_sof_timestamp( csid_get_time.time_stamp_val; *boot_time_stamp = csid_get_time.boot_timestamp; } break; } } } Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c +70 −19 Original line number Diff line number Diff line Loading @@ -343,6 +343,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; } Loading Loading @@ -966,6 +967,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; } Loading Loading @@ -1580,6 +1582,25 @@ 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) { Loading @@ -1589,7 +1610,8 @@ static int cam_tfe_csid_get_time_stamp( 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; Loading @@ -1612,33 +1634,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); if (!csid_hw->prev_boot_timestamp) { get_monotonic_boottime64(&ts); time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) + 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; } Loading Loading @@ -2936,6 +2986,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; return 0; err: Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h +4 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,8 @@ struct cam_tfe_csid_path_cfg { * @lock_state csid spin lock * @event_cb: Callback function to hw mgr in case of hw events * @event_cb_priv: Context data * @prev_boot_timestamp previous frame bootime stamp * @prev_qtimer_ts previous frame qtimer csid timestamp * */ struct cam_tfe_csid_hw { Loading @@ -409,6 +411,8 @@ struct cam_tfe_csid_hw { spinlock_t spin_lock; cam_hw_mgr_event_cb_func event_cb; void *event_cb_priv; 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