1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #ifndef __TIMVF_EVDEV_H__ 6 #define __TIMVF_EVDEV_H__ 7 8 #include <rte_common.h> 9 #include <rte_cycles.h> 10 #include <rte_debug.h> 11 #include <rte_eal.h> 12 #include <rte_eventdev.h> 13 #include <rte_event_timer_adapter.h> 14 #include <rte_event_timer_adapter_pmd.h> 15 #include <rte_io.h> 16 #include <rte_lcore.h> 17 #include <rte_log.h> 18 #include <rte_malloc.h> 19 #include <rte_mbuf_pool_ops.h> 20 #include <rte_mempool.h> 21 #include <rte_memzone.h> 22 #include <rte_pci.h> 23 #include <rte_prefetch.h> 24 #include <rte_reciprocal.h> 25 26 #include <octeontx_mbox.h> 27 #include <octeontx_fpavf.h> 28 29 #define timvf_log(level, fmt, args...) \ 30 rte_log(RTE_LOG_ ## level, otx_logtype_timvf, \ 31 "[%s] %s() " fmt "\n", \ 32 RTE_STR(event_timer_octeontx), __func__, ## args) 33 34 #define timvf_log_info(fmt, ...) timvf_log(INFO, fmt, ##__VA_ARGS__) 35 #define timvf_log_dbg(fmt, ...) timvf_log(DEBUG, fmt, ##__VA_ARGS__) 36 #define timvf_log_err(fmt, ...) timvf_log(ERR, fmt, ##__VA_ARGS__) 37 #define timvf_func_trace timvf_log_dbg 38 39 #define TIM_COPROC (8) 40 #define TIM_GET_DEV_INFO (1) 41 #define TIM_GET_RING_INFO (2) 42 #define TIM_SET_RING_INFO (3) 43 #define TIM_RING_START_CYC_GET (4) 44 45 #define TIM_MAX_RINGS (64) 46 #define TIM_DEV_PER_NODE (1) 47 #define TIM_VF_PER_DEV (64) 48 #define TIM_RING_PER_DEV (TIM_VF_PER_DEV) 49 #define TIM_RING_NODE_SHIFT (6) 50 #define TIM_RING_MASK ((TIM_RING_PER_DEV) - 1) 51 #define TIM_RING_INVALID (-1) 52 53 #define TIM_MIN_INTERVAL (1E3) 54 #define TIM_MAX_INTERVAL ((1ull << 32) - 1) 55 #define TIM_MAX_BUCKETS (1ull << 20) 56 #define TIM_CHUNK_SIZE (4096) 57 #define TIM_MAX_CHUNKS_PER_BUCKET (1ull << 32) 58 59 #define TIMVF_MAX_BURST (8) 60 61 /* TIM VF Control/Status registers (CSRs): */ 62 /* VF_BAR0: */ 63 #define TIM_VF_NRSPERR_INT (0x0) 64 #define TIM_VF_NRSPERR_INT_W1S (0x8) 65 #define TIM_VF_NRSPERR_ENA_W1C (0x10) 66 #define TIM_VF_NRSPERR_ENA_W1S (0x18) 67 #define TIM_VRING_FR_RN_CYCLES (0x20) 68 #define TIM_VRING_FR_RN_GPIOS (0x28) 69 #define TIM_VRING_FR_RN_GTI (0x30) 70 #define TIM_VRING_FR_RN_PTP (0x38) 71 #define TIM_VRING_CTL0 (0x40) 72 #define TIM_VRING_CTL1 (0x50) 73 #define TIM_VRING_CTL2 (0x60) 74 #define TIM_VRING_BASE (0x100) 75 #define TIM_VRING_AURA (0x108) 76 #define TIM_VRING_REL (0x110) 77 78 #define TIM_CTL1_W0_S_BUCKET 20 79 #define TIM_CTL1_W0_M_BUCKET ((1ull << (40 - 20)) - 1) 80 81 #define TIM_BUCKET_W1_S_NUM_ENTRIES (0) /*Shift*/ 82 #define TIM_BUCKET_W1_M_NUM_ENTRIES ((1ull << (32 - 0)) - 1) 83 #define TIM_BUCKET_W1_S_SBT (32) 84 #define TIM_BUCKET_W1_M_SBT ((1ull << (33 - 32)) - 1) 85 #define TIM_BUCKET_W1_S_HBT (33) 86 #define TIM_BUCKET_W1_M_HBT ((1ull << (34 - 33)) - 1) 87 #define TIM_BUCKET_W1_S_BSK (34) 88 #define TIM_BUCKET_W1_M_BSK ((1ull << (35 - 34)) - 1) 89 #define TIM_BUCKET_W1_S_LOCK (40) 90 #define TIM_BUCKET_W1_M_LOCK ((1ull << (48 - 40)) - 1) 91 #define TIM_BUCKET_W1_S_CHUNK_REMAINDER (48) 92 #define TIM_BUCKET_W1_M_CHUNK_REMAINDER ((1ull << (64 - 48)) - 1) 93 94 #define TIM_BUCKET_SEMA \ 95 (TIM_BUCKET_CHUNK_REMAIN) 96 97 #define TIM_BUCKET_CHUNK_REMAIN \ 98 (TIM_BUCKET_W1_M_CHUNK_REMAINDER << TIM_BUCKET_W1_S_CHUNK_REMAINDER) 99 100 #define TIM_BUCKET_LOCK \ 101 (TIM_BUCKET_W1_M_LOCK << TIM_BUCKET_W1_S_LOCK) 102 103 #define TIM_BUCKET_SEMA_WLOCK \ 104 (TIM_BUCKET_CHUNK_REMAIN | (1ull << TIM_BUCKET_W1_S_LOCK)) 105 106 #define NSEC_PER_SEC 1E9 107 #define NSEC2CLK(__ns, __freq) (((__ns) * (__freq)) / NSEC_PER_SEC) 108 #define CLK2NSEC(__clk, __freq) (((__clk) * NSEC_PER_SEC) / (__freq)) 109 110 #define timvf_read64 rte_read64_relaxed 111 #define timvf_write64 rte_write64_relaxed 112 113 #define TIMVF_ENABLE_STATS_ARG ("timvf_stats") 114 115 extern int otx_logtype_timvf; 116 static const uint16_t nb_chunk_slots = (TIM_CHUNK_SIZE / 16) - 1; 117 118 struct timvf_info { 119 uint16_t domain; /* Domain id */ 120 uint8_t total_timvfs; /* Total timvf available in domain */ 121 }; 122 123 enum timvf_clk_src { 124 TIM_CLK_SRC_SCLK = RTE_EVENT_TIMER_ADAPTER_CPU_CLK, 125 TIM_CLK_SRC_GPIO = RTE_EVENT_TIMER_ADAPTER_EXT_CLK0, 126 TIM_CLK_SRC_GTI = RTE_EVENT_TIMER_ADAPTER_EXT_CLK1, 127 TIM_CLK_SRC_PTP = RTE_EVENT_TIMER_ADAPTER_EXT_CLK2, 128 }; 129 130 /* TIM_MEM_BUCKET */ 131 struct tim_mem_bucket { 132 uint64_t first_chunk; 133 union { 134 uint64_t w1; 135 struct { 136 uint32_t nb_entry; 137 uint8_t sbt:1; 138 uint8_t hbt:1; 139 uint8_t bsk:1; 140 uint8_t rsvd:5; 141 uint8_t lock; 142 int16_t chunk_remainder; 143 }; 144 }; 145 uint64_t current_chunk; 146 uint64_t pad; 147 } __rte_packed __rte_aligned(8); 148 149 struct tim_mem_entry { 150 uint64_t w0; 151 uint64_t wqe; 152 } __rte_packed; 153 154 struct timvf_ctrl_reg { 155 uint64_t rctrl0; 156 uint64_t rctrl1; 157 uint64_t rctrl2; 158 uint8_t use_pmu; 159 } __rte_packed; 160 161 struct timvf_ring; 162 163 typedef uint32_t (*bkt_id)(const uint32_t bkt_tcks, const uint32_t nb_bkts); 164 typedef struct tim_mem_entry * (*refill_chunk)( 165 struct tim_mem_bucket * const bkt, 166 struct timvf_ring * const timr); 167 168 struct timvf_ring { 169 bkt_id get_target_bkt; 170 refill_chunk refill_chunk; 171 struct rte_reciprocal_u64 fast_div; 172 uint64_t ring_start_cyc; 173 uint32_t nb_bkts; 174 struct tim_mem_bucket *bkt; 175 void *chunk_pool; 176 uint64_t tck_int; 177 volatile uint64_t tim_arm_cnt; 178 uint64_t tck_nsec; 179 void *vbar0; 180 void *bkt_pos; 181 uint64_t max_tout; 182 uint64_t nb_chunks; 183 enum timvf_clk_src clk_src; 184 uint16_t tim_ring_id; 185 } __rte_cache_aligned; 186 187 static __rte_always_inline uint32_t 188 bkt_mod(const uint32_t rel_bkt, const uint32_t nb_bkts) 189 { 190 return rel_bkt % nb_bkts; 191 } 192 193 static __rte_always_inline uint32_t 194 bkt_and(uint32_t rel_bkt, uint32_t nb_bkts) 195 { 196 return rel_bkt & (nb_bkts - 1); 197 } 198 199 int timvf_info(struct timvf_info *tinfo); 200 void *timvf_bar(uint8_t id, uint8_t bar); 201 int timvf_timer_adapter_caps_get(const struct rte_eventdev *dev, uint64_t flags, 202 uint32_t *caps, const struct rte_event_timer_adapter_ops **ops, 203 uint8_t enable_stats); 204 uint16_t timvf_timer_cancel_burst(const struct rte_event_timer_adapter *adptr, 205 struct rte_event_timer **tim, const uint16_t nb_timers); 206 uint16_t timvf_timer_arm_burst_sp(const struct rte_event_timer_adapter *adptr, 207 struct rte_event_timer **tim, const uint16_t nb_timers); 208 uint16_t timvf_timer_arm_burst_sp_stats( 209 const struct rte_event_timer_adapter *adptr, 210 struct rte_event_timer **tim, const uint16_t nb_timers); 211 uint16_t timvf_timer_arm_burst_mp(const struct rte_event_timer_adapter *adptr, 212 struct rte_event_timer **tim, const uint16_t nb_timers); 213 uint16_t timvf_timer_arm_burst_mp_stats( 214 const struct rte_event_timer_adapter *adptr, 215 struct rte_event_timer **tim, const uint16_t nb_timers); 216 uint16_t timvf_timer_arm_tmo_brst(const struct rte_event_timer_adapter *adptr, 217 struct rte_event_timer **tim, const uint64_t timeout_tick, 218 const uint16_t nb_timers); 219 uint16_t timvf_timer_arm_tmo_brst_stats( 220 const struct rte_event_timer_adapter *adptr, 221 struct rte_event_timer **tim, const uint64_t timeout_tick, 222 const uint16_t nb_timers); 223 void timvf_set_chunk_refill(struct timvf_ring * const timr, uint8_t use_fpa); 224 225 #endif /* __TIMVF_EVDEV_H__ */ 226