xref: /dpdk/drivers/event/cnxk/cnxk_tim_evdev.h (revision 5f6bc8a4)
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 
19 #include "roc_api.h"
20 
21 #define NSECPERSEC		 1E9
22 #define USECPERSEC		 1E6
23 #define TICK2NSEC(__tck, __freq) (((__tck)*NSECPERSEC) / (__freq))
24 
25 #define CNXK_TIM_EVDEV_NAME	    cnxk_tim_eventdev
26 #define CNXK_TIM_MAX_BUCKETS	    (0xFFFFF)
27 #define CNXK_TIM_RING_DEF_CHUNK_SZ  (4096)
28 #define CNXK_TIM_CHUNK_ALIGNMENT    (16)
29 #define CNXK_TIM_MAX_BURST	    \
30 			(RTE_CACHE_LINE_SIZE / CNXK_TIM_CHUNK_ALIGNMENT)
31 #define CNXK_TIM_NB_CHUNK_SLOTS(sz) (((sz) / CNXK_TIM_CHUNK_ALIGNMENT) - 1)
32 #define CNXK_TIM_MIN_CHUNK_SLOTS    (0x1)
33 #define CNXK_TIM_MAX_CHUNK_SLOTS    (0x1FFE)
34 #define CNXK_TIM_MAX_POOL_CACHE_SZ  (128)
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 struct cnxk_tim_ctl {
82 	uint16_t ring;
83 	uint16_t chunk_slots;
84 	uint16_t disable_npa;
85 	uint16_t enable_stats;
86 };
87 
88 struct cnxk_tim_evdev {
89 	struct roc_tim tim;
90 	struct rte_eventdev *event_dev;
91 	uint16_t nb_rings;
92 	uint32_t chunk_sz;
93 	/* Dev args */
94 	uint8_t disable_npa;
95 	uint32_t chunk_slots;
96 	uint32_t min_ring_cnt;
97 	uint8_t enable_stats;
98 	uint16_t ring_ctl_cnt;
99 	uint64_t ext_clk_freq[ROC_TIM_CLK_SRC_INVALID];
100 	struct cnxk_tim_ctl *ring_ctl_data;
101 };
102 
103 struct cnxk_tim_bkt {
104 	uint64_t first_chunk;
105 	union {
106 		uint64_t w1;
107 		struct {
108 			uint32_t nb_entry;
109 			uint8_t sbt : 1;
110 			uint8_t hbt : 1;
111 			uint8_t bsk : 1;
112 			uint8_t rsvd : 5;
113 			uint8_t lock;
114 			int16_t chunk_remainder;
115 		};
116 	};
117 	uint64_t current_chunk;
118 	uint64_t pad;
119 };
120 
121 struct cnxk_tim_ring {
122 	uintptr_t base;
123 	uint16_t nb_chunk_slots;
124 	uint32_t nb_bkts;
125 	uint64_t last_updt_cyc;
126 	uint64_t ring_start_cyc;
127 	uint64_t tck_int;
128 	uint64_t tot_int;
129 	struct cnxk_tim_bkt *bkt;
130 	struct rte_mempool *chunk_pool;
131 	struct rte_reciprocal_u64 fast_div;
132 	struct rte_reciprocal_u64 fast_bkt;
133 	uint64_t arm_cnt;
134 	uint8_t prod_type_sp;
135 	uint8_t enable_stats;
136 	uint8_t disable_npa;
137 	uint8_t ena_dfb;
138 	uint8_t ena_periodic;
139 	uint16_t ring_id;
140 	uint32_t aura;
141 	uint64_t nb_timers;
142 	uint64_t tck_nsec;
143 	uint64_t max_tout;
144 	uint64_t nb_chunks;
145 	uint64_t chunk_sz;
146 	enum roc_tim_clk_src clk_src;
147 } __rte_cache_aligned;
148 
149 struct cnxk_tim_ent {
150 	uint64_t w0;
151 	uint64_t wqe;
152 };
153 
154 static inline struct cnxk_tim_evdev *
cnxk_tim_priv_get(void)155 cnxk_tim_priv_get(void)
156 {
157 	const struct rte_memzone *mz;
158 
159 	mz = rte_memzone_lookup(RTE_STR(CNXK_TIM_EVDEV_NAME));
160 	if (mz == NULL)
161 		return NULL;
162 
163 	return mz->addr;
164 }
165 
166 static inline long double
cnxk_tim_ns_per_tck(uint64_t freq)167 cnxk_tim_ns_per_tck(uint64_t freq)
168 {
169 	return (long double)NSECPERSEC / freq;
170 }
171 
172 #ifdef RTE_ARCH_ARM64
173 static inline uint64_t
cnxk_tim_cntvct(void)174 cnxk_tim_cntvct(void)
175 {
176 	uint64_t tsc;
177 
178 	asm volatile("mrs %0, cntvct_el0" : "=r"(tsc));
179 	return tsc;
180 }
181 
182 static inline uint64_t
cnxk_tim_cntfrq(void)183 cnxk_tim_cntfrq(void)
184 {
185 	uint64_t freq;
186 
187 	asm volatile("mrs %0, cntfrq_el0" : "=r"(freq));
188 	return freq;
189 }
190 #else
191 static inline uint64_t
cnxk_tim_cntvct(void)192 cnxk_tim_cntvct(void)
193 {
194 	return 0;
195 }
196 
197 static inline uint64_t
cnxk_tim_cntfrq(void)198 cnxk_tim_cntfrq(void)
199 {
200 	return 0;
201 }
202 #endif
203 
204 static inline enum roc_tim_clk_src
cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)205 cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
206 {
207 	switch (clk_src) {
208 	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
209 		return ROC_TIM_CLK_SRC_GTI;
210 	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
211 		return ROC_TIM_CLK_SRC_10NS;
212 	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
213 		return ROC_TIM_CLK_SRC_GPIO;
214 	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
215 		return ROC_TIM_CLK_SRC_PTP;
216 	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
217 		return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
218 						      ROC_TIM_CLK_SRC_SYNCE;
219 	default:
220 		return ROC_TIM_CLK_SRC_INVALID;
221 	}
222 }
223 
224 static inline int
cnxk_tim_get_clk_freq(struct cnxk_tim_evdev * dev,enum roc_tim_clk_src clk_src,uint64_t * freq)225 cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
226 		      uint64_t *freq)
227 {
228 	if (freq == NULL)
229 		return -EINVAL;
230 
231 	PLT_SET_USED(dev);
232 	switch (clk_src) {
233 	case ROC_TIM_CLK_SRC_GTI:
234 		*freq = cnxk_tim_cntfrq();
235 		break;
236 	case ROC_TIM_CLK_SRC_10NS:
237 		*freq = 1E8;
238 		break;
239 	case ROC_TIM_CLK_SRC_GPIO:
240 	case ROC_TIM_CLK_SRC_PTP:
241 	case ROC_TIM_CLK_SRC_SYNCE:
242 		*freq = dev->ext_clk_freq[clk_src];
243 		break;
244 	default:
245 		return -EINVAL;
246 	}
247 
248 	return 0;
249 }
250 
251 #define TIM_ARM_FASTPATH_MODES                                                 \
252 	FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                        \
253 	FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                        \
254 	FP(fb_sp, 0, 1, 0, CNXK_TIM_ENA_FB | CNXK_TIM_SP)                      \
255 	FP(fb_mp, 0, 1, 1, CNXK_TIM_ENA_FB | CNXK_TIM_MP)                      \
256 	FP(stats_sp, 1, 0, 0,                                                  \
257 	   CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                \
258 	FP(stats_mp, 1, 0, 1,                                                  \
259 	   CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                \
260 	FP(stats_fb_sp, 1, 1, 0,                                               \
261 	   CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB | CNXK_TIM_SP)                 \
262 	FP(stats_fb_mp, 1, 1, 1,                                               \
263 	   CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB | CNXK_TIM_MP)
264 
265 #define TIM_ARM_TMO_FASTPATH_MODES                                             \
266 	FP(dfb, 0, 0, CNXK_TIM_ENA_DFB)                                        \
267 	FP(fb, 0, 1, CNXK_TIM_ENA_FB)                                          \
268 	FP(stats_dfb, 1, 0, CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB)             \
269 	FP(stats_fb, 1, 1, CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB)
270 
271 #define FP(_name, _f3, _f2, _f1, flags)                                        \
272 	uint16_t cnxk_tim_arm_burst_##_name(                                   \
273 		const struct rte_event_timer_adapter *adptr,                   \
274 		struct rte_event_timer **tim, const uint16_t nb_timers);
275 TIM_ARM_FASTPATH_MODES
276 #undef FP
277 
278 #define FP(_name, _f2, _f1, flags)                                             \
279 	uint16_t cnxk_tim_arm_tmo_tick_burst_##_name(                          \
280 		const struct rte_event_timer_adapter *adptr,                   \
281 		struct rte_event_timer **tim, const uint64_t timeout_tick,     \
282 		const uint16_t nb_timers);
283 TIM_ARM_TMO_FASTPATH_MODES
284 #undef FP
285 
286 uint16_t
287 cnxk_tim_timer_cancel_burst(const struct rte_event_timer_adapter *adptr,
288 			    struct rte_event_timer **tim,
289 			    const uint16_t nb_timers);
290 
291 int cnxk_tim_caps_get(const struct rte_eventdev *dev, uint64_t flags,
292 		      uint32_t *caps,
293 		      const struct event_timer_adapter_ops **ops);
294 
295 void cnxk_tim_init(struct roc_sso *sso);
296 void cnxk_tim_fini(void);
297 
298 #endif /* __CNXK_TIM_EVDEV_H__ */
299