1fb17f571d97f7732feb0fb9399e6ae73f193fc3
[dpdk.git] / drivers / event / cnxk / cnxk_tim_evdev.h
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
44 #define CNXK_TIM_SP        0x1
45 #define CNXK_TIM_MP        0x2
46 #define CNXK_TIM_ENA_FB    0x10
47 #define CNXK_TIM_ENA_DFB   0x20
48 #define CNXK_TIM_ENA_STATS 0x40
49
50 #define TIM_BUCKET_W1_S_CHUNK_REMAINDER (48)
51 #define TIM_BUCKET_W1_M_CHUNK_REMAINDER                                        \
52         ((1ULL << (64 - TIM_BUCKET_W1_S_CHUNK_REMAINDER)) - 1)
53 #define TIM_BUCKET_W1_S_LOCK (40)
54 #define TIM_BUCKET_W1_M_LOCK                                                   \
55         ((1ULL << (TIM_BUCKET_W1_S_CHUNK_REMAINDER - TIM_BUCKET_W1_S_LOCK)) - 1)
56 #define TIM_BUCKET_W1_S_RSVD (35)
57 #define TIM_BUCKET_W1_S_BSK  (34)
58 #define TIM_BUCKET_W1_M_BSK                                                    \
59         ((1ULL << (TIM_BUCKET_W1_S_RSVD - TIM_BUCKET_W1_S_BSK)) - 1)
60 #define TIM_BUCKET_W1_S_HBT (33)
61 #define TIM_BUCKET_W1_M_HBT                                                    \
62         ((1ULL << (TIM_BUCKET_W1_S_BSK - TIM_BUCKET_W1_S_HBT)) - 1)
63 #define TIM_BUCKET_W1_S_SBT (32)
64 #define TIM_BUCKET_W1_M_SBT                                                    \
65         ((1ULL << (TIM_BUCKET_W1_S_HBT - TIM_BUCKET_W1_S_SBT)) - 1)
66 #define TIM_BUCKET_W1_S_NUM_ENTRIES (0)
67 #define TIM_BUCKET_W1_M_NUM_ENTRIES                                            \
68         ((1ULL << (TIM_BUCKET_W1_S_SBT - TIM_BUCKET_W1_S_NUM_ENTRIES)) - 1)
69
70 #define TIM_BUCKET_SEMA (TIM_BUCKET_CHUNK_REMAIN)
71
72 #define TIM_BUCKET_CHUNK_REMAIN                                                \
73         (TIM_BUCKET_W1_M_CHUNK_REMAINDER << TIM_BUCKET_W1_S_CHUNK_REMAINDER)
74
75 #define TIM_BUCKET_LOCK (TIM_BUCKET_W1_M_LOCK << TIM_BUCKET_W1_S_LOCK)
76
77 #define TIM_BUCKET_SEMA_WLOCK                                                  \
78         (TIM_BUCKET_CHUNK_REMAIN | (1ull << TIM_BUCKET_W1_S_LOCK))
79
80 struct cnxk_tim_ctl {
81         uint16_t ring;
82         uint16_t chunk_slots;
83         uint16_t disable_npa;
84         uint16_t enable_stats;
85 };
86
87 struct cnxk_tim_evdev {
88         struct roc_tim tim;
89         struct rte_eventdev *event_dev;
90         uint16_t nb_rings;
91         uint32_t chunk_sz;
92         /* Dev args */
93         uint8_t disable_npa;
94         uint32_t chunk_slots;
95         uint32_t min_ring_cnt;
96         uint8_t enable_stats;
97         uint16_t ring_ctl_cnt;
98         struct cnxk_tim_ctl *ring_ctl_data;
99 };
100
101 struct cnxk_tim_bkt {
102         uint64_t first_chunk;
103         union {
104                 uint64_t w1;
105                 struct {
106                         uint32_t nb_entry;
107                         uint8_t sbt : 1;
108                         uint8_t hbt : 1;
109                         uint8_t bsk : 1;
110                         uint8_t rsvd : 5;
111                         uint8_t lock;
112                         int16_t chunk_remainder;
113                 };
114         };
115         uint64_t current_chunk;
116         uint64_t pad;
117 };
118
119 struct cnxk_tim_ring {
120         uintptr_t base;
121         uint16_t nb_chunk_slots;
122         uint32_t nb_bkts;
123         uint64_t last_updt_cyc;
124         uint64_t ring_start_cyc;
125         uint64_t tck_int;
126         uint64_t tot_int;
127         struct cnxk_tim_bkt *bkt;
128         struct rte_mempool *chunk_pool;
129         struct rte_reciprocal_u64 fast_div;
130         struct rte_reciprocal_u64 fast_bkt;
131         uint64_t arm_cnt;
132         uint8_t prod_type_sp;
133         uint8_t enable_stats;
134         uint8_t disable_npa;
135         uint8_t ena_dfb;
136         uint16_t ring_id;
137         uint32_t aura;
138         uint64_t nb_timers;
139         uint64_t tck_nsec;
140         uint64_t max_tout;
141         uint64_t nb_chunks;
142         uint64_t chunk_sz;
143         enum roc_tim_clk_src clk_src;
144 } __rte_cache_aligned;
145
146 struct cnxk_tim_ent {
147         uint64_t w0;
148         uint64_t wqe;
149 };
150
151 static inline struct cnxk_tim_evdev *
152 cnxk_tim_priv_get(void)
153 {
154         const struct rte_memzone *mz;
155
156         mz = rte_memzone_lookup(RTE_STR(CNXK_TIM_EVDEV_NAME));
157         if (mz == NULL)
158                 return NULL;
159
160         return mz->addr;
161 }
162
163 static inline long double
164 cnxk_tim_ns_per_tck(uint64_t freq)
165 {
166         return (long double)NSECPERSEC / freq;
167 }
168
169 #ifdef RTE_ARCH_ARM64
170 static inline uint64_t
171 cnxk_tim_cntvct(void)
172 {
173         uint64_t tsc;
174
175         asm volatile("mrs %0, cntvct_el0" : "=r"(tsc));
176         return tsc;
177 }
178
179 static inline uint64_t
180 cnxk_tim_cntfrq(void)
181 {
182         uint64_t freq;
183
184         asm volatile("mrs %0, cntfrq_el0" : "=r"(freq));
185         return freq;
186 }
187 #else
188 static inline uint64_t
189 cnxk_tim_cntvct(void)
190 {
191         return 0;
192 }
193
194 static inline uint64_t
195 cnxk_tim_cntfrq(void)
196 {
197         return 0;
198 }
199 #endif
200
201 static inline enum roc_tim_clk_src
202 cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
203 {
204         switch (clk_src) {
205         case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
206                 return ROC_TIM_CLK_SRC_GTI;
207         case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
208                 return ROC_TIM_CLK_SRC_10NS;
209         case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
210                 return ROC_TIM_CLK_SRC_GPIO;
211         case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
212                 return ROC_TIM_CLK_SRC_PTP;
213         case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
214                 return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
215                                                       ROC_TIM_CLK_SRC_SYNCE;
216         default:
217                 return ROC_TIM_CLK_SRC_INVALID;
218         }
219 }
220
221 static inline int
222 cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
223                       uint64_t *freq)
224 {
225         if (freq == NULL)
226                 return -EINVAL;
227
228         PLT_SET_USED(dev);
229         switch (clk_src) {
230         case ROC_TIM_CLK_SRC_GTI:
231                 *freq = cnxk_tim_cntfrq();
232                 break;
233         case ROC_TIM_CLK_SRC_10NS:
234                 *freq = 1E8;
235                 break;
236         case ROC_TIM_CLK_SRC_GPIO:
237         case ROC_TIM_CLK_SRC_PTP:
238         case ROC_TIM_CLK_SRC_SYNCE:
239         default:
240                 return -EINVAL;
241         }
242
243         return 0;
244 }
245
246 #define TIM_ARM_FASTPATH_MODES                                                 \
247         FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                        \
248         FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                        \
249         FP(fb_sp, 0, 1, 0, CNXK_TIM_ENA_FB | CNXK_TIM_SP)                      \
250         FP(fb_mp, 0, 1, 1, CNXK_TIM_ENA_FB | CNXK_TIM_MP)                      \
251         FP(stats_sp, 1, 0, 0,                                                  \
252            CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                \
253         FP(stats_mp, 1, 0, 1,                                                  \
254            CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                \
255         FP(stats_fb_sp, 1, 1, 0,                                               \
256            CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB | CNXK_TIM_SP)                 \
257         FP(stats_fb_mp, 1, 1, 1,                                               \
258            CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB | CNXK_TIM_MP)
259
260 #define TIM_ARM_TMO_FASTPATH_MODES                                             \
261         FP(dfb, 0, 0, CNXK_TIM_ENA_DFB)                                        \
262         FP(fb, 0, 1, CNXK_TIM_ENA_FB)                                          \
263         FP(stats_dfb, 1, 0, CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_DFB)             \
264         FP(stats_fb, 1, 1, CNXK_TIM_ENA_STATS | CNXK_TIM_ENA_FB)
265
266 #define FP(_name, _f3, _f2, _f1, flags)                                        \
267         uint16_t cnxk_tim_arm_burst_##_name(                                   \
268                 const struct rte_event_timer_adapter *adptr,                   \
269                 struct rte_event_timer **tim, const uint16_t nb_timers);
270 TIM_ARM_FASTPATH_MODES
271 #undef FP
272
273 #define FP(_name, _f2, _f1, flags)                                             \
274         uint16_t cnxk_tim_arm_tmo_tick_burst_##_name(                          \
275                 const struct rte_event_timer_adapter *adptr,                   \
276                 struct rte_event_timer **tim, const uint64_t timeout_tick,     \
277                 const uint16_t nb_timers);
278 TIM_ARM_TMO_FASTPATH_MODES
279 #undef FP
280
281 uint16_t
282 cnxk_tim_timer_cancel_burst(const struct rte_event_timer_adapter *adptr,
283                             struct rte_event_timer **tim,
284                             const uint16_t nb_timers);
285
286 int cnxk_tim_caps_get(const struct rte_eventdev *dev, uint64_t flags,
287                       uint32_t *caps,
288                       const struct event_timer_adapter_ops **ops);
289
290 void cnxk_tim_init(struct roc_sso *sso);
291 void cnxk_tim_fini(void);
292
293 #endif /* __CNXK_TIM_EVDEV_H__ */