]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2010-2018 Intel Corporation | |
3 | */ | |
4 | ||
5 | #include "ifpga_feature_dev.h" | |
6 | ||
7 | int port_get_prop(struct ifpga_port_hw *port, struct feature_prop *prop) | |
8 | { | |
9f95a23c | 9 | struct ifpga_feature *feature; |
11fdf7f2 TL |
10 | |
11 | if (!port) | |
12 | return -ENOENT; | |
13 | ||
14 | feature = get_port_feature_by_id(port, prop->feature_id); | |
15 | ||
16 | if (feature && feature->ops && feature->ops->get_prop) | |
17 | return feature->ops->get_prop(feature, prop); | |
18 | ||
19 | return -ENOENT; | |
20 | } | |
21 | ||
22 | int port_set_prop(struct ifpga_port_hw *port, struct feature_prop *prop) | |
23 | { | |
9f95a23c | 24 | struct ifpga_feature *feature; |
11fdf7f2 TL |
25 | |
26 | if (!port) | |
27 | return -ENOENT; | |
28 | ||
29 | feature = get_port_feature_by_id(port, prop->feature_id); | |
30 | ||
31 | if (feature && feature->ops && feature->ops->set_prop) | |
32 | return feature->ops->set_prop(feature, prop); | |
33 | ||
34 | return -ENOENT; | |
35 | } | |
36 | ||
37 | int port_set_irq(struct ifpga_port_hw *port, u32 feature_id, void *irq_set) | |
38 | { | |
9f95a23c | 39 | struct ifpga_feature *feature; |
11fdf7f2 TL |
40 | |
41 | if (!port) | |
42 | return -ENOENT; | |
43 | ||
44 | feature = get_port_feature_by_id(port, feature_id); | |
45 | ||
46 | if (feature && feature->ops && feature->ops->set_irq) | |
47 | return feature->ops->set_irq(feature, irq_set); | |
48 | ||
49 | return -ENOENT; | |
50 | } | |
51 | ||
52 | static int port_get_revision(struct ifpga_port_hw *port, u64 *revision) | |
53 | { | |
54 | struct feature_port_header *port_hdr | |
55 | = get_port_feature_ioaddr_by_index(port, | |
56 | PORT_FEATURE_ID_HEADER); | |
57 | struct feature_header header; | |
58 | ||
59 | header.csr = readq(&port_hdr->header); | |
60 | ||
61 | *revision = header.revision; | |
62 | ||
63 | return 0; | |
64 | } | |
65 | ||
66 | static int port_get_portidx(struct ifpga_port_hw *port, u64 *idx) | |
67 | { | |
68 | struct feature_port_header *port_hdr; | |
69 | struct feature_port_capability capability; | |
70 | ||
71 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
72 | PORT_FEATURE_ID_HEADER); | |
73 | ||
74 | capability.csr = readq(&port_hdr->capability); | |
75 | *idx = capability.port_number; | |
76 | ||
77 | return 0; | |
78 | } | |
79 | ||
80 | static int port_get_latency_tolerance(struct ifpga_port_hw *port, u64 *val) | |
81 | { | |
82 | struct feature_port_header *port_hdr; | |
83 | struct feature_port_control control; | |
84 | ||
85 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
86 | PORT_FEATURE_ID_HEADER); | |
87 | ||
88 | control.csr = readq(&port_hdr->control); | |
89 | *val = control.latency_tolerance; | |
90 | ||
91 | return 0; | |
92 | } | |
93 | ||
94 | static int port_get_ap1_event(struct ifpga_port_hw *port, u64 *val) | |
95 | { | |
96 | struct feature_port_header *port_hdr; | |
97 | struct feature_port_status status; | |
98 | ||
99 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
100 | PORT_FEATURE_ID_HEADER); | |
101 | ||
102 | spinlock_lock(&port->lock); | |
103 | status.csr = readq(&port_hdr->status); | |
104 | spinlock_unlock(&port->lock); | |
105 | ||
106 | *val = status.ap1_event; | |
107 | ||
108 | return 0; | |
109 | } | |
110 | ||
111 | static int port_set_ap1_event(struct ifpga_port_hw *port, u64 val) | |
112 | { | |
113 | struct feature_port_header *port_hdr; | |
114 | struct feature_port_status status; | |
115 | ||
116 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
117 | PORT_FEATURE_ID_HEADER); | |
118 | ||
119 | spinlock_lock(&port->lock); | |
120 | status.csr = readq(&port_hdr->status); | |
121 | status.ap1_event = val; | |
122 | writeq(status.csr, &port_hdr->status); | |
123 | spinlock_unlock(&port->lock); | |
124 | ||
125 | return 0; | |
126 | } | |
127 | ||
128 | static int port_get_ap2_event(struct ifpga_port_hw *port, u64 *val) | |
129 | { | |
130 | struct feature_port_header *port_hdr; | |
131 | struct feature_port_status status; | |
132 | ||
133 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
134 | PORT_FEATURE_ID_HEADER); | |
135 | ||
136 | spinlock_lock(&port->lock); | |
137 | status.csr = readq(&port_hdr->status); | |
138 | spinlock_unlock(&port->lock); | |
139 | ||
140 | *val = status.ap2_event; | |
141 | ||
142 | return 0; | |
143 | } | |
144 | ||
145 | static int port_set_ap2_event(struct ifpga_port_hw *port, u64 val) | |
146 | { | |
147 | struct feature_port_header *port_hdr; | |
148 | struct feature_port_status status; | |
149 | ||
150 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
151 | PORT_FEATURE_ID_HEADER); | |
152 | ||
153 | spinlock_lock(&port->lock); | |
154 | status.csr = readq(&port_hdr->status); | |
155 | status.ap2_event = val; | |
156 | writeq(status.csr, &port_hdr->status); | |
157 | spinlock_unlock(&port->lock); | |
158 | ||
159 | return 0; | |
160 | } | |
161 | ||
162 | static int port_get_power_state(struct ifpga_port_hw *port, u64 *val) | |
163 | { | |
164 | struct feature_port_header *port_hdr; | |
165 | struct feature_port_status status; | |
166 | ||
167 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
168 | PORT_FEATURE_ID_HEADER); | |
169 | ||
170 | spinlock_lock(&port->lock); | |
171 | status.csr = readq(&port_hdr->status); | |
172 | spinlock_unlock(&port->lock); | |
173 | ||
174 | *val = status.power_state; | |
175 | ||
176 | return 0; | |
177 | } | |
178 | ||
179 | static int port_get_userclk_freqcmd(struct ifpga_port_hw *port, u64 *val) | |
180 | { | |
181 | struct feature_port_header *port_hdr; | |
182 | ||
183 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
184 | PORT_FEATURE_ID_HEADER); | |
185 | ||
186 | spinlock_lock(&port->lock); | |
187 | *val = readq(&port_hdr->user_clk_freq_cmd0); | |
188 | spinlock_unlock(&port->lock); | |
189 | ||
190 | return 0; | |
191 | } | |
192 | ||
193 | static int port_set_userclk_freqcmd(struct ifpga_port_hw *port, u64 val) | |
194 | { | |
195 | struct feature_port_header *port_hdr; | |
196 | ||
197 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
198 | PORT_FEATURE_ID_HEADER); | |
199 | ||
200 | spinlock_lock(&port->lock); | |
201 | writeq(val, &port_hdr->user_clk_freq_cmd0); | |
202 | spinlock_unlock(&port->lock); | |
203 | ||
204 | return 0; | |
205 | } | |
206 | ||
207 | static int port_get_userclk_freqcntrcmd(struct ifpga_port_hw *port, u64 *val) | |
208 | { | |
209 | struct feature_port_header *port_hdr; | |
210 | ||
211 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
212 | PORT_FEATURE_ID_HEADER); | |
213 | ||
214 | spinlock_lock(&port->lock); | |
215 | *val = readq(&port_hdr->user_clk_freq_cmd1); | |
216 | spinlock_unlock(&port->lock); | |
217 | ||
218 | return 0; | |
219 | } | |
220 | ||
221 | static int port_set_userclk_freqcntrcmd(struct ifpga_port_hw *port, u64 val) | |
222 | { | |
223 | struct feature_port_header *port_hdr; | |
224 | ||
225 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
226 | PORT_FEATURE_ID_HEADER); | |
227 | ||
228 | spinlock_lock(&port->lock); | |
229 | writeq(val, &port_hdr->user_clk_freq_cmd1); | |
230 | spinlock_unlock(&port->lock); | |
231 | ||
232 | return 0; | |
233 | } | |
234 | ||
235 | static int port_get_userclk_freqsts(struct ifpga_port_hw *port, u64 *val) | |
236 | { | |
237 | struct feature_port_header *port_hdr; | |
238 | ||
239 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
240 | PORT_FEATURE_ID_HEADER); | |
241 | ||
242 | spinlock_lock(&port->lock); | |
243 | *val = readq(&port_hdr->user_clk_freq_sts0); | |
244 | spinlock_unlock(&port->lock); | |
245 | ||
246 | return 0; | |
247 | } | |
248 | ||
249 | static int port_get_userclk_freqcntrsts(struct ifpga_port_hw *port, u64 *val) | |
250 | { | |
251 | struct feature_port_header *port_hdr; | |
252 | ||
253 | port_hdr = get_port_feature_ioaddr_by_index(port, | |
254 | PORT_FEATURE_ID_HEADER); | |
255 | ||
256 | spinlock_lock(&port->lock); | |
257 | *val = readq(&port_hdr->user_clk_freq_sts1); | |
258 | spinlock_unlock(&port->lock); | |
259 | ||
260 | return 0; | |
261 | } | |
262 | ||
9f95a23c | 263 | static int port_hdr_init(struct ifpga_feature *feature) |
11fdf7f2 TL |
264 | { |
265 | struct ifpga_port_hw *port = feature->parent; | |
266 | ||
267 | dev_info(NULL, "port hdr Init.\n"); | |
268 | ||
269 | fpga_port_reset(port); | |
270 | ||
271 | return 0; | |
272 | } | |
273 | ||
9f95a23c | 274 | static void port_hdr_uinit(struct ifpga_feature *feature) |
11fdf7f2 TL |
275 | { |
276 | UNUSED(feature); | |
277 | ||
278 | dev_info(NULL, "port hdr uinit.\n"); | |
279 | } | |
280 | ||
9f95a23c TL |
281 | static int port_hdr_get_prop(struct ifpga_feature *feature, |
282 | struct feature_prop *prop) | |
11fdf7f2 TL |
283 | { |
284 | struct ifpga_port_hw *port = feature->parent; | |
285 | ||
286 | switch (prop->prop_id) { | |
287 | case PORT_HDR_PROP_REVISION: | |
288 | return port_get_revision(port, &prop->data); | |
289 | case PORT_HDR_PROP_PORTIDX: | |
290 | return port_get_portidx(port, &prop->data); | |
291 | case PORT_HDR_PROP_LATENCY_TOLERANCE: | |
292 | return port_get_latency_tolerance(port, &prop->data); | |
293 | case PORT_HDR_PROP_AP1_EVENT: | |
294 | return port_get_ap1_event(port, &prop->data); | |
295 | case PORT_HDR_PROP_AP2_EVENT: | |
296 | return port_get_ap2_event(port, &prop->data); | |
297 | case PORT_HDR_PROP_POWER_STATE: | |
298 | return port_get_power_state(port, &prop->data); | |
299 | case PORT_HDR_PROP_USERCLK_FREQCMD: | |
300 | return port_get_userclk_freqcmd(port, &prop->data); | |
301 | case PORT_HDR_PROP_USERCLK_FREQCNTRCMD: | |
302 | return port_get_userclk_freqcntrcmd(port, &prop->data); | |
303 | case PORT_HDR_PROP_USERCLK_FREQSTS: | |
304 | return port_get_userclk_freqsts(port, &prop->data); | |
305 | case PORT_HDR_PROP_USERCLK_CNTRSTS: | |
306 | return port_get_userclk_freqcntrsts(port, &prop->data); | |
307 | } | |
308 | ||
309 | return -ENOENT; | |
310 | } | |
311 | ||
9f95a23c TL |
312 | static int port_hdr_set_prop(struct ifpga_feature *feature, |
313 | struct feature_prop *prop) | |
11fdf7f2 TL |
314 | { |
315 | struct ifpga_port_hw *port = feature->parent; | |
316 | ||
317 | switch (prop->prop_id) { | |
318 | case PORT_HDR_PROP_AP1_EVENT: | |
319 | return port_set_ap1_event(port, prop->data); | |
320 | case PORT_HDR_PROP_AP2_EVENT: | |
321 | return port_set_ap2_event(port, prop->data); | |
322 | case PORT_HDR_PROP_USERCLK_FREQCMD: | |
323 | return port_set_userclk_freqcmd(port, prop->data); | |
324 | case PORT_HDR_PROP_USERCLK_FREQCNTRCMD: | |
325 | return port_set_userclk_freqcntrcmd(port, prop->data); | |
326 | } | |
327 | ||
328 | return -ENOENT; | |
329 | } | |
330 | ||
9f95a23c | 331 | struct ifpga_feature_ops ifpga_rawdev_port_hdr_ops = { |
11fdf7f2 TL |
332 | .init = port_hdr_init, |
333 | .uinit = port_hdr_uinit, | |
334 | .get_prop = port_hdr_get_prop, | |
335 | .set_prop = port_hdr_set_prop, | |
336 | }; | |
337 | ||
9f95a23c | 338 | static int port_stp_init(struct ifpga_feature *feature) |
11fdf7f2 TL |
339 | { |
340 | struct ifpga_port_hw *port = feature->parent; | |
341 | ||
342 | dev_info(NULL, "port stp Init.\n"); | |
343 | ||
344 | spinlock_lock(&port->lock); | |
345 | port->stp_addr = feature->addr; | |
346 | port->stp_size = feature->size; | |
347 | spinlock_unlock(&port->lock); | |
348 | ||
349 | return 0; | |
350 | } | |
351 | ||
9f95a23c | 352 | static void port_stp_uinit(struct ifpga_feature *feature) |
11fdf7f2 TL |
353 | { |
354 | UNUSED(feature); | |
355 | ||
356 | dev_info(NULL, "port stp uinit.\n"); | |
357 | } | |
358 | ||
9f95a23c | 359 | struct ifpga_feature_ops ifpga_rawdev_port_stp_ops = { |
11fdf7f2 TL |
360 | .init = port_stp_init, |
361 | .uinit = port_stp_uinit, | |
362 | }; | |
363 | ||
9f95a23c | 364 | static int port_uint_init(struct ifpga_feature *feature) |
11fdf7f2 TL |
365 | { |
366 | struct ifpga_port_hw *port = feature->parent; | |
367 | ||
368 | dev_info(NULL, "PORT UINT Init.\n"); | |
369 | ||
370 | spinlock_lock(&port->lock); | |
371 | if (feature->ctx_num) { | |
372 | port->capability |= FPGA_PORT_CAP_UAFU_IRQ; | |
373 | port->num_uafu_irqs = feature->ctx_num; | |
374 | } | |
375 | spinlock_unlock(&port->lock); | |
376 | ||
377 | return 0; | |
378 | } | |
379 | ||
9f95a23c | 380 | static void port_uint_uinit(struct ifpga_feature *feature) |
11fdf7f2 TL |
381 | { |
382 | UNUSED(feature); | |
383 | ||
384 | dev_info(NULL, "PORT UINT UInit.\n"); | |
385 | } | |
386 | ||
9f95a23c | 387 | struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = { |
11fdf7f2 TL |
388 | .init = port_uint_init, |
389 | .uinit = port_uint_uinit, | |
390 | }; | |
9f95a23c TL |
391 | |
392 | static int port_afu_init(struct ifpga_feature *feature) | |
393 | { | |
394 | UNUSED(feature); | |
395 | ||
396 | dev_info(NULL, "PORT AFU Init.\n"); | |
397 | ||
398 | return 0; | |
399 | } | |
400 | ||
401 | static void port_afu_uinit(struct ifpga_feature *feature) | |
402 | { | |
403 | UNUSED(feature); | |
404 | ||
405 | dev_info(NULL, "PORT AFU UInit.\n"); | |
406 | } | |
407 | ||
408 | struct ifpga_feature_ops ifpga_rawdev_port_afu_ops = { | |
409 | .init = port_afu_init, | |
410 | .uinit = port_afu_uinit, | |
411 | }; |