event/octeontx2: add timer adapter info function
[dpdk.git] / drivers / event / octeontx2 / otx2_tim_evdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_kvargs.h>
6 #include <rte_malloc.h>
7 #include <rte_mbuf_pool_ops.h>
8
9 #include "otx2_evdev.h"
10 #include "otx2_tim_evdev.h"
11
12 static struct rte_event_timer_adapter_ops otx2_tim_ops;
13
14 static inline int
15 tim_get_msix_offsets(void)
16 {
17         struct otx2_tim_evdev *dev = tim_priv_get();
18         struct otx2_mbox *mbox = dev->mbox;
19         struct msix_offset_rsp *msix_rsp;
20         int i, rc;
21
22         /* Get TIM MSIX vector offsets */
23         otx2_mbox_alloc_msg_msix_offset(mbox);
24         rc = otx2_mbox_process_msg(mbox, (void *)&msix_rsp);
25
26         for (i = 0; i < dev->nb_rings; i++)
27                 dev->tim_msixoff[i] = msix_rsp->timlf_msixoff[i];
28
29         return rc;
30 }
31
32 static void
33 otx2_tim_ring_info_get(const struct rte_event_timer_adapter *adptr,
34                        struct rte_event_timer_adapter_info *adptr_info)
35 {
36         struct otx2_tim_ring *tim_ring = adptr->data->adapter_priv;
37
38         adptr_info->max_tmo_ns = tim_ring->max_tout;
39         adptr_info->min_resolution_ns = tim_ring->tck_nsec;
40         rte_memcpy(&adptr_info->conf, &adptr->data->conf,
41                    sizeof(struct rte_event_timer_adapter_conf));
42 }
43
44 static void
45 tim_optimze_bkt_param(struct otx2_tim_ring *tim_ring)
46 {
47         uint64_t tck_nsec;
48         uint32_t hbkts;
49         uint32_t lbkts;
50
51         hbkts = rte_align32pow2(tim_ring->nb_bkts);
52         tck_nsec = RTE_ALIGN_MUL_CEIL(tim_ring->max_tout / (hbkts - 1), 10);
53
54         if ((tck_nsec < TICK2NSEC(OTX2_TIM_MIN_TMO_TKS,
55                                   tim_ring->tenns_clk_freq) ||
56             hbkts > OTX2_TIM_MAX_BUCKETS))
57                 hbkts = 0;
58
59         lbkts = rte_align32prevpow2(tim_ring->nb_bkts);
60         tck_nsec = RTE_ALIGN_MUL_CEIL((tim_ring->max_tout / (lbkts - 1)), 10);
61
62         if ((tck_nsec < TICK2NSEC(OTX2_TIM_MIN_TMO_TKS,
63                                   tim_ring->tenns_clk_freq) ||
64             lbkts > OTX2_TIM_MAX_BUCKETS))
65                 lbkts = 0;
66
67         if (!hbkts && !lbkts)
68                 return;
69
70         if (!hbkts) {
71                 tim_ring->nb_bkts = lbkts;
72                 goto end;
73         } else if (!lbkts) {
74                 tim_ring->nb_bkts = hbkts;
75                 goto end;
76         }
77
78         tim_ring->nb_bkts = (hbkts - tim_ring->nb_bkts) <
79                 (tim_ring->nb_bkts - lbkts) ? hbkts : lbkts;
80 end:
81         tim_ring->optimized = true;
82         tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL((tim_ring->max_tout /
83                                                 (tim_ring->nb_bkts - 1)), 10);
84         otx2_tim_dbg("Optimized configured values");
85         otx2_tim_dbg("Nb_bkts  : %" PRIu32 "", tim_ring->nb_bkts);
86         otx2_tim_dbg("Tck_nsec : %" PRIu64 "", tim_ring->tck_nsec);
87 }
88
89 static int
90 tim_chnk_pool_create(struct otx2_tim_ring *tim_ring,
91                      struct rte_event_timer_adapter_conf *rcfg)
92 {
93         unsigned int cache_sz = (tim_ring->nb_chunks / 1.5);
94         unsigned int mp_flags = 0;
95         char pool_name[25];
96         int rc;
97
98         /* Create chunk pool. */
99         if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_SP_PUT) {
100                 mp_flags = MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET;
101                 otx2_tim_dbg("Using single producer mode");
102                 tim_ring->prod_type_sp = true;
103         }
104
105         snprintf(pool_name, sizeof(pool_name), "otx2_tim_chunk_pool%d",
106                  tim_ring->ring_id);
107
108         if (cache_sz > RTE_MEMPOOL_CACHE_MAX_SIZE)
109                 cache_sz = RTE_MEMPOOL_CACHE_MAX_SIZE;
110
111         if (!tim_ring->disable_npa) {
112                 /* NPA need not have cache as free is not visible to SW */
113                 tim_ring->chunk_pool = rte_mempool_create_empty(pool_name,
114                                 tim_ring->nb_chunks, tim_ring->chunk_sz,
115                                 0, 0, rte_socket_id(), mp_flags);
116
117                 if (tim_ring->chunk_pool == NULL) {
118                         otx2_err("Unable to create chunkpool.");
119                         return -ENOMEM;
120                 }
121
122                 rc = rte_mempool_set_ops_byname(tim_ring->chunk_pool,
123                                                 rte_mbuf_platform_mempool_ops(),
124                                                 NULL);
125                 if (rc < 0) {
126                         otx2_err("Unable to set chunkpool ops");
127                         goto free;
128                 }
129
130                 rc = rte_mempool_populate_default(tim_ring->chunk_pool);
131                 if (rc < 0) {
132                         otx2_err("Unable to set populate chunkpool.");
133                         goto free;
134                 }
135                 tim_ring->aura = npa_lf_aura_handle_to_aura(
136                                 tim_ring->chunk_pool->pool_id);
137                 tim_ring->ena_dfb = 0;
138         } else {
139                 tim_ring->chunk_pool = rte_mempool_create(pool_name,
140                                 tim_ring->nb_chunks, tim_ring->chunk_sz,
141                                 cache_sz, 0, NULL, NULL, NULL, NULL,
142                                 rte_socket_id(),
143                                 mp_flags);
144                 if (tim_ring->chunk_pool == NULL) {
145                         otx2_err("Unable to create chunkpool.");
146                         return -ENOMEM;
147                 }
148                 tim_ring->ena_dfb = 1;
149         }
150
151         return 0;
152
153 free:
154         rte_mempool_free(tim_ring->chunk_pool);
155         return rc;
156 }
157
158 static void
159 tim_err_desc(int rc)
160 {
161         switch (rc) {
162         case TIM_AF_NO_RINGS_LEFT:
163                 otx2_err("Unable to allocat new TIM ring.");
164                 break;
165         case TIM_AF_INVALID_NPA_PF_FUNC:
166                 otx2_err("Invalid NPA pf func.");
167                 break;
168         case TIM_AF_INVALID_SSO_PF_FUNC:
169                 otx2_err("Invalid SSO pf func.");
170                 break;
171         case TIM_AF_RING_STILL_RUNNING:
172                 otx2_tim_dbg("Ring busy.");
173                 break;
174         case TIM_AF_LF_INVALID:
175                 otx2_err("Invalid Ring id.");
176                 break;
177         case TIM_AF_CSIZE_NOT_ALIGNED:
178                 otx2_err("Chunk size specified needs to be multiple of 16.");
179                 break;
180         case TIM_AF_CSIZE_TOO_SMALL:
181                 otx2_err("Chunk size too small.");
182                 break;
183         case TIM_AF_CSIZE_TOO_BIG:
184                 otx2_err("Chunk size too big.");
185                 break;
186         case TIM_AF_INTERVAL_TOO_SMALL:
187                 otx2_err("Bucket traversal interval too small.");
188                 break;
189         case TIM_AF_INVALID_BIG_ENDIAN_VALUE:
190                 otx2_err("Invalid Big endian value.");
191                 break;
192         case TIM_AF_INVALID_CLOCK_SOURCE:
193                 otx2_err("Invalid Clock source specified.");
194                 break;
195         case TIM_AF_GPIO_CLK_SRC_NOT_ENABLED:
196                 otx2_err("GPIO clock source not enabled.");
197                 break;
198         case TIM_AF_INVALID_BSIZE:
199                 otx2_err("Invalid bucket size.");
200                 break;
201         case TIM_AF_INVALID_ENABLE_PERIODIC:
202                 otx2_err("Invalid bucket size.");
203                 break;
204         case TIM_AF_INVALID_ENABLE_DONTFREE:
205                 otx2_err("Invalid Don't free value.");
206                 break;
207         case TIM_AF_ENA_DONTFRE_NSET_PERIODIC:
208                 otx2_err("Don't free bit not set when periodic is enabled.");
209                 break;
210         case TIM_AF_RING_ALREADY_DISABLED:
211                 otx2_err("Ring already stopped");
212                 break;
213         default:
214                 otx2_err("Unknown Error.");
215         }
216 }
217
218 static int
219 otx2_tim_ring_create(struct rte_event_timer_adapter *adptr)
220 {
221         struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
222         struct otx2_tim_evdev *dev = tim_priv_get();
223         struct otx2_tim_ring *tim_ring;
224         struct tim_config_req *cfg_req;
225         struct tim_ring_req *free_req;
226         struct tim_lf_alloc_req *req;
227         struct tim_lf_alloc_rsp *rsp;
228         uint64_t nb_timers;
229         int rc;
230
231         if (dev == NULL)
232                 return -ENODEV;
233
234         if (adptr->data->id >= dev->nb_rings)
235                 return -ENODEV;
236
237         req = otx2_mbox_alloc_msg_tim_lf_alloc(dev->mbox);
238         req->npa_pf_func = otx2_npa_pf_func_get();
239         req->sso_pf_func = otx2_sso_pf_func_get();
240         req->ring = adptr->data->id;
241
242         rc = otx2_mbox_process_msg(dev->mbox, (void **)&rsp);
243         if (rc < 0) {
244                 tim_err_desc(rc);
245                 return -ENODEV;
246         }
247
248         if (NSEC2TICK(RTE_ALIGN_MUL_CEIL(rcfg->timer_tick_ns, 10),
249                       rsp->tenns_clk) < OTX2_TIM_MIN_TMO_TKS) {
250                 if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)
251                         rcfg->timer_tick_ns = TICK2NSEC(OTX2_TIM_MIN_TMO_TKS,
252                                         rsp->tenns_clk);
253                 else {
254                         rc = -ERANGE;
255                         goto rng_mem_err;
256                 }
257         }
258
259         tim_ring = rte_zmalloc("otx2_tim_prv", sizeof(struct otx2_tim_ring), 0);
260         if (tim_ring == NULL) {
261                 rc =  -ENOMEM;
262                 goto rng_mem_err;
263         }
264
265         adptr->data->adapter_priv = tim_ring;
266
267         tim_ring->tenns_clk_freq = rsp->tenns_clk;
268         tim_ring->clk_src = (int)rcfg->clk_src;
269         tim_ring->ring_id = adptr->data->id;
270         tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(rcfg->timer_tick_ns, 10);
271         tim_ring->max_tout = rcfg->max_tmo_ns;
272         tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
273         tim_ring->chunk_sz = dev->chunk_sz;
274         nb_timers = rcfg->nb_timers;
275         tim_ring->disable_npa = dev->disable_npa;
276
277         tim_ring->nb_chunks = nb_timers / OTX2_TIM_NB_CHUNK_SLOTS(
278                                                         tim_ring->chunk_sz);
279         tim_ring->nb_chunk_slots = OTX2_TIM_NB_CHUNK_SLOTS(tim_ring->chunk_sz);
280
281         /* Try to optimize the bucket parameters. */
282         if ((rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)) {
283                 if (rte_is_power_of_2(tim_ring->nb_bkts))
284                         tim_ring->optimized = true;
285                 else
286                         tim_optimze_bkt_param(tim_ring);
287         }
288
289         tim_ring->nb_chunks = tim_ring->nb_chunks * tim_ring->nb_bkts;
290         /* Create buckets. */
291         tim_ring->bkt = rte_zmalloc("otx2_tim_bucket", (tim_ring->nb_bkts) *
292                                     sizeof(struct otx2_tim_bkt),
293                                     RTE_CACHE_LINE_SIZE);
294         if (tim_ring->bkt == NULL)
295                 goto bkt_mem_err;
296
297         rc = tim_chnk_pool_create(tim_ring, rcfg);
298         if (rc < 0)
299                 goto chnk_mem_err;
300
301         cfg_req = otx2_mbox_alloc_msg_tim_config_ring(dev->mbox);
302
303         cfg_req->ring = tim_ring->ring_id;
304         cfg_req->bigendian = false;
305         cfg_req->clocksource = tim_ring->clk_src;
306         cfg_req->enableperiodic = false;
307         cfg_req->enabledontfreebuffer = tim_ring->ena_dfb;
308         cfg_req->bucketsize = tim_ring->nb_bkts;
309         cfg_req->chunksize = tim_ring->chunk_sz;
310         cfg_req->interval = NSEC2TICK(tim_ring->tck_nsec,
311                                       tim_ring->tenns_clk_freq);
312
313         rc = otx2_mbox_process(dev->mbox);
314         if (rc < 0) {
315                 tim_err_desc(rc);
316                 goto chnk_mem_err;
317         }
318
319         tim_ring->base = dev->bar2 +
320                 (RVU_BLOCK_ADDR_TIM << 20 | tim_ring->ring_id << 12);
321
322         rc = tim_register_irq(tim_ring->ring_id);
323         if (rc < 0)
324                 goto chnk_mem_err;
325
326         otx2_write64((uint64_t)tim_ring->bkt,
327                      tim_ring->base + TIM_LF_RING_BASE);
328         otx2_write64(tim_ring->aura, tim_ring->base + TIM_LF_RING_AURA);
329
330         /* Update SSO xae count. */
331         sso_updt_xae_cnt(sso_pmd_priv(dev->event_dev), (void *)&nb_timers,
332                          RTE_EVENT_TYPE_TIMER);
333         sso_xae_reconfigure(dev->event_dev);
334
335         return rc;
336
337 chnk_mem_err:
338         rte_free(tim_ring->bkt);
339 bkt_mem_err:
340         rte_free(tim_ring);
341 rng_mem_err:
342         free_req = otx2_mbox_alloc_msg_tim_lf_free(dev->mbox);
343         free_req->ring = adptr->data->id;
344         otx2_mbox_process(dev->mbox);
345         return rc;
346 }
347
348 static int
349 otx2_tim_ring_free(struct rte_event_timer_adapter *adptr)
350 {
351         struct otx2_tim_ring *tim_ring = adptr->data->adapter_priv;
352         struct otx2_tim_evdev *dev = tim_priv_get();
353         struct tim_ring_req *req;
354         int rc;
355
356         if (dev == NULL)
357                 return -ENODEV;
358
359         tim_unregister_irq(tim_ring->ring_id);
360
361         req = otx2_mbox_alloc_msg_tim_lf_free(dev->mbox);
362         req->ring = tim_ring->ring_id;
363
364         rc = otx2_mbox_process(dev->mbox);
365         if (rc < 0) {
366                 tim_err_desc(rc);
367                 return -EBUSY;
368         }
369
370         rte_free(tim_ring->bkt);
371         rte_mempool_free(tim_ring->chunk_pool);
372         rte_free(adptr->data->adapter_priv);
373
374         return 0;
375 }
376
377 int
378 otx2_tim_caps_get(const struct rte_eventdev *evdev, uint64_t flags,
379                   uint32_t *caps,
380                   const struct rte_event_timer_adapter_ops **ops)
381 {
382         struct otx2_tim_evdev *dev = tim_priv_get();
383
384         RTE_SET_USED(flags);
385         if (dev == NULL)
386                 return -ENODEV;
387
388         otx2_tim_ops.init = otx2_tim_ring_create;
389         otx2_tim_ops.uninit = otx2_tim_ring_free;
390         otx2_tim_ops.get_info   = otx2_tim_ring_info_get;
391
392         /* Store evdev pointer for later use. */
393         dev->event_dev = (struct rte_eventdev *)(uintptr_t)evdev;
394         *caps = RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT;
395         *ops = &otx2_tim_ops;
396
397         return 0;
398 }
399
400 #define OTX2_TIM_DISABLE_NPA    "tim_disable_npa"
401 #define OTX2_TIM_CHNK_SLOTS     "tim_chnk_slots"
402
403 static void
404 tim_parse_devargs(struct rte_devargs *devargs, struct otx2_tim_evdev *dev)
405 {
406         struct rte_kvargs *kvlist;
407
408         if (devargs == NULL)
409                 return;
410
411         kvlist = rte_kvargs_parse(devargs->args, NULL);
412         if (kvlist == NULL)
413                 return;
414
415         rte_kvargs_process(kvlist, OTX2_TIM_DISABLE_NPA,
416                            &parse_kvargs_flag, &dev->disable_npa);
417         rte_kvargs_process(kvlist, OTX2_TIM_CHNK_SLOTS,
418                            &parse_kvargs_value, &dev->chunk_slots);
419 }
420
421 void
422 otx2_tim_init(struct rte_pci_device *pci_dev, struct otx2_dev *cmn_dev)
423 {
424         struct rsrc_attach_req *atch_req;
425         struct rsrc_detach_req *dtch_req;
426         struct free_rsrcs_rsp *rsrc_cnt;
427         const struct rte_memzone *mz;
428         struct otx2_tim_evdev *dev;
429         int rc;
430
431         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
432                 return;
433
434         mz = rte_memzone_reserve(RTE_STR(OTX2_TIM_EVDEV_NAME),
435                                  sizeof(struct otx2_tim_evdev),
436                                  rte_socket_id(), 0);
437         if (mz == NULL) {
438                 otx2_tim_dbg("Unable to allocate memory for TIM Event device");
439                 return;
440         }
441
442         dev = mz->addr;
443         dev->pci_dev = pci_dev;
444         dev->mbox = cmn_dev->mbox;
445         dev->bar2 = cmn_dev->bar2;
446
447         tim_parse_devargs(pci_dev->device.devargs, dev);
448
449         otx2_mbox_alloc_msg_free_rsrc_cnt(dev->mbox);
450         rc = otx2_mbox_process_msg(dev->mbox, (void *)&rsrc_cnt);
451         if (rc < 0) {
452                 otx2_err("Unable to get free rsrc count.");
453                 goto mz_free;
454         }
455
456         dev->nb_rings = rsrc_cnt->tim;
457
458         if (!dev->nb_rings) {
459                 otx2_tim_dbg("No TIM Logical functions provisioned.");
460                 goto mz_free;
461         }
462
463         atch_req = otx2_mbox_alloc_msg_attach_resources(dev->mbox);
464         atch_req->modify = true;
465         atch_req->timlfs = dev->nb_rings;
466
467         rc = otx2_mbox_process(dev->mbox);
468         if (rc < 0) {
469                 otx2_err("Unable to attach TIM rings.");
470                 goto mz_free;
471         }
472
473         rc = tim_get_msix_offsets();
474         if (rc < 0) {
475                 otx2_err("Unable to get MSIX offsets for TIM.");
476                 goto detach;
477         }
478
479         if (dev->chunk_slots &&
480             dev->chunk_slots <= OTX2_TIM_MAX_CHUNK_SLOTS &&
481             dev->chunk_slots >= OTX2_TIM_MIN_CHUNK_SLOTS) {
482                 dev->chunk_sz = (dev->chunk_slots + 1) *
483                         OTX2_TIM_CHUNK_ALIGNMENT;
484         } else {
485                 dev->chunk_sz = OTX2_TIM_RING_DEF_CHUNK_SZ;
486         }
487
488         return;
489
490 detach:
491         dtch_req = otx2_mbox_alloc_msg_detach_resources(dev->mbox);
492         dtch_req->partial = true;
493         dtch_req->timlfs = true;
494
495         otx2_mbox_process(dev->mbox);
496 mz_free:
497         rte_memzone_free(mz);
498 }
499
500 void
501 otx2_tim_fini(void)
502 {
503         struct otx2_tim_evdev *dev = tim_priv_get();
504         struct rsrc_detach_req *dtch_req;
505
506         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
507                 return;
508
509         dtch_req = otx2_mbox_alloc_msg_detach_resources(dev->mbox);
510         dtch_req->partial = true;
511         dtch_req->timlfs = true;
512
513         otx2_mbox_process(dev->mbox);
514         rte_memzone_free(rte_memzone_lookup(RTE_STR(OTX2_TIM_EVDEV_NAME)));
515 }