Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/fpga/stratix10-soc.c
26381 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* FPGA Manager Driver for Intel Stratix10 SoC
4
*
5
* Copyright (C) 2018 Intel Corporation
6
*/
7
#include <linux/completion.h>
8
#include <linux/fpga/fpga-mgr.h>
9
#include <linux/firmware/intel/stratix10-svc-client.h>
10
#include <linux/module.h>
11
#include <linux/of.h>
12
#include <linux/of_platform.h>
13
#include <linux/platform_device.h>
14
15
/*
16
* FPGA programming requires a higher level of privilege (EL3), per the SoC
17
* design.
18
*/
19
#define NUM_SVC_BUFS 4
20
#define SVC_BUF_SIZE SZ_512K
21
22
/* Indicates buffer is in use if set */
23
#define SVC_BUF_LOCK 0
24
25
#define S10_BUFFER_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_BUFFER_TIMEOUT_MS))
26
#define S10_RECONFIG_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_REQUEST_TIMEOUT_MS))
27
28
/*
29
* struct s10_svc_buf
30
* buf: virtual address of buf provided by service layer
31
* lock: locked if buffer is in use
32
*/
33
struct s10_svc_buf {
34
char *buf;
35
unsigned long lock;
36
};
37
38
struct s10_priv {
39
struct stratix10_svc_chan *chan;
40
struct stratix10_svc_client client;
41
struct completion status_return_completion;
42
struct s10_svc_buf svc_bufs[NUM_SVC_BUFS];
43
unsigned long status;
44
};
45
46
static int s10_svc_send_msg(struct s10_priv *priv,
47
enum stratix10_svc_command_code command,
48
void *payload, u32 payload_length)
49
{
50
struct stratix10_svc_chan *chan = priv->chan;
51
struct device *dev = priv->client.dev;
52
struct stratix10_svc_client_msg msg;
53
int ret;
54
55
dev_dbg(dev, "%s cmd=%d payload=%p length=%d\n",
56
__func__, command, payload, payload_length);
57
58
msg.command = command;
59
msg.payload = payload;
60
msg.payload_length = payload_length;
61
62
ret = stratix10_svc_send(chan, &msg);
63
dev_dbg(dev, "stratix10_svc_send returned status %d\n", ret);
64
65
return ret;
66
}
67
68
/*
69
* Free buffers allocated from the service layer's pool that are not in use.
70
* Return true when all buffers are freed.
71
*/
72
static bool s10_free_buffers(struct fpga_manager *mgr)
73
{
74
struct s10_priv *priv = mgr->priv;
75
uint num_free = 0;
76
uint i;
77
78
for (i = 0; i < NUM_SVC_BUFS; i++) {
79
if (!priv->svc_bufs[i].buf) {
80
num_free++;
81
continue;
82
}
83
84
if (!test_and_set_bit_lock(SVC_BUF_LOCK,
85
&priv->svc_bufs[i].lock)) {
86
stratix10_svc_free_memory(priv->chan,
87
priv->svc_bufs[i].buf);
88
priv->svc_bufs[i].buf = NULL;
89
num_free++;
90
}
91
}
92
93
return num_free == NUM_SVC_BUFS;
94
}
95
96
/*
97
* Returns count of how many buffers are not in use.
98
*/
99
static uint s10_free_buffer_count(struct fpga_manager *mgr)
100
{
101
struct s10_priv *priv = mgr->priv;
102
uint num_free = 0;
103
uint i;
104
105
for (i = 0; i < NUM_SVC_BUFS; i++)
106
if (!priv->svc_bufs[i].buf)
107
num_free++;
108
109
return num_free;
110
}
111
112
/*
113
* s10_unlock_bufs
114
* Given the returned buffer address, match that address to our buffer struct
115
* and unlock that buffer. This marks it as available to be refilled and sent
116
* (or freed).
117
* priv: private data
118
* kaddr: kernel address of buffer that was returned from service layer
119
*/
120
static void s10_unlock_bufs(struct s10_priv *priv, void *kaddr)
121
{
122
uint i;
123
124
if (!kaddr)
125
return;
126
127
for (i = 0; i < NUM_SVC_BUFS; i++)
128
if (priv->svc_bufs[i].buf == kaddr) {
129
clear_bit_unlock(SVC_BUF_LOCK,
130
&priv->svc_bufs[i].lock);
131
return;
132
}
133
134
WARN(1, "Unknown buffer returned from service layer %p\n", kaddr);
135
}
136
137
/*
138
* s10_receive_callback - callback for service layer to use to provide client
139
* (this driver) messages received through the mailbox.
140
* client: service layer client struct
141
* data: message from service layer
142
*/
143
static void s10_receive_callback(struct stratix10_svc_client *client,
144
struct stratix10_svc_cb_data *data)
145
{
146
struct s10_priv *priv = client->priv;
147
u32 status;
148
int i;
149
150
WARN_ONCE(!data, "%s: stratix10_svc_rc_data = NULL", __func__);
151
152
status = data->status;
153
154
/*
155
* Here we set status bits as we receive them. Elsewhere, we always use
156
* test_and_clear_bit() to check status in priv->status
157
*/
158
for (i = 0; i <= SVC_STATUS_ERROR; i++)
159
if (status & (1 << i))
160
set_bit(i, &priv->status);
161
162
if (status & BIT(SVC_STATUS_BUFFER_DONE)) {
163
s10_unlock_bufs(priv, data->kaddr1);
164
s10_unlock_bufs(priv, data->kaddr2);
165
s10_unlock_bufs(priv, data->kaddr3);
166
}
167
168
complete(&priv->status_return_completion);
169
}
170
171
/*
172
* s10_ops_write_init - prepare for FPGA reconfiguration by requesting
173
* partial reconfig and allocating buffers from the service layer.
174
*/
175
static int s10_ops_write_init(struct fpga_manager *mgr,
176
struct fpga_image_info *info,
177
const char *buf, size_t count)
178
{
179
struct s10_priv *priv = mgr->priv;
180
struct device *dev = priv->client.dev;
181
struct stratix10_svc_command_config_type ctype;
182
char *kbuf;
183
uint i;
184
int ret;
185
186
ctype.flags = 0;
187
if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
188
dev_dbg(dev, "Requesting partial reconfiguration.\n");
189
ctype.flags |= BIT(COMMAND_RECONFIG_FLAG_PARTIAL);
190
} else {
191
dev_dbg(dev, "Requesting full reconfiguration.\n");
192
}
193
194
reinit_completion(&priv->status_return_completion);
195
ret = s10_svc_send_msg(priv, COMMAND_RECONFIG,
196
&ctype, sizeof(ctype));
197
if (ret < 0)
198
goto init_done;
199
200
ret = wait_for_completion_timeout(
201
&priv->status_return_completion, S10_RECONFIG_TIMEOUT);
202
if (!ret) {
203
dev_err(dev, "timeout waiting for RECONFIG_REQUEST\n");
204
ret = -ETIMEDOUT;
205
goto init_done;
206
}
207
208
ret = 0;
209
if (!test_and_clear_bit(SVC_STATUS_OK, &priv->status)) {
210
ret = -ETIMEDOUT;
211
goto init_done;
212
}
213
214
/* Allocate buffers from the service layer's pool. */
215
for (i = 0; i < NUM_SVC_BUFS; i++) {
216
kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE);
217
if (IS_ERR(kbuf)) {
218
s10_free_buffers(mgr);
219
ret = PTR_ERR(kbuf);
220
goto init_done;
221
}
222
223
priv->svc_bufs[i].buf = kbuf;
224
priv->svc_bufs[i].lock = 0;
225
}
226
227
init_done:
228
stratix10_svc_done(priv->chan);
229
return ret;
230
}
231
232
/*
233
* s10_send_buf - send a buffer to the service layer queue
234
* mgr: fpga manager struct
235
* buf: fpga image buffer
236
* count: size of buf in bytes
237
* Returns # of bytes transferred or -ENOBUFS if the all the buffers are in use
238
* or if the service queue is full. Never returns 0.
239
*/
240
static int s10_send_buf(struct fpga_manager *mgr, const char *buf, size_t count)
241
{
242
struct s10_priv *priv = mgr->priv;
243
struct device *dev = priv->client.dev;
244
void *svc_buf;
245
size_t xfer_sz;
246
int ret;
247
uint i;
248
249
/* get/lock a buffer that that's not being used */
250
for (i = 0; i < NUM_SVC_BUFS; i++)
251
if (!test_and_set_bit_lock(SVC_BUF_LOCK,
252
&priv->svc_bufs[i].lock))
253
break;
254
255
if (i == NUM_SVC_BUFS)
256
return -ENOBUFS;
257
258
xfer_sz = count < SVC_BUF_SIZE ? count : SVC_BUF_SIZE;
259
260
svc_buf = priv->svc_bufs[i].buf;
261
memcpy(svc_buf, buf, xfer_sz);
262
ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_DATA_SUBMIT,
263
svc_buf, xfer_sz);
264
if (ret < 0) {
265
dev_err(dev,
266
"Error while sending data to service layer (%d)", ret);
267
clear_bit_unlock(SVC_BUF_LOCK, &priv->svc_bufs[i].lock);
268
return ret;
269
}
270
271
return xfer_sz;
272
}
273
274
/*
275
* Send an FPGA image to privileged layers to write to the FPGA. When done
276
* sending, free all service layer buffers we allocated in write_init.
277
*/
278
static int s10_ops_write(struct fpga_manager *mgr, const char *buf,
279
size_t count)
280
{
281
struct s10_priv *priv = mgr->priv;
282
struct device *dev = priv->client.dev;
283
long wait_status;
284
int sent = 0;
285
int ret = 0;
286
287
/*
288
* Loop waiting for buffers to be returned. When a buffer is returned,
289
* reuse it to send more data or free if if all data has been sent.
290
*/
291
while (count > 0 || s10_free_buffer_count(mgr) != NUM_SVC_BUFS) {
292
reinit_completion(&priv->status_return_completion);
293
294
if (count > 0) {
295
sent = s10_send_buf(mgr, buf, count);
296
if (sent < 0)
297
continue;
298
299
count -= sent;
300
buf += sent;
301
} else {
302
if (s10_free_buffers(mgr))
303
return 0;
304
305
ret = s10_svc_send_msg(
306
priv, COMMAND_RECONFIG_DATA_CLAIM,
307
NULL, 0);
308
if (ret < 0)
309
break;
310
}
311
312
/*
313
* If callback hasn't already happened, wait for buffers to be
314
* returned from service layer
315
*/
316
wait_status = 1; /* not timed out */
317
if (!priv->status)
318
wait_status = wait_for_completion_timeout(
319
&priv->status_return_completion,
320
S10_BUFFER_TIMEOUT);
321
322
if (test_and_clear_bit(SVC_STATUS_BUFFER_DONE, &priv->status) ||
323
test_and_clear_bit(SVC_STATUS_BUFFER_SUBMITTED,
324
&priv->status)) {
325
ret = 0;
326
continue;
327
}
328
329
if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {
330
dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");
331
ret = -EFAULT;
332
break;
333
}
334
335
if (!wait_status) {
336
dev_err(dev, "timeout waiting for svc layer buffers\n");
337
ret = -ETIMEDOUT;
338
break;
339
}
340
}
341
342
if (!s10_free_buffers(mgr))
343
dev_err(dev, "%s not all buffers were freed\n", __func__);
344
345
return ret;
346
}
347
348
static int s10_ops_write_complete(struct fpga_manager *mgr,
349
struct fpga_image_info *info)
350
{
351
struct s10_priv *priv = mgr->priv;
352
struct device *dev = priv->client.dev;
353
unsigned long timeout;
354
int ret;
355
356
timeout = usecs_to_jiffies(info->config_complete_timeout_us);
357
358
do {
359
reinit_completion(&priv->status_return_completion);
360
361
ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_STATUS, NULL, 0);
362
if (ret < 0)
363
break;
364
365
ret = wait_for_completion_timeout(
366
&priv->status_return_completion, timeout);
367
if (!ret) {
368
dev_err(dev,
369
"timeout waiting for RECONFIG_COMPLETED\n");
370
ret = -ETIMEDOUT;
371
break;
372
}
373
/* Not error or timeout, so ret is # of jiffies until timeout */
374
timeout = ret;
375
ret = 0;
376
377
if (test_and_clear_bit(SVC_STATUS_COMPLETED, &priv->status))
378
break;
379
380
if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {
381
dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");
382
ret = -EFAULT;
383
break;
384
}
385
} while (1);
386
387
stratix10_svc_done(priv->chan);
388
389
return ret;
390
}
391
392
static const struct fpga_manager_ops s10_ops = {
393
.write_init = s10_ops_write_init,
394
.write = s10_ops_write,
395
.write_complete = s10_ops_write_complete,
396
};
397
398
static int s10_probe(struct platform_device *pdev)
399
{
400
struct device *dev = &pdev->dev;
401
struct s10_priv *priv;
402
struct fpga_manager *mgr;
403
int ret;
404
405
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
406
if (!priv)
407
return -ENOMEM;
408
409
priv->client.dev = dev;
410
priv->client.receive_cb = s10_receive_callback;
411
priv->client.priv = priv;
412
413
priv->chan = stratix10_svc_request_channel_byname(&priv->client,
414
SVC_CLIENT_FPGA);
415
if (IS_ERR(priv->chan)) {
416
dev_err(dev, "couldn't get service channel (%s)\n",
417
SVC_CLIENT_FPGA);
418
return PTR_ERR(priv->chan);
419
}
420
421
init_completion(&priv->status_return_completion);
422
423
mgr = fpga_mgr_register(dev, "Stratix10 SOC FPGA Manager",
424
&s10_ops, priv);
425
if (IS_ERR(mgr)) {
426
dev_err(dev, "unable to register FPGA manager\n");
427
ret = PTR_ERR(mgr);
428
goto probe_err;
429
}
430
431
platform_set_drvdata(pdev, mgr);
432
return 0;
433
434
probe_err:
435
stratix10_svc_free_channel(priv->chan);
436
return ret;
437
}
438
439
static void s10_remove(struct platform_device *pdev)
440
{
441
struct fpga_manager *mgr = platform_get_drvdata(pdev);
442
struct s10_priv *priv = mgr->priv;
443
444
fpga_mgr_unregister(mgr);
445
stratix10_svc_free_channel(priv->chan);
446
}
447
448
static const struct of_device_id s10_of_match[] = {
449
{.compatible = "intel,stratix10-soc-fpga-mgr"},
450
{.compatible = "intel,agilex-soc-fpga-mgr"},
451
{},
452
};
453
454
MODULE_DEVICE_TABLE(of, s10_of_match);
455
456
static struct platform_driver s10_driver = {
457
.probe = s10_probe,
458
.remove = s10_remove,
459
.driver = {
460
.name = "Stratix10 SoC FPGA manager",
461
.of_match_table = of_match_ptr(s10_of_match),
462
},
463
};
464
465
static int __init s10_init(void)
466
{
467
struct device_node *fw_np;
468
struct device_node *np;
469
int ret;
470
471
fw_np = of_find_node_by_name(NULL, "svc");
472
if (!fw_np)
473
return -ENODEV;
474
475
of_node_get(fw_np);
476
np = of_find_matching_node(fw_np, s10_of_match);
477
if (!np) {
478
of_node_put(fw_np);
479
return -ENODEV;
480
}
481
482
of_node_put(np);
483
ret = of_platform_populate(fw_np, s10_of_match, NULL, NULL);
484
of_node_put(fw_np);
485
if (ret)
486
return ret;
487
488
return platform_driver_register(&s10_driver);
489
}
490
491
static void __exit s10_exit(void)
492
{
493
return platform_driver_unregister(&s10_driver);
494
}
495
496
module_init(s10_init);
497
module_exit(s10_exit);
498
499
MODULE_AUTHOR("Alan Tull <[email protected]>");
500
MODULE_DESCRIPTION("Intel Stratix 10 SOC FPGA Manager");
501
MODULE_LICENSE("GPL v2");
502
503