build: add global libatomic dependency for 32-bit clang
[dpdk.git] / drivers / event / octeontx2 / otx2_evdev_irq.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include "otx2_evdev.h"
6 #include "otx2_tim_evdev.h"
7
8 static void
9 sso_lf_irq(void *param)
10 {
11         uintptr_t base = (uintptr_t)param;
12         uint64_t intr;
13         uint8_t ggrp;
14
15         ggrp = (base >> 12) & 0xFF;
16
17         intr = otx2_read64(base + SSO_LF_GGRP_INT);
18         if (intr == 0)
19                 return;
20
21         otx2_err("GGRP %d GGRP_INT=0x%" PRIx64 "", ggrp, intr);
22
23         /* Clear interrupt */
24         otx2_write64(intr, base + SSO_LF_GGRP_INT);
25 }
26
27 static int
28 sso_lf_register_irq(const struct rte_eventdev *event_dev, uint16_t ggrp_msixoff,
29                     uintptr_t base)
30 {
31         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(event_dev->dev);
32         struct rte_intr_handle *handle = &pci_dev->intr_handle;
33         int rc, vec;
34
35         vec = ggrp_msixoff + SSO_LF_INT_VEC_GRP;
36
37         /* Clear err interrupt */
38         otx2_write64(~0ull, base + SSO_LF_GGRP_INT_ENA_W1C);
39         /* Set used interrupt vectors */
40         rc = otx2_register_irq(handle, sso_lf_irq, (void *)base, vec);
41         /* Enable hw interrupt */
42         otx2_write64(~0ull, base + SSO_LF_GGRP_INT_ENA_W1S);
43
44         return rc;
45 }
46
47 static void
48 ssow_lf_irq(void *param)
49 {
50         uintptr_t base = (uintptr_t)param;
51         uint8_t gws = (base >> 12) & 0xFF;
52         uint64_t intr;
53
54         intr = otx2_read64(base + SSOW_LF_GWS_INT);
55         if (intr == 0)
56                 return;
57
58         otx2_err("GWS %d GWS_INT=0x%" PRIx64 "", gws, intr);
59
60         /* Clear interrupt */
61         otx2_write64(intr, base + SSOW_LF_GWS_INT);
62 }
63
64 static int
65 ssow_lf_register_irq(const struct rte_eventdev *event_dev, uint16_t gws_msixoff,
66                      uintptr_t base)
67 {
68         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(event_dev->dev);
69         struct rte_intr_handle *handle = &pci_dev->intr_handle;
70         int rc, vec;
71
72         vec = gws_msixoff + SSOW_LF_INT_VEC_IOP;
73
74         /* Clear err interrupt */
75         otx2_write64(~0ull, base + SSOW_LF_GWS_INT_ENA_W1C);
76         /* Set used interrupt vectors */
77         rc = otx2_register_irq(handle, ssow_lf_irq, (void *)base, vec);
78         /* Enable hw interrupt */
79         otx2_write64(~0ull, base + SSOW_LF_GWS_INT_ENA_W1S);
80
81         return rc;
82 }
83
84 static void
85 sso_lf_unregister_irq(const struct rte_eventdev *event_dev,
86                       uint16_t ggrp_msixoff, uintptr_t base)
87 {
88         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(event_dev->dev);
89         struct rte_intr_handle *handle = &pci_dev->intr_handle;
90         int vec;
91
92         vec = ggrp_msixoff + SSO_LF_INT_VEC_GRP;
93
94         /* Clear err interrupt */
95         otx2_write64(~0ull, base + SSO_LF_GGRP_INT_ENA_W1C);
96         otx2_unregister_irq(handle, sso_lf_irq, (void *)base, vec);
97 }
98
99 static void
100 ssow_lf_unregister_irq(const struct rte_eventdev *event_dev,
101                        uint16_t gws_msixoff, uintptr_t base)
102 {
103         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(event_dev->dev);
104         struct rte_intr_handle *handle = &pci_dev->intr_handle;
105         int vec;
106
107         vec = gws_msixoff + SSOW_LF_INT_VEC_IOP;
108
109         /* Clear err interrupt */
110         otx2_write64(~0ull, base + SSOW_LF_GWS_INT_ENA_W1C);
111         otx2_unregister_irq(handle, ssow_lf_irq, (void *)base, vec);
112 }
113
114 int
115 sso_register_irqs(const struct rte_eventdev *event_dev)
116 {
117         struct otx2_sso_evdev *dev = sso_pmd_priv(event_dev);
118         int i, rc = -EINVAL;
119         uint8_t nb_ports;
120
121         nb_ports = dev->nb_event_ports * (dev->dual_ws ? 2 : 1);
122
123         for (i = 0; i < dev->nb_event_queues; i++) {
124                 if (dev->sso_msixoff[i] == MSIX_VECTOR_INVALID) {
125                         otx2_err("Invalid SSOLF MSIX offset[%d] vector: 0x%x",
126                                  i, dev->sso_msixoff[i]);
127                         goto fail;
128                 }
129         }
130
131         for (i = 0; i < nb_ports; i++) {
132                 if (dev->ssow_msixoff[i] == MSIX_VECTOR_INVALID) {
133                         otx2_err("Invalid SSOWLF MSIX offset[%d] vector: 0x%x",
134                                  i, dev->ssow_msixoff[i]);
135                         goto fail;
136                 }
137         }
138
139         for (i = 0; i < dev->nb_event_queues; i++) {
140                 uintptr_t base = dev->bar2 + (RVU_BLOCK_ADDR_SSO << 20 |
141                                               i << 12);
142                 rc = sso_lf_register_irq(event_dev, dev->sso_msixoff[i], base);
143         }
144
145         for (i = 0; i < nb_ports; i++) {
146                 uintptr_t base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 |
147                                               i << 12);
148                 rc = ssow_lf_register_irq(event_dev, dev->ssow_msixoff[i],
149                                           base);
150         }
151
152 fail:
153         return rc;
154 }
155
156 void
157 sso_unregister_irqs(const struct rte_eventdev *event_dev)
158 {
159         struct otx2_sso_evdev *dev = sso_pmd_priv(event_dev);
160         uint8_t nb_ports;
161         int i;
162
163         nb_ports = dev->nb_event_ports * (dev->dual_ws ? 2 : 1);
164
165         for (i = 0; i < dev->nb_event_queues; i++) {
166                 uintptr_t base = dev->bar2 + (RVU_BLOCK_ADDR_SSO << 20 |
167                                               i << 12);
168                 sso_lf_unregister_irq(event_dev, dev->sso_msixoff[i], base);
169         }
170
171         for (i = 0; i < nb_ports; i++) {
172                 uintptr_t base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 |
173                                               i << 12);
174                 ssow_lf_unregister_irq(event_dev, dev->ssow_msixoff[i], base);
175         }
176 }
177
178 static void
179 tim_lf_irq(void *param)
180 {
181         uintptr_t base = (uintptr_t)param;
182         uint64_t intr;
183         uint8_t ring;
184
185         ring = (base >> 12) & 0xFF;
186
187         intr = otx2_read64(base + TIM_LF_NRSPERR_INT);
188         otx2_err("TIM RING %d TIM_LF_NRSPERR_INT=0x%" PRIx64 "", ring, intr);
189         intr = otx2_read64(base + TIM_LF_RAS_INT);
190         otx2_err("TIM RING %d TIM_LF_RAS_INT=0x%" PRIx64 "", ring, intr);
191
192         /* Clear interrupt */
193         otx2_write64(intr, base + TIM_LF_NRSPERR_INT);
194         otx2_write64(intr, base + TIM_LF_RAS_INT);
195 }
196
197 static int
198 tim_lf_register_irq(struct rte_pci_device *pci_dev, uint16_t tim_msixoff,
199                     uintptr_t base)
200 {
201         struct rte_intr_handle *handle = &pci_dev->intr_handle;
202         int rc, vec;
203
204         vec = tim_msixoff + TIM_LF_INT_VEC_NRSPERR_INT;
205
206         /* Clear err interrupt */
207         otx2_write64(~0ull, base + TIM_LF_NRSPERR_INT);
208         /* Set used interrupt vectors */
209         rc = otx2_register_irq(handle, tim_lf_irq, (void *)base, vec);
210         /* Enable hw interrupt */
211         otx2_write64(~0ull, base + TIM_LF_NRSPERR_INT_ENA_W1S);
212
213         vec = tim_msixoff + TIM_LF_INT_VEC_RAS_INT;
214
215         /* Clear err interrupt */
216         otx2_write64(~0ull, base + TIM_LF_RAS_INT);
217         /* Set used interrupt vectors */
218         rc = otx2_register_irq(handle, tim_lf_irq, (void *)base, vec);
219         /* Enable hw interrupt */
220         otx2_write64(~0ull, base + TIM_LF_RAS_INT_ENA_W1S);
221
222         return rc;
223 }
224
225 static void
226 tim_lf_unregister_irq(struct rte_pci_device *pci_dev, uint16_t tim_msixoff,
227                       uintptr_t base)
228 {
229         struct rte_intr_handle *handle = &pci_dev->intr_handle;
230         int vec;
231
232         vec = tim_msixoff + TIM_LF_INT_VEC_NRSPERR_INT;
233
234         /* Clear err interrupt */
235         otx2_write64(~0ull, base + TIM_LF_NRSPERR_INT_ENA_W1C);
236         otx2_unregister_irq(handle, tim_lf_irq, (void *)base, vec);
237
238         vec = tim_msixoff + TIM_LF_INT_VEC_RAS_INT;
239
240         /* Clear err interrupt */
241         otx2_write64(~0ull, base + TIM_LF_RAS_INT_ENA_W1C);
242         otx2_unregister_irq(handle, tim_lf_irq, (void *)base, vec);
243 }
244
245 int
246 tim_register_irq(uint16_t ring_id)
247 {
248         struct otx2_tim_evdev *dev = tim_priv_get();
249         int rc = -EINVAL;
250         uintptr_t base;
251
252         if (dev->tim_msixoff[ring_id] == MSIX_VECTOR_INVALID) {
253                 otx2_err("Invalid TIMLF MSIX offset[%d] vector: 0x%x",
254                          ring_id, dev->tim_msixoff[ring_id]);
255                 goto fail;
256         }
257
258         base = dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12);
259         rc = tim_lf_register_irq(dev->pci_dev, dev->tim_msixoff[ring_id], base);
260 fail:
261         return rc;
262 }
263
264 void
265 tim_unregister_irq(uint16_t ring_id)
266 {
267         struct otx2_tim_evdev *dev = tim_priv_get();
268         uintptr_t base;
269
270         base = dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12);
271         tim_lf_unregister_irq(dev->pci_dev, dev->tim_msixoff[ring_id], base);
272 }