xref: /dpdk/drivers/common/cnxk/roc_tim.c (revision 29fd052d)
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 }
345