@@ -41,6 +41,7 @@ sources = files(
'nthw/core/nt200a0x/reset/nthw_fpga_rst_nt200a0x.c',
'nthw/core/nthw_fpga.c',
'nthw/core/nthw_gmf.c',
+ 'nthw/core/nthw_tsm.c',
'nthw/core/nthw_gpio_phy.c',
'nthw/core/nthw_hif.c',
'nthw/core/nthw_i2cm.c',
new file mode 100644
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef __NTHW_TSM_H__
+#define __NTHW_TSM_H__
+
+#include "stdint.h"
+
+#include "nthw_fpga_model.h"
+
+struct nthw_tsm {
+ nthw_fpga_t *mp_fpga;
+ nthw_module_t *mp_mod_tsm;
+ int mn_instance;
+
+ nthw_field_t *mp_fld_config_ts_format;
+
+ nthw_field_t *mp_fld_timer_ctrl_timer_en_t0;
+ nthw_field_t *mp_fld_timer_ctrl_timer_en_t1;
+
+ nthw_field_t *mp_fld_timer_timer_t0_max_count;
+
+ nthw_field_t *mp_fld_timer_timer_t1_max_count;
+
+ nthw_register_t *mp_reg_ts_lo;
+ nthw_field_t *mp_fld_ts_lo;
+
+ nthw_register_t *mp_reg_ts_hi;
+ nthw_field_t *mp_fld_ts_hi;
+
+ nthw_register_t *mp_reg_time_lo;
+ nthw_field_t *mp_fld_time_lo;
+
+ nthw_register_t *mp_reg_time_hi;
+ nthw_field_t *mp_fld_time_hi;
+};
+
+typedef struct nthw_tsm nthw_tsm_t;
+typedef struct nthw_tsm nthw_tsm;
+
+nthw_tsm_t *nthw_tsm_new(void);
+int nthw_tsm_init(nthw_tsm_t *p, nthw_fpga_t *p_fpga, int n_instance);
+
+int nthw_tsm_get_ts(nthw_tsm_t *p, uint64_t *p_ts);
+int nthw_tsm_get_time(nthw_tsm_t *p, uint64_t *p_time);
+
+int nthw_tsm_set_timer_t0_enable(nthw_tsm_t *p, bool b_enable);
+int nthw_tsm_set_timer_t0_max_count(nthw_tsm_t *p, uint32_t n_timer_val);
+int nthw_tsm_set_timer_t1_enable(nthw_tsm_t *p, bool b_enable);
+int nthw_tsm_set_timer_t1_max_count(nthw_tsm_t *p, uint32_t n_timer_val);
+
+int nthw_tsm_set_config_ts_format(nthw_tsm_t *p, uint32_t n_val);
+
+#endif /* __NTHW_TSM_H__ */
@@ -13,6 +13,8 @@
#include "nthw_fpga_instances.h"
#include "nthw_fpga_mod_str_map.h"
+#include "nthw_tsm.h"
+
#include <arpa/inet.h>
int nthw_fpga_get_param_info(struct fpga_info_s *p_fpga_info, nthw_fpga_t *p_fpga)
@@ -179,6 +181,7 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
nthw_hif_t *p_nthw_hif = NULL;
nthw_pcie3_t *p_nthw_pcie3 = NULL;
nthw_rac_t *p_nthw_rac = NULL;
+ nthw_tsm_t *p_nthw_tsm = NULL;
mcu_info_t *p_mcu_info = &p_fpga_info->mcu_info;
uint64_t n_fpga_ident = 0;
@@ -331,6 +334,50 @@ int nthw_fpga_init(struct fpga_info_s *p_fpga_info)
p_fpga_info->mp_nthw_hif = p_nthw_hif;
+ p_nthw_tsm = nthw_tsm_new();
+
+ if (p_nthw_tsm) {
+ nthw_tsm_init(p_nthw_tsm, p_fpga, 0);
+
+ nthw_tsm_set_config_ts_format(p_nthw_tsm, 1); /* 1 = TSM: TS format native */
+
+ /* Timer T0 - stat toggle timer */
+ nthw_tsm_set_timer_t0_enable(p_nthw_tsm, false);
+ nthw_tsm_set_timer_t0_max_count(p_nthw_tsm, 50 * 1000 * 1000); /* ns */
+ nthw_tsm_set_timer_t0_enable(p_nthw_tsm, true);
+
+ /* Timer T1 - keep alive timer */
+ nthw_tsm_set_timer_t1_enable(p_nthw_tsm, false);
+ nthw_tsm_set_timer_t1_max_count(p_nthw_tsm, 100 * 1000 * 1000); /* ns */
+ nthw_tsm_set_timer_t1_enable(p_nthw_tsm, true);
+ }
+
+ p_fpga_info->mp_nthw_tsm = p_nthw_tsm;
+
+ /* TSM sample triggering: test validation... */
+#if defined(DEBUG) && (1)
+ {
+ uint64_t n_time, n_ts;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (p_nthw_hif)
+ nthw_hif_trigger_sample_time(p_nthw_hif);
+
+ else if (p_nthw_pcie3)
+ nthw_pcie3_trigger_sample_time(p_nthw_pcie3);
+
+ nthw_tsm_get_time(p_nthw_tsm, &n_time);
+ nthw_tsm_get_ts(p_nthw_tsm, &n_ts);
+
+ NT_LOG(DBG, NTHW, "%s: TSM time: %016" PRIX64 " %016" PRIX64 "\n",
+ p_adapter_id_str, n_time, n_ts);
+
+ nt_os_wait_usec(1000);
+ }
+ }
+#endif
+
return res;
}
new file mode 100644
@@ -0,0 +1,167 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "ntlog.h"
+
+#include "nthw_drv.h"
+#include "nthw_register.h"
+
+#include "nthw_tsm.h"
+
+nthw_tsm_t *nthw_tsm_new(void)
+{
+ nthw_tsm_t *p = malloc(sizeof(nthw_tsm_t));
+
+ if (p)
+ memset(p, 0, sizeof(nthw_tsm_t));
+
+ return p;
+}
+
+int nthw_tsm_init(nthw_tsm_t *p, nthw_fpga_t *p_fpga, int n_instance)
+{
+ const char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;
+ nthw_module_t *mod = nthw_fpga_query_module(p_fpga, MOD_TSM, n_instance);
+
+ if (p == NULL)
+ return mod == NULL ? -1 : 0;
+
+ if (mod == NULL) {
+ NT_LOG(ERR, NTHW, "%s: TSM %d: no such instance", p_adapter_id_str, n_instance);
+ return -1;
+ }
+
+ p->mp_fpga = p_fpga;
+ p->mn_instance = n_instance;
+ p->mp_mod_tsm = mod;
+
+ {
+ nthw_register_t *p_reg;
+
+ p_reg = nthw_module_get_register(p->mp_mod_tsm, TSM_CONFIG);
+ p->mp_fld_config_ts_format = nthw_register_get_field(p_reg, TSM_CONFIG_TS_FORMAT);
+
+ p_reg = nthw_module_get_register(p->mp_mod_tsm, TSM_TIMER_CTRL);
+ p->mp_fld_timer_ctrl_timer_en_t0 =
+ nthw_register_get_field(p_reg, TSM_TIMER_CTRL_TIMER_EN_T0);
+ p->mp_fld_timer_ctrl_timer_en_t1 =
+ nthw_register_get_field(p_reg, TSM_TIMER_CTRL_TIMER_EN_T1);
+
+ p_reg = nthw_module_get_register(p->mp_mod_tsm, TSM_TIMER_T0);
+ p->mp_fld_timer_timer_t0_max_count =
+ nthw_register_get_field(p_reg, TSM_TIMER_T0_MAX_COUNT);
+
+ p_reg = nthw_module_get_register(p->mp_mod_tsm, TSM_TIMER_T1);
+ p->mp_fld_timer_timer_t1_max_count =
+ nthw_register_get_field(p_reg, TSM_TIMER_T1_MAX_COUNT);
+
+ p->mp_reg_time_lo = nthw_module_get_register(p->mp_mod_tsm, TSM_TIME_LO);
+ p_reg = p->mp_reg_time_lo;
+ p->mp_fld_time_lo = nthw_register_get_field(p_reg, TSM_TIME_LO_NS);
+
+ p->mp_reg_time_hi = nthw_module_get_register(p->mp_mod_tsm, TSM_TIME_HI);
+ p_reg = p->mp_reg_time_hi;
+ p->mp_fld_time_hi = nthw_register_get_field(p_reg, TSM_TIME_HI_SEC);
+
+ p->mp_reg_ts_lo = nthw_module_get_register(p->mp_mod_tsm, TSM_TS_LO);
+ p_reg = p->mp_reg_ts_lo;
+ p->mp_fld_ts_lo = nthw_register_get_field(p_reg, TSM_TS_LO_TIME);
+
+ p->mp_reg_ts_hi = nthw_module_get_register(p->mp_mod_tsm, TSM_TS_HI);
+ p_reg = p->mp_reg_ts_hi;
+ p->mp_fld_ts_hi = nthw_register_get_field(p_reg, TSM_TS_HI_TIME);
+ }
+ return 0;
+}
+
+int nthw_tsm_get_ts(nthw_tsm_t *p, uint64_t *p_ts)
+{
+ uint32_t n_ts_lo, n_ts_hi;
+ uint64_t val;
+
+ if (!p_ts)
+ return -1;
+
+ n_ts_lo = nthw_field_get_updated(p->mp_fld_ts_lo);
+ n_ts_hi = nthw_field_get_updated(p->mp_fld_ts_hi);
+
+ val = ((((uint64_t)n_ts_hi) << 32UL) | n_ts_lo);
+
+ if (p_ts)
+ *p_ts = val;
+
+ return 0;
+}
+
+int nthw_tsm_get_time(nthw_tsm_t *p, uint64_t *p_time)
+{
+ uint32_t n_time_lo, n_time_hi;
+ uint64_t val;
+
+ if (!p_time)
+ return -1;
+
+ n_time_lo = nthw_field_get_updated(p->mp_fld_time_lo);
+ n_time_hi = nthw_field_get_updated(p->mp_fld_time_hi);
+
+ val = ((((uint64_t)n_time_hi) << 32UL) | n_time_lo);
+
+ if (p_time)
+ *p_time = val;
+
+ return 0;
+}
+
+int nthw_tsm_set_timer_t0_enable(nthw_tsm_t *p, bool b_enable)
+{
+ nthw_field_update_register(p->mp_fld_timer_ctrl_timer_en_t0);
+
+ if (b_enable)
+ nthw_field_set_flush(p->mp_fld_timer_ctrl_timer_en_t0);
+
+ else
+ nthw_field_clr_flush(p->mp_fld_timer_ctrl_timer_en_t0);
+
+ return 0;
+}
+
+int nthw_tsm_set_timer_t0_max_count(nthw_tsm_t *p, uint32_t n_timer_val)
+{
+ /* Timer T0 - stat toggle timer */
+ nthw_field_update_register(p->mp_fld_timer_timer_t0_max_count);
+ nthw_field_set_val_flush32(p->mp_fld_timer_timer_t0_max_count,
+ n_timer_val); /* ns (50*1000*1000) */
+ return 0;
+}
+
+int nthw_tsm_set_timer_t1_enable(nthw_tsm_t *p, bool b_enable)
+{
+ nthw_field_update_register(p->mp_fld_timer_ctrl_timer_en_t1);
+
+ if (b_enable)
+ nthw_field_set_flush(p->mp_fld_timer_ctrl_timer_en_t1);
+
+ else
+ nthw_field_clr_flush(p->mp_fld_timer_ctrl_timer_en_t1);
+
+ return 0;
+}
+
+int nthw_tsm_set_timer_t1_max_count(nthw_tsm_t *p, uint32_t n_timer_val)
+{
+ /* Timer T1 - keep alive timer */
+ nthw_field_update_register(p->mp_fld_timer_timer_t1_max_count);
+ nthw_field_set_val_flush32(p->mp_fld_timer_timer_t1_max_count,
+ n_timer_val); /* ns (100*1000*1000) */
+ return 0;
+}
+
+int nthw_tsm_set_config_ts_format(nthw_tsm_t *p, uint32_t n_val)
+{
+ nthw_field_update_register(p->mp_fld_config_ts_format);
+ /* 0x1: Native - 10ns units, start date: 1970-01-01. */
+ nthw_field_set_val_flush32(p->mp_fld_config_ts_format, n_val);
+ return 0;
+}
@@ -48,6 +48,7 @@
#define MOD_SLC (0x1aef1f38UL)
#define MOD_SLC_LR (0x969fc50bUL)
#define MOD_STA (0x76fae64dUL)
+#define MOD_TSM (0x35422a24UL)
#define MOD_TX_CPY (0x60acf217UL)
#define MOD_TX_INS (0x59afa100UL)
#define MOD_TX_RPL (0x1095dfbbUL)
@@ -44,6 +44,7 @@
#include "nthw_fpga_reg_defs_rpp_lr.h"
#include "nthw_fpga_reg_defs_rst9563.h"
#include "nthw_fpga_reg_defs_sdc.h"
+#include "nthw_fpga_reg_defs_tsm.h"
#include "nthw_fpga_reg_defs_slc.h"
#include "nthw_fpga_reg_defs_slc_lr.h"
#include "nthw_fpga_reg_defs_sta.h"
new file mode 100644
@@ -0,0 +1,28 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Napatech A/S
+ */
+
+#ifndef _NTHW_FPGA_REG_DEFS_TSM_
+#define _NTHW_FPGA_REG_DEFS_TSM_
+
+/* TSM */
+#define TSM_CONFIG (0xef5dec83UL)
+#define TSM_CONFIG_TS_FORMAT (0xe6efc2faUL)
+#define TSM_TIMER_CTRL (0x648da051UL)
+#define TSM_TIMER_CTRL_TIMER_EN_T0 (0x17cee154UL)
+#define TSM_TIMER_CTRL_TIMER_EN_T1 (0x60c9d1c2UL)
+#define TSM_TIMER_T0 (0x417217a5UL)
+#define TSM_TIMER_T0_MAX_COUNT (0xaa601706UL)
+#define TSM_TIMER_T1 (0x36752733UL)
+#define TSM_TIMER_T1_MAX_COUNT (0x6beec8c6UL)
+#define TSM_TIME_HI (0x175acea1UL)
+#define TSM_TIME_HI_SEC (0xc0e9c9a1UL)
+#define TSM_TIME_LO (0x9a55ae90UL)
+#define TSM_TIME_LO_NS (0x879c5c4bUL)
+#define TSM_TS_HI (0xccfe9e5eUL)
+#define TSM_TS_HI_TIME (0xc23fed30UL)
+#define TSM_TS_LO (0x41f1fe6fUL)
+#define TSM_TS_LO_TIME (0xe0292a3eUL)
+
+#endif /* _NTHW_FPGA_REG_DEFS_TSM_ */