1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Lattice MachXO2 Slave SPI Driver |
4 | * |
5 | * Manage Lattice FPGA firmware that is loaded over SPI using |
6 | * the slave serial configuration interface. |
7 | * |
8 | * Copyright (C) 2018 Paolo Pisati <p.pisati@gmail.com> |
9 | */ |
10 | |
11 | #include <linux/delay.h> |
12 | #include <linux/fpga/fpga-mgr.h> |
13 | #include <linux/gpio/consumer.h> |
14 | #include <linux/module.h> |
15 | #include <linux/of.h> |
16 | #include <linux/spi/spi.h> |
17 | |
18 | /* MachXO2 Programming Guide - sysCONFIG Programming Commands */ |
19 | #define IDCODE_PUB {0xe0, 0x00, 0x00, 0x00} |
20 | #define ISC_ENABLE {0xc6, 0x08, 0x00, 0x00} |
21 | #define ISC_ERASE {0x0e, 0x04, 0x00, 0x00} |
22 | #define ISC_PROGRAMDONE {0x5e, 0x00, 0x00, 0x00} |
23 | #define LSC_INITADDRESS {0x46, 0x00, 0x00, 0x00} |
24 | #define LSC_PROGINCRNV {0x70, 0x00, 0x00, 0x01} |
25 | #define LSC_READ_STATUS {0x3c, 0x00, 0x00, 0x00} |
26 | #define LSC_REFRESH {0x79, 0x00, 0x00, 0x00} |
27 | |
28 | /* |
29 | * Max CCLK in Slave SPI mode according to 'MachXO2 Family Data |
30 | * Sheet' sysCONFIG Port Timing Specifications (3-36) |
31 | */ |
32 | #define MACHXO2_MAX_SPEED 66000000 |
33 | |
34 | #define MACHXO2_LOW_DELAY_USEC 5 |
35 | #define MACHXO2_HIGH_DELAY_USEC 200 |
36 | #define MACHXO2_REFRESH_USEC 4800 |
37 | #define MACHXO2_MAX_BUSY_LOOP 128 |
38 | #define MACHXO2_MAX_REFRESH_LOOP 16 |
39 | |
40 | #define MACHXO2_PAGE_SIZE 16 |
41 | #define MACHXO2_BUF_SIZE (MACHXO2_PAGE_SIZE + 4) |
42 | |
43 | /* Status register bits, errors and error mask */ |
44 | #define BUSY 12 |
45 | #define DONE 8 |
46 | #define DVER 27 |
47 | #define ENAB 9 |
48 | #define ERRBITS 23 |
49 | #define ERRMASK 7 |
50 | #define FAIL 13 |
51 | |
52 | #define ENOERR 0 /* no error */ |
53 | #define EID 1 |
54 | #define ECMD 2 |
55 | #define ECRC 3 |
56 | #define EPREAM 4 /* preamble error */ |
57 | #define EABRT 5 /* abort error */ |
58 | #define EOVERFL 6 /* overflow error */ |
59 | #define ESDMEOF 7 /* SDM EOF */ |
60 | |
61 | static inline u8 get_err(unsigned long *status) |
62 | { |
63 | return (*status >> ERRBITS) & ERRMASK; |
64 | } |
65 | |
66 | static int get_status(struct spi_device *spi, unsigned long *status) |
67 | { |
68 | struct spi_message msg; |
69 | struct spi_transfer rx, tx; |
70 | static const u8 cmd[] = LSC_READ_STATUS; |
71 | int ret; |
72 | |
73 | memset(&rx, 0, sizeof(rx)); |
74 | memset(&tx, 0, sizeof(tx)); |
75 | tx.tx_buf = cmd; |
76 | tx.len = sizeof(cmd); |
77 | rx.rx_buf = status; |
78 | rx.len = 4; |
79 | spi_message_init(m: &msg); |
80 | spi_message_add_tail(t: &tx, m: &msg); |
81 | spi_message_add_tail(t: &rx, m: &msg); |
82 | ret = spi_sync(spi, message: &msg); |
83 | if (ret) |
84 | return ret; |
85 | |
86 | *status = be32_to_cpu(*status); |
87 | |
88 | return 0; |
89 | } |
90 | |
91 | #ifdef DEBUG |
92 | static const char *get_err_string(u8 err) |
93 | { |
94 | switch (err) { |
95 | case ENOERR: return "No Error" ; |
96 | case EID: return "ID ERR" ; |
97 | case ECMD: return "CMD ERR" ; |
98 | case ECRC: return "CRC ERR" ; |
99 | case EPREAM: return "Preamble ERR" ; |
100 | case EABRT: return "Abort ERR" ; |
101 | case EOVERFL: return "Overflow ERR" ; |
102 | case ESDMEOF: return "SDM EOF" ; |
103 | } |
104 | |
105 | return "Default switch case" ; |
106 | } |
107 | #endif |
108 | |
109 | static void dump_status_reg(unsigned long *status) |
110 | { |
111 | #ifdef DEBUG |
112 | pr_debug("machxo2 status: 0x%08lX - done=%d, cfgena=%d, busy=%d, fail=%d, devver=%d, err=%s\n" , |
113 | *status, test_bit(DONE, status), test_bit(ENAB, status), |
114 | test_bit(BUSY, status), test_bit(FAIL, status), |
115 | test_bit(DVER, status), get_err_string(get_err(status))); |
116 | #endif |
117 | } |
118 | |
119 | static int wait_until_not_busy(struct spi_device *spi) |
120 | { |
121 | unsigned long status; |
122 | int ret, loop = 0; |
123 | |
124 | do { |
125 | ret = get_status(spi, status: &status); |
126 | if (ret) |
127 | return ret; |
128 | if (++loop >= MACHXO2_MAX_BUSY_LOOP) |
129 | return -EBUSY; |
130 | } while (test_bit(BUSY, &status)); |
131 | |
132 | return 0; |
133 | } |
134 | |
135 | static int machxo2_cleanup(struct fpga_manager *mgr) |
136 | { |
137 | struct spi_device *spi = mgr->priv; |
138 | struct spi_message msg; |
139 | struct spi_transfer tx[2]; |
140 | static const u8 erase[] = ISC_ERASE; |
141 | static const u8 refresh[] = LSC_REFRESH; |
142 | int ret; |
143 | |
144 | memset(tx, 0, sizeof(tx)); |
145 | spi_message_init(m: &msg); |
146 | tx[0].tx_buf = &erase; |
147 | tx[0].len = sizeof(erase); |
148 | spi_message_add_tail(t: &tx[0], m: &msg); |
149 | ret = spi_sync(spi, message: &msg); |
150 | if (ret) |
151 | goto fail; |
152 | |
153 | ret = wait_until_not_busy(spi); |
154 | if (ret) |
155 | goto fail; |
156 | |
157 | spi_message_init(m: &msg); |
158 | tx[1].tx_buf = &refresh; |
159 | tx[1].len = sizeof(refresh); |
160 | tx[1].delay.value = MACHXO2_REFRESH_USEC; |
161 | tx[1].delay.unit = SPI_DELAY_UNIT_USECS; |
162 | spi_message_add_tail(t: &tx[1], m: &msg); |
163 | ret = spi_sync(spi, message: &msg); |
164 | if (ret) |
165 | goto fail; |
166 | |
167 | return 0; |
168 | fail: |
169 | dev_err(&mgr->dev, "Cleanup failed\n" ); |
170 | |
171 | return ret; |
172 | } |
173 | |
174 | static enum fpga_mgr_states machxo2_spi_state(struct fpga_manager *mgr) |
175 | { |
176 | struct spi_device *spi = mgr->priv; |
177 | unsigned long status; |
178 | |
179 | get_status(spi, status: &status); |
180 | if (!test_bit(BUSY, &status) && test_bit(DONE, &status) && |
181 | get_err(status: &status) == ENOERR) |
182 | return FPGA_MGR_STATE_OPERATING; |
183 | |
184 | return FPGA_MGR_STATE_UNKNOWN; |
185 | } |
186 | |
187 | static int machxo2_write_init(struct fpga_manager *mgr, |
188 | struct fpga_image_info *info, |
189 | const char *buf, size_t count) |
190 | { |
191 | struct spi_device *spi = mgr->priv; |
192 | struct spi_message msg; |
193 | struct spi_transfer tx[3]; |
194 | static const u8 enable[] = ISC_ENABLE; |
195 | static const u8 erase[] = ISC_ERASE; |
196 | static const u8 initaddr[] = LSC_INITADDRESS; |
197 | unsigned long status; |
198 | int ret; |
199 | |
200 | if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
201 | dev_err(&mgr->dev, |
202 | "Partial reconfiguration is not supported\n" ); |
203 | return -ENOTSUPP; |
204 | } |
205 | |
206 | get_status(spi, status: &status); |
207 | dump_status_reg(status: &status); |
208 | memset(tx, 0, sizeof(tx)); |
209 | spi_message_init(m: &msg); |
210 | tx[0].tx_buf = &enable; |
211 | tx[0].len = sizeof(enable); |
212 | tx[0].delay.value = MACHXO2_LOW_DELAY_USEC; |
213 | tx[0].delay.unit = SPI_DELAY_UNIT_USECS; |
214 | spi_message_add_tail(t: &tx[0], m: &msg); |
215 | |
216 | tx[1].tx_buf = &erase; |
217 | tx[1].len = sizeof(erase); |
218 | spi_message_add_tail(t: &tx[1], m: &msg); |
219 | ret = spi_sync(spi, message: &msg); |
220 | if (ret) |
221 | goto fail; |
222 | |
223 | ret = wait_until_not_busy(spi); |
224 | if (ret) |
225 | goto fail; |
226 | |
227 | get_status(spi, status: &status); |
228 | if (test_bit(FAIL, &status)) { |
229 | ret = -EINVAL; |
230 | goto fail; |
231 | } |
232 | dump_status_reg(status: &status); |
233 | |
234 | spi_message_init(m: &msg); |
235 | tx[2].tx_buf = &initaddr; |
236 | tx[2].len = sizeof(initaddr); |
237 | spi_message_add_tail(t: &tx[2], m: &msg); |
238 | ret = spi_sync(spi, message: &msg); |
239 | if (ret) |
240 | goto fail; |
241 | |
242 | get_status(spi, status: &status); |
243 | dump_status_reg(status: &status); |
244 | |
245 | return 0; |
246 | fail: |
247 | dev_err(&mgr->dev, "Error during FPGA init.\n" ); |
248 | |
249 | return ret; |
250 | } |
251 | |
252 | static int machxo2_write(struct fpga_manager *mgr, const char *buf, |
253 | size_t count) |
254 | { |
255 | struct spi_device *spi = mgr->priv; |
256 | struct spi_message msg; |
257 | struct spi_transfer tx; |
258 | static const u8 progincr[] = LSC_PROGINCRNV; |
259 | u8 payload[MACHXO2_BUF_SIZE]; |
260 | unsigned long status; |
261 | int i, ret; |
262 | |
263 | if (count % MACHXO2_PAGE_SIZE != 0) { |
264 | dev_err(&mgr->dev, "Malformed payload.\n" ); |
265 | return -EINVAL; |
266 | } |
267 | get_status(spi, status: &status); |
268 | dump_status_reg(status: &status); |
269 | memcpy(payload, &progincr, sizeof(progincr)); |
270 | for (i = 0; i < count; i += MACHXO2_PAGE_SIZE) { |
271 | memcpy(&payload[sizeof(progincr)], &buf[i], MACHXO2_PAGE_SIZE); |
272 | memset(&tx, 0, sizeof(tx)); |
273 | spi_message_init(m: &msg); |
274 | tx.tx_buf = payload; |
275 | tx.len = MACHXO2_BUF_SIZE; |
276 | tx.delay.value = MACHXO2_HIGH_DELAY_USEC; |
277 | tx.delay.unit = SPI_DELAY_UNIT_USECS; |
278 | spi_message_add_tail(t: &tx, m: &msg); |
279 | ret = spi_sync(spi, message: &msg); |
280 | if (ret) { |
281 | dev_err(&mgr->dev, "Error loading the bitstream.\n" ); |
282 | return ret; |
283 | } |
284 | } |
285 | get_status(spi, status: &status); |
286 | dump_status_reg(status: &status); |
287 | |
288 | return 0; |
289 | } |
290 | |
291 | static int machxo2_write_complete(struct fpga_manager *mgr, |
292 | struct fpga_image_info *info) |
293 | { |
294 | struct spi_device *spi = mgr->priv; |
295 | struct spi_message msg; |
296 | struct spi_transfer tx[2]; |
297 | static const u8 progdone[] = ISC_PROGRAMDONE; |
298 | static const u8 refresh[] = LSC_REFRESH; |
299 | unsigned long status; |
300 | int ret, refreshloop = 0; |
301 | |
302 | memset(tx, 0, sizeof(tx)); |
303 | spi_message_init(m: &msg); |
304 | tx[0].tx_buf = &progdone; |
305 | tx[0].len = sizeof(progdone); |
306 | spi_message_add_tail(t: &tx[0], m: &msg); |
307 | ret = spi_sync(spi, message: &msg); |
308 | if (ret) |
309 | goto fail; |
310 | ret = wait_until_not_busy(spi); |
311 | if (ret) |
312 | goto fail; |
313 | |
314 | get_status(spi, status: &status); |
315 | dump_status_reg(status: &status); |
316 | if (!test_bit(DONE, &status)) { |
317 | machxo2_cleanup(mgr); |
318 | ret = -EINVAL; |
319 | goto fail; |
320 | } |
321 | |
322 | do { |
323 | spi_message_init(m: &msg); |
324 | tx[1].tx_buf = &refresh; |
325 | tx[1].len = sizeof(refresh); |
326 | tx[1].delay.value = MACHXO2_REFRESH_USEC; |
327 | tx[1].delay.unit = SPI_DELAY_UNIT_USECS; |
328 | spi_message_add_tail(t: &tx[1], m: &msg); |
329 | ret = spi_sync(spi, message: &msg); |
330 | if (ret) |
331 | goto fail; |
332 | |
333 | /* check refresh status */ |
334 | get_status(spi, status: &status); |
335 | dump_status_reg(status: &status); |
336 | if (!test_bit(BUSY, &status) && test_bit(DONE, &status) && |
337 | get_err(status: &status) == ENOERR) |
338 | break; |
339 | if (++refreshloop == MACHXO2_MAX_REFRESH_LOOP) { |
340 | machxo2_cleanup(mgr); |
341 | ret = -EINVAL; |
342 | goto fail; |
343 | } |
344 | } while (1); |
345 | |
346 | get_status(spi, status: &status); |
347 | dump_status_reg(status: &status); |
348 | |
349 | return 0; |
350 | fail: |
351 | dev_err(&mgr->dev, "Refresh failed.\n" ); |
352 | |
353 | return ret; |
354 | } |
355 | |
356 | static const struct fpga_manager_ops machxo2_ops = { |
357 | .state = machxo2_spi_state, |
358 | .write_init = machxo2_write_init, |
359 | .write = machxo2_write, |
360 | .write_complete = machxo2_write_complete, |
361 | }; |
362 | |
363 | static int machxo2_spi_probe(struct spi_device *spi) |
364 | { |
365 | struct device *dev = &spi->dev; |
366 | struct fpga_manager *mgr; |
367 | |
368 | if (spi->max_speed_hz > MACHXO2_MAX_SPEED) { |
369 | dev_err(dev, "Speed is too high\n" ); |
370 | return -EINVAL; |
371 | } |
372 | |
373 | mgr = devm_fpga_mgr_register(parent: dev, name: "Lattice MachXO2 SPI FPGA Manager" , |
374 | mops: &machxo2_ops, priv: spi); |
375 | return PTR_ERR_OR_ZERO(ptr: mgr); |
376 | } |
377 | |
378 | #ifdef CONFIG_OF |
379 | static const struct of_device_id of_match[] = { |
380 | { .compatible = "lattice,machxo2-slave-spi" , }, |
381 | {} |
382 | }; |
383 | MODULE_DEVICE_TABLE(of, of_match); |
384 | #endif |
385 | |
386 | static const struct spi_device_id lattice_ids[] = { |
387 | { "machxo2-slave-spi" , 0 }, |
388 | { }, |
389 | }; |
390 | MODULE_DEVICE_TABLE(spi, lattice_ids); |
391 | |
392 | static struct spi_driver machxo2_spi_driver = { |
393 | .driver = { |
394 | .name = "machxo2-slave-spi" , |
395 | .of_match_table = of_match_ptr(of_match), |
396 | }, |
397 | .probe = machxo2_spi_probe, |
398 | .id_table = lattice_ids, |
399 | }; |
400 | |
401 | module_spi_driver(machxo2_spi_driver) |
402 | |
403 | MODULE_AUTHOR("Paolo Pisati <p.pisati@gmail.com>" ); |
404 | MODULE_DESCRIPTION("Load Lattice FPGA firmware over SPI" ); |
405 | MODULE_LICENSE("GPL v2" ); |
406 | |