Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #ifndef __CNXK_TIM_EVDEV_H__
6 : : #define __CNXK_TIM_EVDEV_H__
7 : :
8 : : #include <stddef.h>
9 : : #include <stdint.h>
10 : : #include <stdlib.h>
11 : : #include <string.h>
12 : :
13 : : #include <eventdev_pmd_pci.h>
14 : : #include <rte_event_timer_adapter.h>
15 : : #include <rte_malloc.h>
16 : : #include <rte_memzone.h>
17 : : #include <rte_reciprocal.h>
18 : : #include <rte_vect.h>
19 : :
20 : : #define NSECPERSEC 1E9
21 : : #define USECPERSEC 1E6
22 : : #define TICK2NSEC(__tck, __freq) (((__tck)*NSECPERSEC) / (__freq))
23 : :
24 : : #define CNXK_TIM_EVDEV_NAME cnxk_tim_eventdev
25 : : #define CNXK_TIM_MAX_BUCKETS (0xFFFFF)
26 : : #define CNXK_TIM_RING_DEF_CHUNK_SZ (1024)
27 : : #define CNXK_TIM_CHUNK_ALIGNMENT (16)
28 : : #define CNXK_TIM_MAX_BURST (16)
29 : : #define CNXK_TIM_NB_CHUNK_SLOTS(sz) (((sz) / CNXK_TIM_CHUNK_ALIGNMENT) - 1)
30 : : #define CNXK_TIM_MIN_CHUNK_SLOTS (0x1)
31 : : #define CNXK_TIM_MAX_CHUNK_SLOTS (0x1FFE)
32 : : #define CNXK_TIM_MAX_POOL_CACHE_SZ (16)
33 : : #define CNXK_TIM_HWWQE_RES_OFFSET_B (24)
34 : : #define CNXK_TIM_ENT_PER_LMT (7)
35 : :
36 : : #define CN9K_TIM_MIN_TMO_TKS (256)
37 : :
38 : : #define CNXK_TIM_DISABLE_NPA "tim_disable_npa"
39 : : #define CNXK_TIM_CHNK_SLOTS "tim_chnk_slots"
40 : : #define CNXK_TIM_STATS_ENA "tim_stats_ena"
41 : : #define CNXK_TIM_RINGS_LMT "tim_rings_lmt"
42 : : #define CNXK_TIM_RING_CTL "tim_ring_ctl"
43 : : #define CNXK_TIM_EXT_CLK "tim_eclk_freq"
44 : :
45 : : #define CNXK_TIM_SP 0x1
46 : : #define CNXK_TIM_MP 0x2
47 : : #define CNXK_TIM_ENA_FB 0x10
48 : : #define CNXK_TIM_ENA_DFB 0x20
49 : : #define CNXK_TIM_ENA_STATS 0x40
50 : :
51 : : #define TIM_BUCKET_W1_S_CHUNK_REMAINDER (48)
52 : : #define TIM_BUCKET_W1_M_CHUNK_REMAINDER \
53 : : ((1ULL << (64 - TIM_BUCKET_W1_S_CHUNK_REMAINDER)) - 1)
54 : : #define TIM_BUCKET_W1_S_LOCK (40)
55 : : #define TIM_BUCKET_W1_M_LOCK \
56 : : ((1ULL << (TIM_BUCKET_W1_S_CHUNK_REMAINDER - TIM_BUCKET_W1_S_LOCK)) - 1)
57 : : #define TIM_BUCKET_W1_S_RSVD (35)
58 : : #define TIM_BUCKET_W1_S_BSK (34)
59 : : #define TIM_BUCKET_W1_M_BSK \
60 : : ((1ULL << (TIM_BUCKET_W1_S_RSVD - TIM_BUCKET_W1_S_BSK)) - 1)
61 : : #define TIM_BUCKET_W1_S_HBT (33)
62 : : #define TIM_BUCKET_W1_M_HBT \
63 : : ((1ULL << (TIM_BUCKET_W1_S_BSK - TIM_BUCKET_W1_S_HBT)) - 1)
64 : : #define TIM_BUCKET_W1_S_SBT (32)
65 : : #define TIM_BUCKET_W1_M_SBT \
66 : : ((1ULL << (TIM_BUCKET_W1_S_HBT - TIM_BUCKET_W1_S_SBT)) - 1)
67 : : #define TIM_BUCKET_W1_S_NUM_ENTRIES (0)
68 : : #define TIM_BUCKET_W1_M_NUM_ENTRIES \
69 : : ((1ULL << (TIM_BUCKET_W1_S_SBT - TIM_BUCKET_W1_S_NUM_ENTRIES)) - 1)
70 : :
71 : : #define TIM_BUCKET_SEMA (TIM_BUCKET_CHUNK_REMAIN)
72 : :
73 : : #define TIM_BUCKET_CHUNK_REMAIN \
74 : : (TIM_BUCKET_W1_M_CHUNK_REMAINDER << TIM_BUCKET_W1_S_CHUNK_REMAINDER)
75 : :
76 : : #define TIM_BUCKET_LOCK (TIM_BUCKET_W1_M_LOCK << TIM_BUCKET_W1_S_LOCK)
77 : :
78 : : #define TIM_BUCKET_SEMA_WLOCK \
79 : : (TIM_BUCKET_CHUNK_REMAIN | (1ull << TIM_BUCKET_W1_S_LOCK))
80 : :
81 : : typedef void (*cnxk_sso_set_priv_mem_t)(const struct rte_eventdev *event_dev,
82 : : void *lookup_mem);
83 : :
84 : : struct cnxk_tim_ctl {
85 : : uint16_t ring;
86 : : uint16_t chunk_slots;
87 : : uint16_t disable_npa;
88 : : uint16_t enable_stats;
89 : : };
90 : :
91 : : struct cnxk_tim_evdev {
92 : : struct roc_tim tim;
93 : : struct rte_eventdev *event_dev;
94 : : uint16_t nb_rings;
95 : : uint32_t chunk_sz;
96 : : /* Dev args */
97 : : uint8_t disable_npa;
98 : : uint32_t chunk_slots;
99 : : uint32_t min_ring_cnt;
100 : : uint8_t enable_stats;
101 : : uint16_t ring_ctl_cnt;
102 : : uint64_t ext_clk_freq[ROC_TIM_CLK_SRC_INVALID];
103 : : struct cnxk_tim_ctl *ring_ctl_data;
104 : : };
105 : :
106 : : struct cnxk_tim_bkt {
107 : : uint64_t first_chunk;
108 : : union {
109 : : uint64_t __rte_atomic w1;
110 : : struct {
111 : : uint32_t __rte_atomic nb_entry;
112 : : uint8_t sbt : 1;
113 : : uint8_t hbt : 1;
114 : : uint8_t bsk : 1;
115 : : uint8_t rsvd : 5;
116 : : uint8_t __rte_atomic lock;
117 : : int16_t __rte_atomic chunk_remainder;
118 : : };
119 : : };
120 : : uint64_t current_chunk;
121 : : uint64_t pad;
122 : : };
123 : :
124 : : struct __rte_cache_aligned cnxk_tim_ring {
125 : : uint16_t nb_chunk_slots;
126 : : uint32_t nb_bkts;
127 : : uintptr_t tbase;
128 : : uint64_t (*tick_fn)(uint64_t tbase);
129 : : uint64_t ring_start_cyc;
130 : : uint64_t lmt_base;
131 : : struct cnxk_tim_bkt *bkt;
132 : : struct rte_mempool *chunk_pool;
133 : : struct rte_reciprocal_u64 fast_div;
134 : : struct rte_reciprocal_u64 fast_bkt;
135 : : uint64_t tck_int;
136 : : uint64_t __rte_atomic arm_cnt;
137 : : uintptr_t base;
138 : : uint8_t prod_type_sp;
139 : : uint8_t enable_stats;
140 : : uint8_t disable_npa;
141 : : uint8_t ena_dfb;
142 : : uint8_t ena_periodic;
143 : : uint16_t ring_id;
144 : : uint32_t aura;
145 : : uint64_t nb_timers;
146 : : uint64_t tck_nsec;
147 : : uint64_t max_tout;
148 : : uint64_t nb_chunks;
149 : : uint64_t chunk_sz;
150 : : enum roc_tim_clk_src clk_src;
151 : : };
152 : :
153 : : struct cnxk_tim_ent {
154 : : uint64_t w0;
155 : : uint64_t wqe;
156 : : };
157 : :
158 : : static inline struct cnxk_tim_evdev *
159 : : cnxk_tim_priv_get(void)
160 : : {
161 : : const struct rte_memzone *mz;
162 : :
163 : 0 : mz = rte_memzone_lookup(RTE_STR(CNXK_TIM_EVDEV_NAME));
164 [ # # # # : 0 : if (mz == NULL)
# # # # #
# # # #
# ]
165 : : return NULL;
166 : :
167 [ # # # # : 0 : return mz->addr;
# # # # #
# # # ]
168 : : }
169 : :
170 : : static inline double
171 : : cnxk_tim_ns_per_tck(uint64_t freq)
172 : : {
173 : 0 : return (double)NSECPERSEC / freq;
174 : : }
175 : :
176 : : #ifdef RTE_ARCH_ARM64
177 : : static inline uint64_t
178 : : cnxk_tim_cntvct(uint64_t base __rte_unused)
179 : : {
180 : : uint64_t tsc;
181 : :
182 : : asm volatile("mrs %0, CNTVCT_EL0" : "=r"(tsc)::"memory");
183 : : return tsc;
184 : : }
185 : :
186 : : static inline uint64_t
187 : : cnxk_tim_cntfrq(void)
188 : : {
189 : : uint64_t freq;
190 : :
191 : : asm volatile("mrs %0, cntfrq_el0" : "=r"(freq));
192 : : return freq;
193 : : }
194 : : #else
195 : : static inline uint64_t
196 : 0 : cnxk_tim_cntvct(uint64_t base __rte_unused)
197 : : {
198 : 0 : return 0;
199 : : }
200 : :
201 : : static inline uint64_t
202 : : cnxk_tim_cntfrq(void)
203 : : {
204 : : return 0;
205 : : }
206 : : #endif
207 : :
208 : : static inline uint64_t
209 : 0 : cnxk_tim_tick_read(uint64_t tick_base)
210 : : {
211 : 0 : return plt_read64(tick_base);
212 : : }
213 : :
214 : : static inline enum roc_tim_clk_src
215 : : cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
216 : : {
217 : : switch (clk_src) {
218 : : case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
219 : : return ROC_TIM_CLK_SRC_GTI;
220 : : case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
221 : : return ROC_TIM_CLK_SRC_10NS;
222 : : case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
223 : : return ROC_TIM_CLK_SRC_GPIO;
224 : : case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
225 : : return ROC_TIM_CLK_SRC_PTP;
226 : : case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
227 : : return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
228 : : ROC_TIM_CLK_SRC_SYNCE;
229 : : default:
230 : : return ROC_TIM_CLK_SRC_INVALID;
231 : : }
232 : : }
233 : :
234 : : static inline uintptr_t
235 : 0 : cnxk_tim_get_tick_base(enum roc_tim_clk_src clk_src, uintptr_t base)
236 : : {
237 [ # # # # : 0 : switch (clk_src) {
# # # ]
238 : 0 : case ROC_TIM_CLK_SRC_GTI:
239 : 0 : return base + TIM_LF_FR_RN_GTI;
240 : 0 : case ROC_TIM_CLK_SRC_GPIO:
241 : 0 : return base + TIM_LF_FR_RN_GPIOS;
242 : 0 : case ROC_TIM_CLK_SRC_10NS:
243 : 0 : return base + TIM_LF_FR_RN_TENNS;
244 : 0 : case ROC_TIM_CLK_SRC_PTP:
245 : 0 : return base + TIM_LF_FR_RN_PTP;
246 : 0 : case ROC_TIM_CLK_SRC_SYNCE:
247 : 0 : return base + TIM_LF_FR_RN_SYNCE;
248 : 0 : case ROC_TIM_CLK_SRC_BTS:
249 : 0 : return base + TIM_LF_FR_RN_BTS;
250 : : default:
251 : : return ROC_TIM_CLK_SRC_INVALID;
252 : : }
253 : : }
254 : :
255 : : static inline int
256 : : cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
257 : : uint64_t *freq)
258 : : {
259 : : if (freq == NULL)
260 : : return -EINVAL;
261 : :
262 : : PLT_SET_USED(dev);
263 [ # # # # ]: 0 : switch (clk_src) {
264 : : case ROC_TIM_CLK_SRC_GTI:
265 : : *freq = cnxk_tim_cntfrq();
266 : : break;
267 : : case ROC_TIM_CLK_SRC_10NS:
268 : : *freq = 1E8;
269 : : break;
270 : 0 : case ROC_TIM_CLK_SRC_GPIO:
271 : : case ROC_TIM_CLK_SRC_PTP:
272 : : case ROC_TIM_CLK_SRC_SYNCE:
273 : 0 : *freq = dev->ext_clk_freq[clk_src];
274 : : break;
275 : : default:
276 : : return -EINVAL;
277 : : }
278 : :
279 : : return 0;
280 : : }
281 : :
282 : : #define TIM_ARM_FASTPATH_MODES \
283 : : FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP) \
284 : : FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP) \
285 : : FP(fb_sp, 0, 1, 0, CNXK_TIM_ENA_FB | CNXK_TIM_SP) \
286 : : FP(fb_mp, 0, 1, 1, CNXK_TIM_ENA_FB | CNXK_TIM_MP) \
287 : : FP(stats_sp, 1, 0, 0, \
288 : : CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB | CNXK_TIM_SP) \
289 : : FP(stats_mp, 1, 0, 1, \
290 : : CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB | CNXK_TIM_MP) \
291 : : FP(stats_fb_sp, 1, 1, 0, \
292 : : CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB | CNXK_TIM_SP) \
293 : : FP(stats_fb_mp, 1, 1, 1, \
294 : : CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB | CNXK_TIM_MP)
295 : :
296 : : #define TIM_ARM_TMO_FASTPATH_MODES \
297 : : FP(dfb, 0, 0, CNXK_TIM_ENA_DFB) \
298 : : FP(fb, 0, 1, CNXK_TIM_ENA_FB) \
299 : : FP(stats_dfb, 1, 0, CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB) \
300 : : FP(stats_fb, 1, 1, CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB)
301 : :
302 : : #define FP(_name, _f3, _f2, _f1, flags) \
303 : : uint16_t cnxk_tim_arm_burst_##_name( \
304 : : const struct rte_event_timer_adapter *adptr, \
305 : : struct rte_event_timer **tim, const uint16_t nb_timers);
306 : : TIM_ARM_FASTPATH_MODES
307 : : #undef FP
308 : :
309 : : #define FP(_name, _f2, _f1, flags) \
310 : : uint16_t cnxk_tim_arm_tmo_tick_burst_##_name( \
311 : : const struct rte_event_timer_adapter *adptr, \
312 : : struct rte_event_timer **tim, const uint64_t timeout_tick, \
313 : : const uint16_t nb_timers);
314 : : TIM_ARM_TMO_FASTPATH_MODES
315 : : #undef FP
316 : :
317 : : uint16_t cnxk_tim_arm_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
318 : : struct rte_event_timer **tim, const uint16_t nb_timers);
319 : :
320 : : uint16_t cnxk_tim_arm_tmo_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
321 : : struct rte_event_timer **tim, const uint64_t timeout_tick,
322 : : const uint16_t nb_timers);
323 : :
324 : : uint16_t
325 : : cnxk_tim_timer_cancel_burst(const struct rte_event_timer_adapter *adptr,
326 : : struct rte_event_timer **tim,
327 : : const uint16_t nb_timers);
328 : :
329 : : uint16_t cnxk_tim_timer_cancel_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
330 : : struct rte_event_timer **tim, const uint16_t nb_timers);
331 : :
332 : : int cnxk_tim_remaining_ticks_get(const struct rte_event_timer_adapter *adapter,
333 : : const struct rte_event_timer *evtim, uint64_t *ticks_remaining);
334 : :
335 : : int cnxk_tim_caps_get(const struct rte_eventdev *dev, uint64_t flags,
336 : : uint32_t *caps,
337 : : const struct event_timer_adapter_ops **ops,
338 : : cnxk_sso_set_priv_mem_t priv_mem_fn);
339 : :
340 : : void cnxk_tim_init(struct roc_sso *sso);
341 : : void cnxk_tim_fini(void);
342 : :
343 : : #endif /* __CNXK_TIM_EVDEV_H__ */
|