/* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2017 Cavium, Inc */ #ifndef __TIMVF_EVDEV_H__ #define __TIMVF_EVDEV_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define timvf_log(level, fmt, args...) \ rte_log(RTE_LOG_ ## level, otx_logtype_timvf, \ "[%s] %s() " fmt "\n", \ RTE_STR(event_timer_octeontx), __func__, ## args) #define timvf_log_info(fmt, ...) timvf_log(INFO, fmt, ##__VA_ARGS__) #define timvf_log_dbg(fmt, ...) timvf_log(DEBUG, fmt, ##__VA_ARGS__) #define timvf_log_err(fmt, ...) timvf_log(ERR, fmt, ##__VA_ARGS__) #define timvf_func_trace timvf_log_dbg #define TIM_COPROC (8) #define TIM_GET_DEV_INFO (1) #define TIM_GET_RING_INFO (2) #define TIM_SET_RING_INFO (3) #define TIM_RING_START_CYC_GET (4) #define TIM_MAX_RINGS (64) #define TIM_DEV_PER_NODE (1) #define TIM_VF_PER_DEV (64) #define TIM_RING_PER_DEV (TIM_VF_PER_DEV) #define TIM_RING_NODE_SHIFT (6) #define TIM_RING_MASK ((TIM_RING_PER_DEV) - 1) #define TIM_RING_INVALID (-1) #define TIM_MIN_INTERVAL (1E3) #define TIM_MAX_INTERVAL ((1ull << 32) - 1) #define TIM_MAX_BUCKETS (1ull << 20) #define TIM_CHUNK_SIZE (4096) #define TIM_MAX_CHUNKS_PER_BUCKET (1ull << 32) #define TIMVF_MAX_BURST (8) /* TIM VF Control/Status registers (CSRs): */ /* VF_BAR0: */ #define TIM_VF_NRSPERR_INT (0x0) #define TIM_VF_NRSPERR_INT_W1S (0x8) #define TIM_VF_NRSPERR_ENA_W1C (0x10) #define TIM_VF_NRSPERR_ENA_W1S (0x18) #define TIM_VRING_FR_RN_CYCLES (0x20) #define TIM_VRING_FR_RN_GPIOS (0x28) #define TIM_VRING_FR_RN_GTI (0x30) #define TIM_VRING_FR_RN_PTP (0x38) #define TIM_VRING_CTL0 (0x40) #define TIM_VRING_CTL1 (0x50) #define TIM_VRING_CTL2 (0x60) #define TIM_VRING_BASE (0x100) #define TIM_VRING_AURA (0x108) #define TIM_VRING_REL (0x110) #define TIM_CTL1_W0_S_BUCKET 20 #define TIM_CTL1_W0_M_BUCKET ((1ull << (40 - 20)) - 1) #define TIM_BUCKET_W1_S_NUM_ENTRIES (0) /*Shift*/ #define TIM_BUCKET_W1_M_NUM_ENTRIES ((1ull << (32 - 0)) - 1) #define TIM_BUCKET_W1_S_SBT (32) #define TIM_BUCKET_W1_M_SBT ((1ull << (33 - 32)) - 1) #define TIM_BUCKET_W1_S_HBT (33) #define TIM_BUCKET_W1_M_HBT ((1ull << (34 - 33)) - 1) #define TIM_BUCKET_W1_S_BSK (34) #define TIM_BUCKET_W1_M_BSK ((1ull << (35 - 34)) - 1) #define TIM_BUCKET_W1_S_LOCK (40) #define TIM_BUCKET_W1_M_LOCK ((1ull << (48 - 40)) - 1) #define TIM_BUCKET_W1_S_CHUNK_REMAINDER (48) #define TIM_BUCKET_W1_M_CHUNK_REMAINDER ((1ull << (64 - 48)) - 1) #define TIM_BUCKET_SEMA \ (TIM_BUCKET_CHUNK_REMAIN) #define TIM_BUCKET_CHUNK_REMAIN \ (TIM_BUCKET_W1_M_CHUNK_REMAINDER << TIM_BUCKET_W1_S_CHUNK_REMAINDER) #define TIM_BUCKET_LOCK \ (TIM_BUCKET_W1_M_LOCK << TIM_BUCKET_W1_S_LOCK) #define TIM_BUCKET_SEMA_WLOCK \ (TIM_BUCKET_CHUNK_REMAIN | (1ull << TIM_BUCKET_W1_S_LOCK)) #define NSEC_PER_SEC 1E9 #define NSEC2CLK(__ns, __freq) (((__ns) * (__freq)) / NSEC_PER_SEC) #define CLK2NSEC(__clk, __freq) (((__clk) * NSEC_PER_SEC) / (__freq)) #define timvf_read64 rte_read64_relaxed #define timvf_write64 rte_write64_relaxed #define TIMVF_ENABLE_STATS_ARG ("timvf_stats") extern int otx_logtype_timvf; static const uint16_t nb_chunk_slots = (TIM_CHUNK_SIZE / 16) - 1; struct timvf_info { uint16_t domain; /* Domain id */ uint8_t total_timvfs; /* Total timvf available in domain */ }; enum timvf_clk_src { TIM_CLK_SRC_SCLK = RTE_EVENT_TIMER_ADAPTER_CPU_CLK, TIM_CLK_SRC_GPIO = RTE_EVENT_TIMER_ADAPTER_EXT_CLK0, TIM_CLK_SRC_GTI = RTE_EVENT_TIMER_ADAPTER_EXT_CLK1, TIM_CLK_SRC_PTP = RTE_EVENT_TIMER_ADAPTER_EXT_CLK2, }; /* TIM_MEM_BUCKET */ struct tim_mem_bucket { uint64_t first_chunk; union { uint64_t w1; struct { uint32_t nb_entry; uint8_t sbt:1; uint8_t hbt:1; uint8_t bsk:1; uint8_t rsvd:5; uint8_t lock; int16_t chunk_remainder; }; }; uint64_t current_chunk; uint64_t pad; } __rte_packed __rte_aligned(8); struct tim_mem_entry { uint64_t w0; uint64_t wqe; } __rte_packed; struct timvf_ctrl_reg { uint64_t rctrl0; uint64_t rctrl1; uint64_t rctrl2; uint8_t use_pmu; } __rte_packed; struct timvf_ring; typedef uint32_t (*bkt_id)(const uint32_t bkt_tcks, const uint32_t nb_bkts); typedef struct tim_mem_entry * (*refill_chunk)( struct tim_mem_bucket * const bkt, struct timvf_ring * const timr); struct timvf_ring { bkt_id get_target_bkt; refill_chunk refill_chunk; struct rte_reciprocal_u64 fast_div; uint64_t ring_start_cyc; uint32_t nb_bkts; struct tim_mem_bucket *bkt; void *chunk_pool; uint64_t tck_int; volatile uint64_t tim_arm_cnt; uint64_t tck_nsec; void *vbar0; void *bkt_pos; uint64_t max_tout; uint64_t nb_chunks; enum timvf_clk_src clk_src; uint16_t tim_ring_id; } __rte_cache_aligned; static __rte_always_inline uint32_t bkt_mod(const uint32_t rel_bkt, const uint32_t nb_bkts) { return rel_bkt % nb_bkts; } static __rte_always_inline uint32_t bkt_and(uint32_t rel_bkt, uint32_t nb_bkts) { return rel_bkt & (nb_bkts - 1); } int timvf_info(struct timvf_info *tinfo); void *timvf_bar(uint8_t id, uint8_t bar); int timvf_timer_adapter_caps_get(const struct rte_eventdev *dev, uint64_t flags, uint32_t *caps, const struct rte_event_timer_adapter_ops **ops, uint8_t enable_stats); uint16_t timvf_timer_cancel_burst(const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim, const uint16_t nb_timers); uint16_t timvf_timer_arm_burst_sp(const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim, const uint16_t nb_timers); uint16_t timvf_timer_arm_burst_sp_stats( const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim, const uint16_t nb_timers); uint16_t timvf_timer_arm_burst_mp(const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim, const uint16_t nb_timers); uint16_t timvf_timer_arm_burst_mp_stats( const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim, const uint16_t nb_timers); uint16_t timvf_timer_arm_tmo_brst(const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim, const uint64_t timeout_tick, const uint16_t nb_timers); uint16_t timvf_timer_arm_tmo_brst_stats( const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim, const uint64_t timeout_tick, const uint16_t nb_timers); void timvf_set_chunk_refill(struct timvf_ring * const timr, uint8_t use_fpa); #endif /* __TIMVF_EVDEV_H__ */