cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

machxo2-spi.c (9545B)


      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");