common/cnxk: add ROC errata list
[dpdk.git] / drivers / common / cnxk / roc_tim.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "roc_api.h"
6 #include "roc_priv.h"
7
8 static int
9 tim_fill_msix(struct roc_tim *roc_tim, uint16_t nb_ring)
10 {
11         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
12         struct tim *tim = roc_tim_to_tim_priv(roc_tim);
13         struct msix_offset_rsp *rsp;
14         int i, rc;
15
16         mbox_alloc_msg_msix_offset(dev->mbox);
17         rc = mbox_process_msg(dev->mbox, (void **)&rsp);
18         if (rc < 0)
19                 return rc;
20
21         for (i = 0; i < nb_ring; i++)
22                 tim->tim_msix_offsets[i] = rsp->timlf_msixoff[i];
23
24         return 0;
25 }
26
27 static void
28 tim_err_desc(int rc)
29 {
30         switch (rc) {
31         case TIM_AF_NO_RINGS_LEFT:
32                 plt_err("Unable to allocate new TIM ring.");
33                 break;
34         case TIM_AF_INVALID_NPA_PF_FUNC:
35                 plt_err("Invalid NPA pf func.");
36                 break;
37         case TIM_AF_INVALID_SSO_PF_FUNC:
38                 plt_err("Invalid SSO pf func.");
39                 break;
40         case TIM_AF_RING_STILL_RUNNING:
41                 plt_err("Ring busy.");
42                 break;
43         case TIM_AF_LF_INVALID:
44                 plt_err("Invalid Ring id.");
45                 break;
46         case TIM_AF_CSIZE_NOT_ALIGNED:
47                 plt_err("Chunk size specified needs to be multiple of 16.");
48                 break;
49         case TIM_AF_CSIZE_TOO_SMALL:
50                 plt_err("Chunk size too small.");
51                 break;
52         case TIM_AF_CSIZE_TOO_BIG:
53                 plt_err("Chunk size too big.");
54                 break;
55         case TIM_AF_INTERVAL_TOO_SMALL:
56                 plt_err("Bucket traversal interval too small.");
57                 break;
58         case TIM_AF_INVALID_BIG_ENDIAN_VALUE:
59                 plt_err("Invalid Big endian value.");
60                 break;
61         case TIM_AF_INVALID_CLOCK_SOURCE:
62                 plt_err("Invalid Clock source specified.");
63                 break;
64         case TIM_AF_GPIO_CLK_SRC_NOT_ENABLED:
65                 plt_err("GPIO clock source not enabled.");
66                 break;
67         case TIM_AF_INVALID_BSIZE:
68                 plt_err("Invalid bucket size.");
69                 break;
70         case TIM_AF_INVALID_ENABLE_PERIODIC:
71                 plt_err("Invalid bucket size.");
72                 break;
73         case TIM_AF_INVALID_ENABLE_DONTFREE:
74                 plt_err("Invalid Don't free value.");
75                 break;
76         case TIM_AF_ENA_DONTFRE_NSET_PERIODIC:
77                 plt_err("Don't free bit not set when periodic is enabled.");
78                 break;
79         case TIM_AF_RING_ALREADY_DISABLED:
80                 plt_err("Ring already stopped");
81                 break;
82         default:
83                 plt_err("Unknown Error.");
84         }
85 }
86
87 int
88 roc_tim_lf_enable(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *start_tsc,
89                   uint32_t *cur_bkt)
90 {
91         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
92         struct tim_enable_rsp *rsp;
93         struct tim_ring_req *req;
94         int rc = -ENOSPC;
95
96         req = mbox_alloc_msg_tim_enable_ring(dev->mbox);
97         if (req == NULL)
98                 return rc;
99         req->ring = ring_id;
100
101         rc = mbox_process_msg(dev->mbox, (void **)&rsp);
102         if (rc < 0) {
103                 tim_err_desc(rc);
104                 return rc;
105         }
106
107         if (cur_bkt)
108                 *cur_bkt = rsp->currentbucket;
109         if (start_tsc)
110                 *start_tsc = rsp->timestarted;
111
112         return 0;
113 }
114
115 int
116 roc_tim_lf_disable(struct roc_tim *roc_tim, uint8_t ring_id)
117 {
118         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
119         struct tim_ring_req *req;
120         int rc = -ENOSPC;
121
122         req = mbox_alloc_msg_tim_disable_ring(dev->mbox);
123         if (req == NULL)
124                 return rc;
125         req->ring = ring_id;
126
127         rc = mbox_process(dev->mbox);
128         if (rc < 0) {
129                 tim_err_desc(rc);
130                 return rc;
131         }
132
133         return 0;
134 }
135
136 uintptr_t
137 roc_tim_lf_base_get(struct roc_tim *roc_tim, uint8_t ring_id)
138 {
139         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
140
141         return dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12);
142 }
143
144 int
145 roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
146                   enum roc_tim_clk_src clk_src, uint8_t ena_periodic,
147                   uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz,
148                   uint32_t interval, uint64_t intervalns, uint64_t clockfreq)
149 {
150         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
151         struct tim_config_req *req;
152         int rc = -ENOSPC;
153
154         req = mbox_alloc_msg_tim_config_ring(dev->mbox);
155         if (req == NULL)
156                 return rc;
157         req->ring = ring_id;
158         req->bigendian = false;
159         req->bucketsize = bucket_sz;
160         req->chunksize = chunk_sz;
161         req->clocksource = clk_src;
162         req->enableperiodic = ena_periodic;
163         req->enabledontfreebuffer = ena_dfb;
164         req->interval = interval;
165         req->intervalns = intervalns;
166         req->clockfreq = clockfreq;
167         req->gpioedge = TIM_GPIO_LTOH_TRANS;
168
169         rc = mbox_process(dev->mbox);
170         if (rc < 0) {
171                 tim_err_desc(rc);
172                 return rc;
173         }
174
175         return 0;
176 }
177
178 int
179 roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src,
180                     uint64_t clockfreq, uint64_t *intervalns,
181                     uint64_t *interval)
182 {
183         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
184         struct tim_intvl_req *req;
185         struct tim_intvl_rsp *rsp;
186         int rc = -ENOSPC;
187
188         req = mbox_alloc_msg_tim_get_min_intvl(dev->mbox);
189         if (req == NULL)
190                 return rc;
191
192         req->clockfreq = clockfreq;
193         req->clocksource = clk_src;
194         rc = mbox_process_msg(dev->mbox, (void **)&rsp);
195         if (rc < 0) {
196                 tim_err_desc(rc);
197                 return rc;
198         }
199
200         *intervalns = rsp->intvl_ns;
201         *interval = rsp->intvl_cyc;
202
203         return 0;
204 }
205
206 int
207 roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
208 {
209         struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
210         struct tim *tim = roc_tim_to_tim_priv(roc_tim);
211         struct tim_ring_req *free_req;
212         struct tim_lf_alloc_req *req;
213         struct tim_lf_alloc_rsp *rsp;
214         struct dev *dev = &sso->dev;
215         int rc = -ENOSPC;
216
217         req = mbox_alloc_msg_tim_lf_alloc(dev->mbox);
218         if (req == NULL)
219                 return rc;
220         req->npa_pf_func = idev_npa_pffunc_get();
221         req->sso_pf_func = idev_sso_pffunc_get();
222         req->ring = ring_id;
223
224         rc = mbox_process_msg(dev->mbox, (void **)&rsp);
225         if (rc < 0) {
226                 tim_err_desc(rc);
227                 return rc;
228         }
229
230         if (clk)
231                 *clk = rsp->tenns_clk;
232
233         rc = tim_register_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id,
234                                    tim->tim_msix_offsets[ring_id]);
235         if (rc < 0) {
236                 plt_tim_dbg("Failed to register Ring[%d] IRQ", ring_id);
237                 free_req = mbox_alloc_msg_tim_lf_free(dev->mbox);
238                 if (free_req == NULL)
239                         return -ENOSPC;
240                 free_req->ring = ring_id;
241                 mbox_process(dev->mbox);
242         }
243
244         return rc;
245 }
246
247 int
248 roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id)
249 {
250         struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
251         struct tim *tim = roc_tim_to_tim_priv(roc_tim);
252         struct dev *dev = &sso->dev;
253         struct tim_ring_req *req;
254         int rc = -ENOSPC;
255
256         tim_unregister_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id,
257                                 tim->tim_msix_offsets[ring_id]);
258
259         req = mbox_alloc_msg_tim_lf_free(dev->mbox);
260         if (req == NULL)
261                 return rc;
262         req->ring = ring_id;
263
264         rc = mbox_process(dev->mbox);
265         if (rc < 0) {
266                 tim_err_desc(rc);
267                 return rc;
268         }
269
270         return 0;
271 }
272
273 int
274 roc_tim_init(struct roc_tim *roc_tim)
275 {
276         struct rsrc_attach_req *attach_req;
277         struct rsrc_detach_req *detach_req;
278         struct free_rsrcs_rsp *free_rsrc;
279         struct dev *dev;
280         uint16_t nb_lfs;
281         int rc;
282
283         if (roc_tim == NULL || roc_tim->roc_sso == NULL)
284                 return TIM_ERR_PARAM;
285
286         PLT_STATIC_ASSERT(sizeof(struct tim) <= TIM_MEM_SZ);
287         dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
288         nb_lfs = roc_tim->nb_lfs;
289         mbox_alloc_msg_free_rsrc_cnt(dev->mbox);
290         rc = mbox_process_msg(dev->mbox, (void *)&free_rsrc);
291         if (rc < 0) {
292                 plt_err("Unable to get free rsrc count.");
293                 return 0;
294         }
295
296         if (nb_lfs && (free_rsrc->tim < nb_lfs)) {
297                 plt_tim_dbg("Requested LFs : %d Available LFs : %d", nb_lfs,
298                             free_rsrc->tim);
299                 return 0;
300         }
301
302         attach_req = mbox_alloc_msg_attach_resources(dev->mbox);
303         if (attach_req == NULL)
304                 return -ENOSPC;
305         attach_req->modify = true;
306         attach_req->timlfs = nb_lfs ? nb_lfs : free_rsrc->tim;
307         nb_lfs = attach_req->timlfs;
308
309         rc = mbox_process(dev->mbox);
310         if (rc < 0) {
311                 plt_err("Unable to attach TIM LFs.");
312                 return 0;
313         }
314
315         rc = tim_fill_msix(roc_tim, nb_lfs);
316         if (rc < 0) {
317                 plt_err("Unable to get TIM MSIX vectors");
318
319                 detach_req = mbox_alloc_msg_detach_resources(dev->mbox);
320                 if (detach_req == NULL)
321                         return -ENOSPC;
322                 detach_req->partial = true;
323                 detach_req->timlfs = true;
324                 mbox_process(dev->mbox);
325
326                 return 0;
327         }
328
329         return nb_lfs;
330 }
331
332 void
333 roc_tim_fini(struct roc_tim *roc_tim)
334 {
335         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
336         struct rsrc_detach_req *detach_req;
337
338         detach_req = mbox_alloc_msg_detach_resources(dev->mbox);
339         PLT_ASSERT(detach_req);
340         detach_req->partial = true;
341         detach_req->timlfs = true;
342
343         mbox_process(dev->mbox);
344 }