Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/fpga/microchip-spi.c
26381 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Microchip Polarfire FPGA programming over slave SPI interface.
4
*/
5
6
#include <linux/unaligned.h>
7
#include <linux/delay.h>
8
#include <linux/fpga/fpga-mgr.h>
9
#include <linux/iopoll.h>
10
#include <linux/module.h>
11
#include <linux/of.h>
12
#include <linux/spi/spi.h>
13
14
#define MPF_SPI_ISC_ENABLE 0x0B
15
#define MPF_SPI_ISC_DISABLE 0x0C
16
#define MPF_SPI_READ_STATUS 0x00
17
#define MPF_SPI_READ_DATA 0x01
18
#define MPF_SPI_FRAME_INIT 0xAE
19
#define MPF_SPI_FRAME 0xEE
20
#define MPF_SPI_PRG_MODE 0x01
21
#define MPF_SPI_RELEASE 0x23
22
23
#define MPF_SPI_FRAME_SIZE 16
24
25
#define MPF_HEADER_SIZE_OFFSET 24
26
#define MPF_DATA_SIZE_OFFSET 55
27
28
#define MPF_LOOKUP_TABLE_RECORD_SIZE 9
29
#define MPF_LOOKUP_TABLE_BLOCK_ID_OFFSET 0
30
#define MPF_LOOKUP_TABLE_BLOCK_START_OFFSET 1
31
32
#define MPF_COMPONENTS_SIZE_ID 5
33
#define MPF_BITSTREAM_ID 8
34
35
#define MPF_BITS_PER_COMPONENT_SIZE 22
36
37
#define MPF_STATUS_POLL_TIMEOUT (2 * USEC_PER_SEC)
38
#define MPF_STATUS_BUSY BIT(0)
39
#define MPF_STATUS_READY BIT(1)
40
#define MPF_STATUS_SPI_VIOLATION BIT(2)
41
#define MPF_STATUS_SPI_ERROR BIT(3)
42
43
struct mpf_priv {
44
struct spi_device *spi;
45
bool program_mode;
46
u8 tx __aligned(ARCH_KMALLOC_MINALIGN);
47
u8 rx;
48
};
49
50
static int mpf_read_status(struct mpf_priv *priv)
51
{
52
/*
53
* HW status is returned on MISO in the first byte after CS went
54
* active. However, first reading can be inadequate, so we submit
55
* two identical SPI transfers and use result of the later one.
56
*/
57
struct spi_transfer xfers[2] = {
58
{
59
.tx_buf = &priv->tx,
60
.rx_buf = &priv->rx,
61
.len = 1,
62
.cs_change = 1,
63
}, {
64
.tx_buf = &priv->tx,
65
.rx_buf = &priv->rx,
66
.len = 1,
67
},
68
};
69
u8 status;
70
int ret;
71
72
priv->tx = MPF_SPI_READ_STATUS;
73
74
ret = spi_sync_transfer(priv->spi, xfers, 2);
75
if (ret)
76
return ret;
77
78
status = priv->rx;
79
80
if ((status & MPF_STATUS_SPI_VIOLATION) ||
81
(status & MPF_STATUS_SPI_ERROR))
82
return -EIO;
83
84
return status;
85
}
86
87
static enum fpga_mgr_states mpf_ops_state(struct fpga_manager *mgr)
88
{
89
struct mpf_priv *priv = mgr->priv;
90
bool program_mode;
91
int status;
92
93
program_mode = priv->program_mode;
94
status = mpf_read_status(priv);
95
96
if (!program_mode && !status)
97
return FPGA_MGR_STATE_OPERATING;
98
99
return FPGA_MGR_STATE_UNKNOWN;
100
}
101
102
static int mpf_ops_parse_header(struct fpga_manager *mgr,
103
struct fpga_image_info *info,
104
const char *buf, size_t count)
105
{
106
size_t component_size_byte_num, component_size_byte_off,
107
components_size_start, bitstream_start,
108
block_id_offset, block_start_offset;
109
u8 header_size, blocks_num, block_id;
110
u32 block_start, component_size;
111
u16 components_num, i;
112
113
if (!buf) {
114
dev_err(&mgr->dev, "Image buffer is not provided\n");
115
return -EINVAL;
116
}
117
118
header_size = *(buf + MPF_HEADER_SIZE_OFFSET);
119
if (header_size > count) {
120
info->header_size = header_size;
121
return -EAGAIN;
122
}
123
124
/*
125
* Go through look-up table to find out where actual bitstream starts
126
* and where sizes of components of the bitstream lies.
127
*/
128
blocks_num = *(buf + header_size - 1);
129
block_id_offset = header_size + MPF_LOOKUP_TABLE_BLOCK_ID_OFFSET;
130
block_start_offset = header_size + MPF_LOOKUP_TABLE_BLOCK_START_OFFSET;
131
132
header_size += blocks_num * MPF_LOOKUP_TABLE_RECORD_SIZE;
133
if (header_size > count) {
134
info->header_size = header_size;
135
return -EAGAIN;
136
}
137
138
components_size_start = 0;
139
bitstream_start = 0;
140
141
while (blocks_num--) {
142
block_id = *(buf + block_id_offset);
143
block_start = get_unaligned_le32(buf + block_start_offset);
144
145
switch (block_id) {
146
case MPF_BITSTREAM_ID:
147
bitstream_start = block_start;
148
info->header_size = block_start;
149
if (block_start > count)
150
return -EAGAIN;
151
152
break;
153
case MPF_COMPONENTS_SIZE_ID:
154
components_size_start = block_start;
155
break;
156
default:
157
break;
158
}
159
160
if (bitstream_start && components_size_start)
161
break;
162
163
block_id_offset += MPF_LOOKUP_TABLE_RECORD_SIZE;
164
block_start_offset += MPF_LOOKUP_TABLE_RECORD_SIZE;
165
}
166
167
if (!bitstream_start || !components_size_start) {
168
dev_err(&mgr->dev, "Failed to parse header look-up table\n");
169
return -EFAULT;
170
}
171
172
/*
173
* Parse bitstream size.
174
* Sizes of components of the bitstream are 22-bits long placed next
175
* to each other. Image header should be extended by now up to where
176
* actual bitstream starts, so no need for overflow check anymore.
177
*/
178
components_num = get_unaligned_le16(buf + MPF_DATA_SIZE_OFFSET);
179
180
for (i = 0; i < components_num; i++) {
181
component_size_byte_num =
182
(i * MPF_BITS_PER_COMPONENT_SIZE) / BITS_PER_BYTE;
183
component_size_byte_off =
184
(i * MPF_BITS_PER_COMPONENT_SIZE) % BITS_PER_BYTE;
185
186
component_size = get_unaligned_le32(buf +
187
components_size_start +
188
component_size_byte_num);
189
component_size >>= component_size_byte_off;
190
component_size &= GENMASK(MPF_BITS_PER_COMPONENT_SIZE - 1, 0);
191
192
info->data_size += component_size * MPF_SPI_FRAME_SIZE;
193
}
194
195
return 0;
196
}
197
198
static int mpf_poll_status(struct mpf_priv *priv, u8 mask)
199
{
200
int ret, status;
201
202
/*
203
* Busy poll HW status. Polling stops if any of the following
204
* conditions are met:
205
* - timeout is reached
206
* - mpf_read_status() returns an error
207
* - busy bit is cleared AND mask bits are set
208
*/
209
ret = read_poll_timeout(mpf_read_status, status,
210
(status < 0) ||
211
((status & (MPF_STATUS_BUSY | mask)) == mask),
212
0, MPF_STATUS_POLL_TIMEOUT, false, priv);
213
if (ret < 0)
214
return ret;
215
216
return status;
217
}
218
219
static int mpf_spi_write(struct mpf_priv *priv, const void *buf, size_t buf_size)
220
{
221
int status = mpf_poll_status(priv, 0);
222
223
if (status < 0)
224
return status;
225
226
return spi_write_then_read(priv->spi, buf, buf_size, NULL, 0);
227
}
228
229
static int mpf_spi_write_then_read(struct mpf_priv *priv,
230
const void *txbuf, size_t txbuf_size,
231
void *rxbuf, size_t rxbuf_size)
232
{
233
const u8 read_command[] = { MPF_SPI_READ_DATA };
234
int ret;
235
236
ret = mpf_spi_write(priv, txbuf, txbuf_size);
237
if (ret)
238
return ret;
239
240
ret = mpf_poll_status(priv, MPF_STATUS_READY);
241
if (ret < 0)
242
return ret;
243
244
return spi_write_then_read(priv->spi, read_command, sizeof(read_command),
245
rxbuf, rxbuf_size);
246
}
247
248
static int mpf_ops_write_init(struct fpga_manager *mgr,
249
struct fpga_image_info *info, const char *buf,
250
size_t count)
251
{
252
const u8 program_mode[] = { MPF_SPI_FRAME_INIT, MPF_SPI_PRG_MODE };
253
const u8 isc_en_command[] = { MPF_SPI_ISC_ENABLE };
254
struct mpf_priv *priv = mgr->priv;
255
struct device *dev = &mgr->dev;
256
u32 isc_ret = 0;
257
int ret;
258
259
if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
260
dev_err(dev, "Partial reconfiguration is not supported\n");
261
return -EOPNOTSUPP;
262
}
263
264
ret = mpf_spi_write_then_read(priv, isc_en_command, sizeof(isc_en_command),
265
&isc_ret, sizeof(isc_ret));
266
if (ret || isc_ret) {
267
dev_err(dev, "Failed to enable ISC: spi_ret %d, isc_ret %u\n",
268
ret, isc_ret);
269
return -EFAULT;
270
}
271
272
ret = mpf_spi_write(priv, program_mode, sizeof(program_mode));
273
if (ret) {
274
dev_err(dev, "Failed to enter program mode: %d\n", ret);
275
return ret;
276
}
277
278
priv->program_mode = true;
279
280
return 0;
281
}
282
283
static int mpf_spi_frame_write(struct mpf_priv *priv, const char *buf)
284
{
285
struct spi_transfer xfers[2] = {
286
{
287
.tx_buf = &priv->tx,
288
.len = 1,
289
}, {
290
.tx_buf = buf,
291
.len = MPF_SPI_FRAME_SIZE,
292
},
293
};
294
int ret;
295
296
ret = mpf_poll_status(priv, 0);
297
if (ret < 0)
298
return ret;
299
300
priv->tx = MPF_SPI_FRAME;
301
302
return spi_sync_transfer(priv->spi, xfers, ARRAY_SIZE(xfers));
303
}
304
305
static int mpf_ops_write(struct fpga_manager *mgr, const char *buf, size_t count)
306
{
307
struct mpf_priv *priv = mgr->priv;
308
struct device *dev = &mgr->dev;
309
int ret, i;
310
311
if (count % MPF_SPI_FRAME_SIZE) {
312
dev_err(dev, "Bitstream size is not a multiple of %d\n",
313
MPF_SPI_FRAME_SIZE);
314
return -EINVAL;
315
}
316
317
for (i = 0; i < count / MPF_SPI_FRAME_SIZE; i++) {
318
ret = mpf_spi_frame_write(priv, buf + i * MPF_SPI_FRAME_SIZE);
319
if (ret) {
320
dev_err(dev, "Failed to write bitstream frame %d/%zu\n",
321
i, count / MPF_SPI_FRAME_SIZE);
322
return ret;
323
}
324
}
325
326
return 0;
327
}
328
329
static int mpf_ops_write_complete(struct fpga_manager *mgr,
330
struct fpga_image_info *info)
331
{
332
const u8 isc_dis_command[] = { MPF_SPI_ISC_DISABLE };
333
const u8 release_command[] = { MPF_SPI_RELEASE };
334
struct mpf_priv *priv = mgr->priv;
335
struct device *dev = &mgr->dev;
336
int ret;
337
338
ret = mpf_spi_write(priv, isc_dis_command, sizeof(isc_dis_command));
339
if (ret) {
340
dev_err(dev, "Failed to disable ISC: %d\n", ret);
341
return ret;
342
}
343
344
usleep_range(1000, 2000);
345
346
ret = mpf_spi_write(priv, release_command, sizeof(release_command));
347
if (ret) {
348
dev_err(dev, "Failed to exit program mode: %d\n", ret);
349
return ret;
350
}
351
352
priv->program_mode = false;
353
354
return 0;
355
}
356
357
static const struct fpga_manager_ops mpf_ops = {
358
.state = mpf_ops_state,
359
.initial_header_size = 71,
360
.skip_header = true,
361
.parse_header = mpf_ops_parse_header,
362
.write_init = mpf_ops_write_init,
363
.write = mpf_ops_write,
364
.write_complete = mpf_ops_write_complete,
365
};
366
367
static int mpf_probe(struct spi_device *spi)
368
{
369
struct device *dev = &spi->dev;
370
struct fpga_manager *mgr;
371
struct mpf_priv *priv;
372
373
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
374
if (!priv)
375
return -ENOMEM;
376
377
priv->spi = spi;
378
379
mgr = devm_fpga_mgr_register(dev, "Microchip Polarfire SPI FPGA Manager",
380
&mpf_ops, priv);
381
382
return PTR_ERR_OR_ZERO(mgr);
383
}
384
385
static const struct spi_device_id mpf_spi_ids[] = {
386
{ .name = "mpf-spi-fpga-mgr", },
387
{},
388
};
389
MODULE_DEVICE_TABLE(spi, mpf_spi_ids);
390
391
#if IS_ENABLED(CONFIG_OF)
392
static const struct of_device_id mpf_of_ids[] = {
393
{ .compatible = "microchip,mpf-spi-fpga-mgr" },
394
{},
395
};
396
MODULE_DEVICE_TABLE(of, mpf_of_ids);
397
#endif /* IS_ENABLED(CONFIG_OF) */
398
399
static struct spi_driver mpf_driver = {
400
.probe = mpf_probe,
401
.id_table = mpf_spi_ids,
402
.driver = {
403
.name = "microchip_mpf_spi_fpga_mgr",
404
.of_match_table = of_match_ptr(mpf_of_ids),
405
},
406
};
407
408
module_spi_driver(mpf_driver);
409
410
MODULE_DESCRIPTION("Microchip Polarfire SPI FPGA Manager");
411
MODULE_AUTHOR("Ivan Bornyakov <[email protected]>");
412
MODULE_LICENSE("GPL");
413
414