xref: /dpdk/drivers/common/cnxk/roc_tim.c (revision 822d4ef519f66b4f1184a1e708ed758e44b99b3a)
1796e3668SPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause
2796e3668SPavan Nikhilesh  * Copyright(C) 2021 Marvell.
3796e3668SPavan Nikhilesh  */
4796e3668SPavan Nikhilesh 
5796e3668SPavan Nikhilesh #include "roc_api.h"
6796e3668SPavan Nikhilesh #include "roc_priv.h"
7796e3668SPavan Nikhilesh 
8f3c7b607SPavan Nikhilesh #define LF_ENABLE_RETRY_CNT 8
9f3c7b607SPavan Nikhilesh 
10309b553cSPavan Nikhilesh static int
11309b553cSPavan Nikhilesh tim_fill_msix(struct roc_tim *roc_tim, uint16_t nb_ring)
12309b553cSPavan Nikhilesh {
13be541d37SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
14309b553cSPavan Nikhilesh 	struct tim *tim = roc_tim_to_tim_priv(roc_tim);
15be541d37SPavan Nikhilesh 	struct dev *dev = &sso->dev;
16309b553cSPavan Nikhilesh 	struct msix_offset_rsp *rsp;
1744a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
18309b553cSPavan Nikhilesh 	int i, rc;
19309b553cSPavan Nikhilesh 
2044a9307cSRakesh Kudurumalla 	mbox_alloc_msg_msix_offset(mbox);
2144a9307cSRakesh Kudurumalla 	rc = mbox_process_msg(mbox, (void **)&rsp);
2244a9307cSRakesh Kudurumalla 	if (rc) {
2344a9307cSRakesh Kudurumalla 		rc = -EIO;
2444a9307cSRakesh Kudurumalla 		goto exit;
2544a9307cSRakesh Kudurumalla 	}
26309b553cSPavan Nikhilesh 
27309b553cSPavan Nikhilesh 	for (i = 0; i < nb_ring; i++)
28309b553cSPavan Nikhilesh 		tim->tim_msix_offsets[i] = rsp->timlf_msixoff[i];
29309b553cSPavan Nikhilesh 
3044a9307cSRakesh Kudurumalla 	rc = 0;
3144a9307cSRakesh Kudurumalla exit:
3244a9307cSRakesh Kudurumalla 	mbox_put(mbox);
3344a9307cSRakesh Kudurumalla 	return rc;
34309b553cSPavan Nikhilesh }
35309b553cSPavan Nikhilesh 
36796e3668SPavan Nikhilesh static void
37796e3668SPavan Nikhilesh tim_err_desc(int rc)
38796e3668SPavan Nikhilesh {
39796e3668SPavan Nikhilesh 	switch (rc) {
40796e3668SPavan Nikhilesh 	case TIM_AF_NO_RINGS_LEFT:
41796e3668SPavan Nikhilesh 		plt_err("Unable to allocate new TIM ring.");
42796e3668SPavan Nikhilesh 		break;
43796e3668SPavan Nikhilesh 	case TIM_AF_INVALID_NPA_PF_FUNC:
44796e3668SPavan Nikhilesh 		plt_err("Invalid NPA pf func.");
45796e3668SPavan Nikhilesh 		break;
46796e3668SPavan Nikhilesh 	case TIM_AF_INVALID_SSO_PF_FUNC:
47796e3668SPavan Nikhilesh 		plt_err("Invalid SSO pf func.");
48796e3668SPavan Nikhilesh 		break;
49796e3668SPavan Nikhilesh 	case TIM_AF_RING_STILL_RUNNING:
50796e3668SPavan Nikhilesh 		plt_err("Ring busy.");
51796e3668SPavan Nikhilesh 		break;
52796e3668SPavan Nikhilesh 	case TIM_AF_LF_INVALID:
53796e3668SPavan Nikhilesh 		plt_err("Invalid Ring id.");
54796e3668SPavan Nikhilesh 		break;
55796e3668SPavan Nikhilesh 	case TIM_AF_CSIZE_NOT_ALIGNED:
56796e3668SPavan Nikhilesh 		plt_err("Chunk size specified needs to be multiple of 16.");
57796e3668SPavan Nikhilesh 		break;
58796e3668SPavan Nikhilesh 	case TIM_AF_CSIZE_TOO_SMALL:
59796e3668SPavan Nikhilesh 		plt_err("Chunk size too small.");
60796e3668SPavan Nikhilesh 		break;
61796e3668SPavan Nikhilesh 	case TIM_AF_CSIZE_TOO_BIG:
62796e3668SPavan Nikhilesh 		plt_err("Chunk size too big.");
63796e3668SPavan Nikhilesh 		break;
64796e3668SPavan Nikhilesh 	case TIM_AF_INTERVAL_TOO_SMALL:
65796e3668SPavan Nikhilesh 		plt_err("Bucket traversal interval too small.");
66796e3668SPavan Nikhilesh 		break;
67796e3668SPavan Nikhilesh 	case TIM_AF_INVALID_BIG_ENDIAN_VALUE:
68796e3668SPavan Nikhilesh 		plt_err("Invalid Big endian value.");
69796e3668SPavan Nikhilesh 		break;
70796e3668SPavan Nikhilesh 	case TIM_AF_INVALID_CLOCK_SOURCE:
71796e3668SPavan Nikhilesh 		plt_err("Invalid Clock source specified.");
72796e3668SPavan Nikhilesh 		break;
73796e3668SPavan Nikhilesh 	case TIM_AF_GPIO_CLK_SRC_NOT_ENABLED:
74796e3668SPavan Nikhilesh 		plt_err("GPIO clock source not enabled.");
75796e3668SPavan Nikhilesh 		break;
76796e3668SPavan Nikhilesh 	case TIM_AF_INVALID_BSIZE:
77796e3668SPavan Nikhilesh 		plt_err("Invalid bucket size.");
78796e3668SPavan Nikhilesh 		break;
79796e3668SPavan Nikhilesh 	case TIM_AF_INVALID_ENABLE_PERIODIC:
80796e3668SPavan Nikhilesh 		plt_err("Invalid bucket size.");
81796e3668SPavan Nikhilesh 		break;
82796e3668SPavan Nikhilesh 	case TIM_AF_INVALID_ENABLE_DONTFREE:
83796e3668SPavan Nikhilesh 		plt_err("Invalid Don't free value.");
84796e3668SPavan Nikhilesh 		break;
85796e3668SPavan Nikhilesh 	case TIM_AF_ENA_DONTFRE_NSET_PERIODIC:
86796e3668SPavan Nikhilesh 		plt_err("Don't free bit not set when periodic is enabled.");
87796e3668SPavan Nikhilesh 		break;
88796e3668SPavan Nikhilesh 	case TIM_AF_RING_ALREADY_DISABLED:
89796e3668SPavan Nikhilesh 		plt_err("Ring already stopped");
90796e3668SPavan Nikhilesh 		break;
91f3c7b607SPavan Nikhilesh 	case TIM_AF_LF_START_SYNC_FAIL:
92f3c7b607SPavan Nikhilesh 		plt_err("Ring start sync failed.");
93f3c7b607SPavan Nikhilesh 		break;
94796e3668SPavan Nikhilesh 	default:
95f3c7b607SPavan Nikhilesh 		plt_err("Unknown Error: %d", rc);
96796e3668SPavan Nikhilesh 	}
97796e3668SPavan Nikhilesh }
98796e3668SPavan Nikhilesh 
99796e3668SPavan Nikhilesh int
10037a94462SPavan Nikhilesh roc_tim_capture_counters(struct roc_tim *roc_tim, uint64_t *counters, uint8_t nb_cntrs)
10137a94462SPavan Nikhilesh {
10237a94462SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
10337a94462SPavan Nikhilesh 	struct dev *dev = &sso->dev;
10437a94462SPavan Nikhilesh 	struct mbox *mbox = mbox_get(dev->mbox);
10537a94462SPavan Nikhilesh 	struct tim_capture_rsp *rsp;
10637a94462SPavan Nikhilesh 	int rc, i;
10737a94462SPavan Nikhilesh 
10837a94462SPavan Nikhilesh 	mbox_alloc_msg_tim_capture_counters(mbox);
10937a94462SPavan Nikhilesh 	rc = mbox_process_msg(dev->mbox, (void **)&rsp);
11037a94462SPavan Nikhilesh 	if (rc) {
11137a94462SPavan Nikhilesh 		tim_err_desc(rc);
11237a94462SPavan Nikhilesh 		rc = -EIO;
11337a94462SPavan Nikhilesh 		goto fail;
11437a94462SPavan Nikhilesh 	}
11537a94462SPavan Nikhilesh 
11637a94462SPavan Nikhilesh 	for (i = 0; i < nb_cntrs; i++)
11737a94462SPavan Nikhilesh 		counters[i] = rsp->counters[i];
11837a94462SPavan Nikhilesh 
11937a94462SPavan Nikhilesh fail:
12037a94462SPavan Nikhilesh 	mbox_put(mbox);
12137a94462SPavan Nikhilesh 	return rc;
12237a94462SPavan Nikhilesh }
12337a94462SPavan Nikhilesh 
12437a94462SPavan Nikhilesh int
125796e3668SPavan Nikhilesh roc_tim_lf_enable(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *start_tsc,
126796e3668SPavan Nikhilesh 		  uint32_t *cur_bkt)
127796e3668SPavan Nikhilesh {
128be541d37SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
129be541d37SPavan Nikhilesh 	struct dev *dev = &sso->dev;
13044a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
131f3c7b607SPavan Nikhilesh 	uint8_t retry_cnt = LF_ENABLE_RETRY_CNT;
132796e3668SPavan Nikhilesh 	struct tim_enable_rsp *rsp;
133796e3668SPavan Nikhilesh 	struct tim_ring_req *req;
134796e3668SPavan Nikhilesh 	int rc = -ENOSPC;
135796e3668SPavan Nikhilesh 
136f3c7b607SPavan Nikhilesh retry:
13744a9307cSRakesh Kudurumalla 	req = mbox_alloc_msg_tim_enable_ring(mbox);
138796e3668SPavan Nikhilesh 	if (req == NULL)
139be541d37SPavan Nikhilesh 		goto fail;
140796e3668SPavan Nikhilesh 	req->ring = ring_id;
141796e3668SPavan Nikhilesh 
142796e3668SPavan Nikhilesh 	rc = mbox_process_msg(dev->mbox, (void **)&rsp);
143be541d37SPavan Nikhilesh 	if (rc) {
144f3c7b607SPavan Nikhilesh 		if (rc == TIM_AF_LF_START_SYNC_FAIL && retry_cnt--)
145f3c7b607SPavan Nikhilesh 			goto retry;
146f3c7b607SPavan Nikhilesh 
147796e3668SPavan Nikhilesh 		tim_err_desc(rc);
148be541d37SPavan Nikhilesh 		rc = -EIO;
149be541d37SPavan Nikhilesh 		goto fail;
150796e3668SPavan Nikhilesh 	}
151796e3668SPavan Nikhilesh 
152796e3668SPavan Nikhilesh 	if (cur_bkt)
153796e3668SPavan Nikhilesh 		*cur_bkt = rsp->currentbucket;
154796e3668SPavan Nikhilesh 	if (start_tsc)
155796e3668SPavan Nikhilesh 		*start_tsc = rsp->timestarted;
156796e3668SPavan Nikhilesh 
157be541d37SPavan Nikhilesh fail:
15844a9307cSRakesh Kudurumalla 	mbox_put(mbox);
159be541d37SPavan Nikhilesh 	return rc;
160796e3668SPavan Nikhilesh }
161796e3668SPavan Nikhilesh 
162796e3668SPavan Nikhilesh int
163796e3668SPavan Nikhilesh roc_tim_lf_disable(struct roc_tim *roc_tim, uint8_t ring_id)
164796e3668SPavan Nikhilesh {
165be541d37SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
166be541d37SPavan Nikhilesh 	struct dev *dev = &sso->dev;
16744a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
168796e3668SPavan Nikhilesh 	struct tim_ring_req *req;
169796e3668SPavan Nikhilesh 	int rc = -ENOSPC;
170796e3668SPavan Nikhilesh 
17144a9307cSRakesh Kudurumalla 	req = mbox_alloc_msg_tim_disable_ring(mbox);
172796e3668SPavan Nikhilesh 	if (req == NULL)
173be541d37SPavan Nikhilesh 		goto fail;
174796e3668SPavan Nikhilesh 	req->ring = ring_id;
175796e3668SPavan Nikhilesh 
17637a94462SPavan Nikhilesh 	rc = mbox_process(mbox);
177be541d37SPavan Nikhilesh 	if (rc) {
178796e3668SPavan Nikhilesh 		tim_err_desc(rc);
179be541d37SPavan Nikhilesh 		rc = -EIO;
180796e3668SPavan Nikhilesh 	}
181796e3668SPavan Nikhilesh 
182be541d37SPavan Nikhilesh fail:
18344a9307cSRakesh Kudurumalla 	mbox_put(mbox);
184be541d37SPavan Nikhilesh 	return rc;
185796e3668SPavan Nikhilesh }
186796e3668SPavan Nikhilesh 
187796e3668SPavan Nikhilesh uintptr_t
188796e3668SPavan Nikhilesh roc_tim_lf_base_get(struct roc_tim *roc_tim, uint8_t ring_id)
189796e3668SPavan Nikhilesh {
190796e3668SPavan Nikhilesh 	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
191796e3668SPavan Nikhilesh 
192796e3668SPavan Nikhilesh 	return dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12);
193796e3668SPavan Nikhilesh }
194796e3668SPavan Nikhilesh 
195796e3668SPavan Nikhilesh int
196f3c7b607SPavan Nikhilesh roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id, enum roc_tim_clk_src clk_src,
197f3c7b607SPavan Nikhilesh 		  uint8_t ena_periodic, uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz,
198f3c7b607SPavan Nikhilesh 		  uint64_t interval, uint64_t intervalns, uint64_t clockfreq)
199796e3668SPavan Nikhilesh {
200be541d37SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
201be541d37SPavan Nikhilesh 	struct dev *dev = &sso->dev;
20244a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
203796e3668SPavan Nikhilesh 	struct tim_config_req *req;
204796e3668SPavan Nikhilesh 	int rc = -ENOSPC;
205796e3668SPavan Nikhilesh 
20644a9307cSRakesh Kudurumalla 	req = mbox_alloc_msg_tim_config_ring(mbox);
207796e3668SPavan Nikhilesh 	if (req == NULL)
208be541d37SPavan Nikhilesh 		goto fail;
209796e3668SPavan Nikhilesh 	req->ring = ring_id;
210796e3668SPavan Nikhilesh 	req->bigendian = false;
211796e3668SPavan Nikhilesh 	req->bucketsize = bucket_sz;
212796e3668SPavan Nikhilesh 	req->chunksize = chunk_sz;
213796e3668SPavan Nikhilesh 	req->clocksource = clk_src;
214796e3668SPavan Nikhilesh 	req->enableperiodic = ena_periodic;
215796e3668SPavan Nikhilesh 	req->enabledontfreebuffer = ena_dfb;
216f3c7b607SPavan Nikhilesh 	req->interval_lo = interval;
217f3c7b607SPavan Nikhilesh 	req->interval_hi = interval >> 32;
218dcc97999SPavan Nikhilesh 	req->intervalns = intervalns;
219dcc97999SPavan Nikhilesh 	req->clockfreq = clockfreq;
220796e3668SPavan Nikhilesh 	req->gpioedge = TIM_GPIO_LTOH_TRANS;
221796e3668SPavan Nikhilesh 
22244a9307cSRakesh Kudurumalla 	rc = mbox_process(mbox);
223be541d37SPavan Nikhilesh 	if (rc) {
224796e3668SPavan Nikhilesh 		tim_err_desc(rc);
225be541d37SPavan Nikhilesh 		rc = -EIO;
226796e3668SPavan Nikhilesh 	}
227796e3668SPavan Nikhilesh 
228be541d37SPavan Nikhilesh fail:
22944a9307cSRakesh Kudurumalla 	mbox_put(mbox);
230be541d37SPavan Nikhilesh 	return rc;
231796e3668SPavan Nikhilesh }
232796e3668SPavan Nikhilesh 
233796e3668SPavan Nikhilesh int
234f3c7b607SPavan Nikhilesh roc_tim_lf_config_hwwqe(struct roc_tim *roc_tim, uint8_t ring_id, struct roc_tim_hwwqe_cfg *cfg)
235f3c7b607SPavan Nikhilesh {
236f3c7b607SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
237f3c7b607SPavan Nikhilesh 	struct dev *dev = &sso->dev;
238f3c7b607SPavan Nikhilesh 	struct mbox *mbox = mbox_get(dev->mbox);
239f3c7b607SPavan Nikhilesh 	struct tim_cfg_hwwqe_req *req;
240f3c7b607SPavan Nikhilesh 	int rc = -ENOSPC;
241f3c7b607SPavan Nikhilesh 
242f3c7b607SPavan Nikhilesh 	req = mbox_alloc_msg_tim_config_hwwqe(mbox);
243f3c7b607SPavan Nikhilesh 	if (req == NULL)
244f3c7b607SPavan Nikhilesh 		goto fail;
245f3c7b607SPavan Nikhilesh 	req->ring = ring_id;
246f3c7b607SPavan Nikhilesh 	req->hwwqe_ena = cfg->hwwqe_ena;
247f3c7b607SPavan Nikhilesh 	req->grp_ena = cfg->grp_ena;
248f3c7b607SPavan Nikhilesh 	req->grp_tmo_cntr = cfg->grp_tmo_cyc;
249f3c7b607SPavan Nikhilesh 	req->flw_ctrl_ena = cfg->flw_ctrl_ena;
250f3c7b607SPavan Nikhilesh 	req->result_offset = cfg->result_offset;
251f3c7b607SPavan Nikhilesh 	req->event_count_offset = cfg->event_count_offset;
252f3c7b607SPavan Nikhilesh 
253f3c7b607SPavan Nikhilesh 	req->wqe_rd_clr_ena = 1;
254f3c7b607SPavan Nikhilesh 	req->npa_tmo_cntr = TIM_NPA_TMO;
255f3c7b607SPavan Nikhilesh 	req->ins_min_gap = TIM_BUCKET_MIN_GAP;
256f3c7b607SPavan Nikhilesh 
257f3c7b607SPavan Nikhilesh 	rc = mbox_process(mbox);
258f3c7b607SPavan Nikhilesh 	if (rc) {
259f3c7b607SPavan Nikhilesh 		tim_err_desc(rc);
260f3c7b607SPavan Nikhilesh 		rc = -EIO;
261f3c7b607SPavan Nikhilesh 	}
262f3c7b607SPavan Nikhilesh 
263f3c7b607SPavan Nikhilesh fail:
264f3c7b607SPavan Nikhilesh 	mbox_put(mbox);
265f3c7b607SPavan Nikhilesh 	return rc;
266f3c7b607SPavan Nikhilesh }
267f3c7b607SPavan Nikhilesh 
268f3c7b607SPavan Nikhilesh int
269dcc97999SPavan Nikhilesh roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src,
270dcc97999SPavan Nikhilesh 		    uint64_t clockfreq, uint64_t *intervalns,
271dcc97999SPavan Nikhilesh 		    uint64_t *interval)
272dcc97999SPavan Nikhilesh {
273be541d37SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
274be541d37SPavan Nikhilesh 	struct dev *dev = &sso->dev;
27544a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
276dcc97999SPavan Nikhilesh 	struct tim_intvl_req *req;
277dcc97999SPavan Nikhilesh 	struct tim_intvl_rsp *rsp;
278dcc97999SPavan Nikhilesh 	int rc = -ENOSPC;
279dcc97999SPavan Nikhilesh 
28044a9307cSRakesh Kudurumalla 	req = mbox_alloc_msg_tim_get_min_intvl(mbox);
281dcc97999SPavan Nikhilesh 	if (req == NULL)
282be541d37SPavan Nikhilesh 		goto fail;
283dcc97999SPavan Nikhilesh 
284dcc97999SPavan Nikhilesh 	req->clockfreq = clockfreq;
285dcc97999SPavan Nikhilesh 	req->clocksource = clk_src;
286dcc97999SPavan Nikhilesh 	rc = mbox_process_msg(dev->mbox, (void **)&rsp);
287be541d37SPavan Nikhilesh 	if (rc) {
288dcc97999SPavan Nikhilesh 		tim_err_desc(rc);
289be541d37SPavan Nikhilesh 		rc = -EIO;
290be541d37SPavan Nikhilesh 		goto fail;
291dcc97999SPavan Nikhilesh 	}
292dcc97999SPavan Nikhilesh 
293dcc97999SPavan Nikhilesh 	*intervalns = rsp->intvl_ns;
294dcc97999SPavan Nikhilesh 	*interval = rsp->intvl_cyc;
295dcc97999SPavan Nikhilesh 
296be541d37SPavan Nikhilesh fail:
29744a9307cSRakesh Kudurumalla 	mbox_put(mbox);
298be541d37SPavan Nikhilesh 	return rc;
299dcc97999SPavan Nikhilesh }
300dcc97999SPavan Nikhilesh 
301dcc97999SPavan Nikhilesh int
302796e3668SPavan Nikhilesh roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
303796e3668SPavan Nikhilesh {
304796e3668SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
305309b553cSPavan Nikhilesh 	struct tim *tim = roc_tim_to_tim_priv(roc_tim);
306309b553cSPavan Nikhilesh 	struct tim_ring_req *free_req;
307796e3668SPavan Nikhilesh 	struct tim_lf_alloc_req *req;
308796e3668SPavan Nikhilesh 	struct tim_lf_alloc_rsp *rsp;
309796e3668SPavan Nikhilesh 	struct dev *dev = &sso->dev;
31044a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
311796e3668SPavan Nikhilesh 	int rc = -ENOSPC;
312796e3668SPavan Nikhilesh 
31344a9307cSRakesh Kudurumalla 	req = mbox_alloc_msg_tim_lf_alloc(mbox);
314796e3668SPavan Nikhilesh 	if (req == NULL)
315be541d37SPavan Nikhilesh 		goto fail;
316796e3668SPavan Nikhilesh 	req->npa_pf_func = idev_npa_pffunc_get();
317796e3668SPavan Nikhilesh 	req->sso_pf_func = idev_sso_pffunc_get();
318796e3668SPavan Nikhilesh 	req->ring = ring_id;
319796e3668SPavan Nikhilesh 
32044a9307cSRakesh Kudurumalla 	rc = mbox_process_msg(mbox, (void **)&rsp);
321be541d37SPavan Nikhilesh 	if (rc) {
322796e3668SPavan Nikhilesh 		tim_err_desc(rc);
323be541d37SPavan Nikhilesh 		rc = -EIO;
324be541d37SPavan Nikhilesh 		goto fail;
325796e3668SPavan Nikhilesh 	}
326796e3668SPavan Nikhilesh 
327796e3668SPavan Nikhilesh 	if (clk)
328796e3668SPavan Nikhilesh 		*clk = rsp->tenns_clk;
329796e3668SPavan Nikhilesh 
330d61138d4SHarman Kalra 	rc = tim_register_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id,
331309b553cSPavan Nikhilesh 				   tim->tim_msix_offsets[ring_id]);
332309b553cSPavan Nikhilesh 	if (rc < 0) {
333309b553cSPavan Nikhilesh 		plt_tim_dbg("Failed to register Ring[%d] IRQ", ring_id);
33444a9307cSRakesh Kudurumalla 		free_req = mbox_alloc_msg_tim_lf_free(mbox);
335be541d37SPavan Nikhilesh 		if (free_req == NULL) {
336be541d37SPavan Nikhilesh 			rc = -ENOSPC;
337be541d37SPavan Nikhilesh 			goto fail;
338be541d37SPavan Nikhilesh 		}
339309b553cSPavan Nikhilesh 		free_req->ring = ring_id;
34044a9307cSRakesh Kudurumalla 		rc = mbox_process(mbox);
341be541d37SPavan Nikhilesh 		if (rc)
342be541d37SPavan Nikhilesh 			rc = -EIO;
343309b553cSPavan Nikhilesh 	}
344309b553cSPavan Nikhilesh 
345be541d37SPavan Nikhilesh fail:
34644a9307cSRakesh Kudurumalla 	mbox_put(dev->mbox);
347796e3668SPavan Nikhilesh 	return rc;
348796e3668SPavan Nikhilesh }
349796e3668SPavan Nikhilesh 
350796e3668SPavan Nikhilesh int
351796e3668SPavan Nikhilesh roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id)
352796e3668SPavan Nikhilesh {
353796e3668SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
354309b553cSPavan Nikhilesh 	struct tim *tim = roc_tim_to_tim_priv(roc_tim);
355796e3668SPavan Nikhilesh 	struct dev *dev = &sso->dev;
356796e3668SPavan Nikhilesh 	struct tim_ring_req *req;
357796e3668SPavan Nikhilesh 	int rc = -ENOSPC;
358796e3668SPavan Nikhilesh 
359d61138d4SHarman Kalra 	tim_unregister_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id,
360309b553cSPavan Nikhilesh 				tim->tim_msix_offsets[ring_id]);
361309b553cSPavan Nikhilesh 
36244a9307cSRakesh Kudurumalla 	req = mbox_alloc_msg_tim_lf_free(mbox_get(dev->mbox));
363796e3668SPavan Nikhilesh 	if (req == NULL)
364be541d37SPavan Nikhilesh 		goto fail;
365796e3668SPavan Nikhilesh 	req->ring = ring_id;
366796e3668SPavan Nikhilesh 
367796e3668SPavan Nikhilesh 	rc = mbox_process(dev->mbox);
368796e3668SPavan Nikhilesh 	if (rc < 0) {
369796e3668SPavan Nikhilesh 		tim_err_desc(rc);
370be541d37SPavan Nikhilesh 		rc = -EIO;
37144a9307cSRakesh Kudurumalla 		goto fail;
372796e3668SPavan Nikhilesh 	}
37344a9307cSRakesh Kudurumalla 	rc = 0;
374796e3668SPavan Nikhilesh 
375be541d37SPavan Nikhilesh fail:
37644a9307cSRakesh Kudurumalla 	mbox_put(dev->mbox);
37744a9307cSRakesh Kudurumalla 	return rc;
378796e3668SPavan Nikhilesh }
379796e3668SPavan Nikhilesh 
380796e3668SPavan Nikhilesh int
381993107f0SShijith Thotton tim_free_lf_count_get(struct dev *dev, uint16_t *nb_lfs)
382993107f0SShijith Thotton {
38344a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
384993107f0SShijith Thotton 	struct free_rsrcs_rsp *rsrc_cnt;
385993107f0SShijith Thotton 	int rc;
386993107f0SShijith Thotton 
38744a9307cSRakesh Kudurumalla 	mbox_alloc_msg_free_rsrc_cnt(mbox);
38844a9307cSRakesh Kudurumalla 	rc = mbox_process_msg(mbox, (void **)&rsrc_cnt);
389993107f0SShijith Thotton 	if (rc) {
390f665790aSDavid Marchand 		plt_err("Failed to get free resource count");
39144a9307cSRakesh Kudurumalla 		mbox_put(mbox);
392993107f0SShijith Thotton 		return -EIO;
393993107f0SShijith Thotton 	}
394993107f0SShijith Thotton 
395993107f0SShijith Thotton 	*nb_lfs = rsrc_cnt->tim;
39644a9307cSRakesh Kudurumalla 	mbox_put(mbox);
397993107f0SShijith Thotton 
398993107f0SShijith Thotton 	return 0;
399993107f0SShijith Thotton }
400993107f0SShijith Thotton 
401f3c7b607SPavan Nikhilesh static int
402f3c7b607SPavan Nikhilesh tim_hw_info_get(struct roc_tim *roc_tim)
403f3c7b607SPavan Nikhilesh {
404f3c7b607SPavan Nikhilesh 	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
405f3c7b607SPavan Nikhilesh 	struct mbox *mbox = mbox_get(dev->mbox);
406f3c7b607SPavan Nikhilesh 	struct tim_hw_info *rsp;
407f3c7b607SPavan Nikhilesh 	int rc;
408f3c7b607SPavan Nikhilesh 
409f3c7b607SPavan Nikhilesh 	mbox_alloc_msg_tim_get_hw_info(mbox);
410f3c7b607SPavan Nikhilesh 	rc = mbox_process_msg(mbox, (void **)&rsp);
411f3c7b607SPavan Nikhilesh 	if (rc && rc != MBOX_MSG_INVALID) {
412*822d4ef5SPavan Nikhilesh 		plt_err("Failed to get TIM HW info");
413f3c7b607SPavan Nikhilesh 		rc = -EIO;
414f3c7b607SPavan Nikhilesh 		goto exit;
415f3c7b607SPavan Nikhilesh 	}
416f3c7b607SPavan Nikhilesh 
417f3c7b607SPavan Nikhilesh 	if (rc != MBOX_MSG_INVALID)
418f3c7b607SPavan Nikhilesh 		mbox_memcpy(&roc_tim->feat, &rsp->feat, sizeof(roc_tim->feat));
419f3c7b607SPavan Nikhilesh 
420f3c7b607SPavan Nikhilesh 	rc = 0;
421f3c7b607SPavan Nikhilesh exit:
422f3c7b607SPavan Nikhilesh 	mbox_put(mbox);
423f3c7b607SPavan Nikhilesh 	return rc;
424f3c7b607SPavan Nikhilesh }
425f3c7b607SPavan Nikhilesh 
426993107f0SShijith Thotton int
427796e3668SPavan Nikhilesh roc_tim_init(struct roc_tim *roc_tim)
428796e3668SPavan Nikhilesh {
429796e3668SPavan Nikhilesh 	struct rsrc_attach_req *attach_req;
430309b553cSPavan Nikhilesh 	struct rsrc_detach_req *detach_req;
431993107f0SShijith Thotton 	uint16_t nb_lfs, nb_free_lfs;
432be541d37SPavan Nikhilesh 	struct sso *sso;
433be541d37SPavan Nikhilesh 	struct dev *dev;
434796e3668SPavan Nikhilesh 	int rc;
435796e3668SPavan Nikhilesh 
436796e3668SPavan Nikhilesh 	if (roc_tim == NULL || roc_tim->roc_sso == NULL)
437796e3668SPavan Nikhilesh 		return TIM_ERR_PARAM;
438796e3668SPavan Nikhilesh 
439be541d37SPavan Nikhilesh 	sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
440be541d37SPavan Nikhilesh 	dev = &sso->dev;
441993107f0SShijith Thotton 	dev->roc_tim = roc_tim;
442796e3668SPavan Nikhilesh 	PLT_STATIC_ASSERT(sizeof(struct tim) <= TIM_MEM_SZ);
443796e3668SPavan Nikhilesh 	nb_lfs = roc_tim->nb_lfs;
444993107f0SShijith Thotton 
445f3c7b607SPavan Nikhilesh 	rc = tim_hw_info_get(roc_tim);
446*822d4ef5SPavan Nikhilesh 	if (rc) {
447*822d4ef5SPavan Nikhilesh 		plt_tim_dbg("Failed to get TIM HW info");
448*822d4ef5SPavan Nikhilesh 		return 0;
449*822d4ef5SPavan Nikhilesh 	}
450f3c7b607SPavan Nikhilesh 
451993107f0SShijith Thotton 	rc = tim_free_lf_count_get(dev, &nb_free_lfs);
452be541d37SPavan Nikhilesh 	if (rc) {
453993107f0SShijith Thotton 		plt_tim_dbg("Failed to get TIM resource count");
454be541d37SPavan Nikhilesh 		nb_lfs = 0;
45544a9307cSRakesh Kudurumalla 		return nb_lfs;
456796e3668SPavan Nikhilesh 	}
457796e3668SPavan Nikhilesh 
458993107f0SShijith Thotton 	if (nb_lfs && (nb_free_lfs < nb_lfs)) {
459993107f0SShijith Thotton 		plt_tim_dbg("Requested LFs : %d Available LFs : %d", nb_lfs, nb_free_lfs);
460be541d37SPavan Nikhilesh 		nb_lfs = 0;
46144a9307cSRakesh Kudurumalla 		return nb_lfs;
462796e3668SPavan Nikhilesh 	}
463796e3668SPavan Nikhilesh 
46444a9307cSRakesh Kudurumalla 	mbox_get(dev->mbox);
465796e3668SPavan Nikhilesh 	attach_req = mbox_alloc_msg_attach_resources(dev->mbox);
466be541d37SPavan Nikhilesh 	if (attach_req == NULL) {
467be541d37SPavan Nikhilesh 		nb_lfs = 0;
468be541d37SPavan Nikhilesh 		goto fail;
469be541d37SPavan Nikhilesh 	}
470796e3668SPavan Nikhilesh 	attach_req->modify = true;
471993107f0SShijith Thotton 	attach_req->timlfs = nb_lfs ? nb_lfs : nb_free_lfs;
472796e3668SPavan Nikhilesh 	nb_lfs = attach_req->timlfs;
473796e3668SPavan Nikhilesh 
474796e3668SPavan Nikhilesh 	rc = mbox_process(dev->mbox);
475be541d37SPavan Nikhilesh 	if (rc) {
476796e3668SPavan Nikhilesh 		plt_err("Unable to attach TIM LFs.");
477be541d37SPavan Nikhilesh 		nb_lfs = 0;
478be541d37SPavan Nikhilesh 		goto fail;
479796e3668SPavan Nikhilesh 	}
480796e3668SPavan Nikhilesh 
48144a9307cSRakesh Kudurumalla 	mbox_put(dev->mbox);
482309b553cSPavan Nikhilesh 	rc = tim_fill_msix(roc_tim, nb_lfs);
483309b553cSPavan Nikhilesh 	if (rc < 0) {
484309b553cSPavan Nikhilesh 		plt_err("Unable to get TIM MSIX vectors");
485309b553cSPavan Nikhilesh 
48644a9307cSRakesh Kudurumalla 		detach_req = mbox_alloc_msg_detach_resources(mbox_get(dev->mbox));
487be541d37SPavan Nikhilesh 		if (detach_req == NULL) {
488be541d37SPavan Nikhilesh 			nb_lfs = 0;
489be541d37SPavan Nikhilesh 			goto fail;
490be541d37SPavan Nikhilesh 		}
491309b553cSPavan Nikhilesh 		detach_req->partial = true;
492309b553cSPavan Nikhilesh 		detach_req->timlfs = true;
493309b553cSPavan Nikhilesh 		mbox_process(dev->mbox);
494be541d37SPavan Nikhilesh 		nb_lfs = 0;
49544a9307cSRakesh Kudurumalla 	} else {
49644a9307cSRakesh Kudurumalla 		goto done;
497309b553cSPavan Nikhilesh 	}
498309b553cSPavan Nikhilesh 
499be541d37SPavan Nikhilesh fail:
50044a9307cSRakesh Kudurumalla 	mbox_put(dev->mbox);
50144a9307cSRakesh Kudurumalla done:
5023d668744SShijith Thotton 	roc_tim->nb_lfs = nb_lfs;
503796e3668SPavan Nikhilesh 	return nb_lfs;
504796e3668SPavan Nikhilesh }
505796e3668SPavan Nikhilesh 
506796e3668SPavan Nikhilesh void
507796e3668SPavan Nikhilesh roc_tim_fini(struct roc_tim *roc_tim)
508796e3668SPavan Nikhilesh {
509be541d37SPavan Nikhilesh 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
510796e3668SPavan Nikhilesh 	struct rsrc_detach_req *detach_req;
511be541d37SPavan Nikhilesh 	struct dev *dev = &sso->dev;
51244a9307cSRakesh Kudurumalla 	struct mbox *mbox = mbox_get(dev->mbox);
513796e3668SPavan Nikhilesh 
51444a9307cSRakesh Kudurumalla 	detach_req = mbox_alloc_msg_detach_resources(mbox);
515796e3668SPavan Nikhilesh 	PLT_ASSERT(detach_req);
516796e3668SPavan Nikhilesh 	detach_req->partial = true;
517796e3668SPavan Nikhilesh 	detach_req->timlfs = true;
518796e3668SPavan Nikhilesh 
51944a9307cSRakesh Kudurumalla 	mbox_process(mbox);
52044a9307cSRakesh Kudurumalla 	mbox_put(mbox);
521796e3668SPavan Nikhilesh }
522