Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Mar 24-27, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.1.
  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
 61static inline u8 get_err(unsigned long *status)
 62{
 63	return (*status >> ERRBITS) & ERRMASK;
 64}
 65
 66static 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(&msg);
 80	spi_message_add_tail(&tx, &msg);
 81	spi_message_add_tail(&rx, &msg);
 82	ret = spi_sync(spi, &msg);
 83	if (ret)
 84		return ret;
 85
 86	*status = be32_to_cpu(*status);
 87
 88	return 0;
 89}
 90
 91#ifdef DEBUG
 92static 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
109static 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
119static 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);
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
135static 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(&msg);
146	tx[0].tx_buf = &erase;
147	tx[0].len = sizeof(erase);
148	spi_message_add_tail(&tx[0], &msg);
149	ret = spi_sync(spi, &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(&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(&tx[1], &msg);
163	ret = spi_sync(spi, &msg);
164	if (ret)
165		goto fail;
166
167	return 0;
168fail:
169	dev_err(&mgr->dev, "Cleanup failed\n");
170
171	return ret;
172}
173
174static 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);
180	if (!test_bit(BUSY, &status) && test_bit(DONE, &status) &&
181	    get_err(&status) == ENOERR)
182		return FPGA_MGR_STATE_OPERATING;
183
184	return FPGA_MGR_STATE_UNKNOWN;
185}
186
187static 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);
207	dump_status_reg(&status);
208	memset(tx, 0, sizeof(tx));
209	spi_message_init(&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(&tx[0], &msg);
215
216	tx[1].tx_buf = &erase;
217	tx[1].len = sizeof(erase);
218	spi_message_add_tail(&tx[1], &msg);
219	ret = spi_sync(spi, &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);
228	if (test_bit(FAIL, &status)) {
229		ret = -EINVAL;
230		goto fail;
231	}
232	dump_status_reg(&status);
233
234	spi_message_init(&msg);
235	tx[2].tx_buf = &initaddr;
236	tx[2].len = sizeof(initaddr);
237	spi_message_add_tail(&tx[2], &msg);
238	ret = spi_sync(spi, &msg);
239	if (ret)
240		goto fail;
241
242	get_status(spi, &status);
243	dump_status_reg(&status);
244
245	return 0;
246fail:
247	dev_err(&mgr->dev, "Error during FPGA init.\n");
248
249	return ret;
250}
251
252static 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);
268	dump_status_reg(&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(&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(&tx, &msg);
279		ret = spi_sync(spi, &msg);
280		if (ret) {
281			dev_err(&mgr->dev, "Error loading the bitstream.\n");
282			return ret;
283		}
284	}
285	get_status(spi, &status);
286	dump_status_reg(&status);
287
288	return 0;
289}
290
291static 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(&msg);
304	tx[0].tx_buf = &progdone;
305	tx[0].len = sizeof(progdone);
306	spi_message_add_tail(&tx[0], &msg);
307	ret = spi_sync(spi, &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);
315	dump_status_reg(&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(&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(&tx[1], &msg);
329		ret = spi_sync(spi, &msg);
330		if (ret)
331			goto fail;
332
333		/* check refresh status */
334		get_status(spi, &status);
335		dump_status_reg(&status);
336		if (!test_bit(BUSY, &status) && test_bit(DONE, &status) &&
337		    get_err(&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);
347	dump_status_reg(&status);
348
349	return 0;
350fail:
351	dev_err(&mgr->dev, "Refresh failed.\n");
352
353	return ret;
354}
355
356static 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
363static 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(dev, "Lattice MachXO2 SPI FPGA Manager",
374				     &machxo2_ops, spi);
375	return PTR_ERR_OR_ZERO(mgr);
376}
377
378#ifdef CONFIG_OF
379static const struct of_device_id of_match[] = {
380	{ .compatible = "lattice,machxo2-slave-spi", },
381	{}
382};
383MODULE_DEVICE_TABLE(of, of_match);
384#endif
385
386static const struct spi_device_id lattice_ids[] = {
387	{ "machxo2-slave-spi", 0 },
388	{ },
389};
390MODULE_DEVICE_TABLE(spi, lattice_ids);
391
392static 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
401module_spi_driver(machxo2_spi_driver)
402
403MODULE_AUTHOR("Paolo Pisati <p.pisati@gmail.com>");
404MODULE_DESCRIPTION("Load Lattice FPGA firmware over SPI");
405MODULE_LICENSE("GPL v2");