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

spi-falcon.c (10454B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *
      4 *  Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
      5 */
      6
      7#include <linux/module.h>
      8#include <linux/device.h>
      9#include <linux/platform_device.h>
     10#include <linux/spi/spi.h>
     11#include <linux/delay.h>
     12#include <linux/of.h>
     13#include <linux/of_platform.h>
     14
     15#include <lantiq_soc.h>
     16
     17#define DRV_NAME		"sflash-falcon"
     18
     19#define FALCON_SPI_XFER_BEGIN	(1 << 0)
     20#define FALCON_SPI_XFER_END	(1 << 1)
     21
     22/* Bus Read Configuration Register0 */
     23#define BUSRCON0		0x00000010
     24/* Bus Write Configuration Register0 */
     25#define BUSWCON0		0x00000018
     26/* Serial Flash Configuration Register */
     27#define SFCON			0x00000080
     28/* Serial Flash Time Register */
     29#define SFTIME			0x00000084
     30/* Serial Flash Status Register */
     31#define SFSTAT			0x00000088
     32/* Serial Flash Command Register */
     33#define SFCMD			0x0000008C
     34/* Serial Flash Address Register */
     35#define SFADDR			0x00000090
     36/* Serial Flash Data Register */
     37#define SFDATA			0x00000094
     38/* Serial Flash I/O Control Register */
     39#define SFIO			0x00000098
     40/* EBU Clock Control Register */
     41#define EBUCC			0x000000C4
     42
     43/* Dummy Phase Length */
     44#define SFCMD_DUMLEN_OFFSET	16
     45#define SFCMD_DUMLEN_MASK	0x000F0000
     46/* Chip Select */
     47#define SFCMD_CS_OFFSET		24
     48#define SFCMD_CS_MASK		0x07000000
     49/* field offset */
     50#define SFCMD_ALEN_OFFSET	20
     51#define SFCMD_ALEN_MASK		0x00700000
     52/* SCK Rise-edge Position */
     53#define SFTIME_SCKR_POS_OFFSET	8
     54#define SFTIME_SCKR_POS_MASK	0x00000F00
     55/* SCK Period */
     56#define SFTIME_SCK_PER_OFFSET	0
     57#define SFTIME_SCK_PER_MASK	0x0000000F
     58/* SCK Fall-edge Position */
     59#define SFTIME_SCKF_POS_OFFSET	12
     60#define SFTIME_SCKF_POS_MASK	0x0000F000
     61/* Device Size */
     62#define SFCON_DEV_SIZE_A23_0	0x03000000
     63#define SFCON_DEV_SIZE_MASK	0x0F000000
     64/* Read Data Position */
     65#define SFTIME_RD_POS_MASK	0x000F0000
     66/* Data Output */
     67#define SFIO_UNUSED_WD_MASK	0x0000000F
     68/* Command Opcode mask */
     69#define SFCMD_OPC_MASK		0x000000FF
     70/* dlen bytes of data to write */
     71#define SFCMD_DIR_WRITE		0x00000100
     72/* Data Length offset */
     73#define SFCMD_DLEN_OFFSET	9
     74/* Command Error */
     75#define SFSTAT_CMD_ERR		0x20000000
     76/* Access Command Pending */
     77#define SFSTAT_CMD_PEND		0x00400000
     78/* Frequency set to 100MHz. */
     79#define EBUCC_EBUDIV_SELF100	0x00000001
     80/* Serial Flash */
     81#define BUSRCON0_AGEN_SERIAL_FLASH	0xF0000000
     82/* 8-bit multiplexed */
     83#define BUSRCON0_PORTW_8_BIT_MUX	0x00000000
     84/* Serial Flash */
     85#define BUSWCON0_AGEN_SERIAL_FLASH	0xF0000000
     86/* Chip Select after opcode */
     87#define SFCMD_KEEP_CS_KEEP_SELECTED	0x00008000
     88
     89#define CLOCK_100M	100000000
     90#define CLOCK_50M	50000000
     91
     92struct falcon_sflash {
     93	u32 sfcmd; /* for caching of opcode, direction, ... */
     94	struct spi_master *master;
     95};
     96
     97int falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t,
     98		unsigned long flags)
     99{
    100	struct device *dev = &spi->dev;
    101	struct falcon_sflash *priv = spi_master_get_devdata(spi->master);
    102	const u8 *txp = t->tx_buf;
    103	u8 *rxp = t->rx_buf;
    104	unsigned int bytelen = ((8 * t->len + 7) / 8);
    105	unsigned int len, alen, dumlen;
    106	u32 val;
    107	enum {
    108		state_init,
    109		state_command_prepare,
    110		state_write,
    111		state_read,
    112		state_disable_cs,
    113		state_end
    114	} state = state_init;
    115
    116	do {
    117		switch (state) {
    118		case state_init: /* detect phase of upper layer sequence */
    119		{
    120			/* initial write ? */
    121			if (flags & FALCON_SPI_XFER_BEGIN) {
    122				if (!txp) {
    123					dev_err(dev,
    124						"BEGIN without tx data!\n");
    125					return -ENODATA;
    126				}
    127				/*
    128				 * Prepare the parts of the sfcmd register,
    129				 * which should not change during a sequence!
    130				 * Only exception are the length fields,
    131				 * especially alen and dumlen.
    132				 */
    133
    134				priv->sfcmd = ((spi->chip_select
    135						<< SFCMD_CS_OFFSET)
    136					       & SFCMD_CS_MASK);
    137				priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
    138				priv->sfcmd |= *txp;
    139				txp++;
    140				bytelen--;
    141				if (bytelen) {
    142					/*
    143					 * more data:
    144					 * maybe address and/or dummy
    145					 */
    146					state = state_command_prepare;
    147					break;
    148				} else {
    149					dev_dbg(dev, "write cmd %02X\n",
    150						priv->sfcmd & SFCMD_OPC_MASK);
    151				}
    152			}
    153			/* continued write ? */
    154			if (txp && bytelen) {
    155				state = state_write;
    156				break;
    157			}
    158			/* read data? */
    159			if (rxp && bytelen) {
    160				state = state_read;
    161				break;
    162			}
    163			/* end of sequence? */
    164			if (flags & FALCON_SPI_XFER_END)
    165				state = state_disable_cs;
    166			else
    167				state = state_end;
    168			break;
    169		}
    170		/* collect tx data for address and dummy phase */
    171		case state_command_prepare:
    172		{
    173			/* txp is valid, already checked */
    174			val = 0;
    175			alen = 0;
    176			dumlen = 0;
    177			while (bytelen > 0) {
    178				if (alen < 3) {
    179					val = (val << 8) | (*txp++);
    180					alen++;
    181				} else if ((dumlen < 15) && (*txp == 0)) {
    182					/*
    183					 * assume dummy bytes are set to 0
    184					 * from upper layer
    185					 */
    186					dumlen++;
    187					txp++;
    188				} else {
    189					break;
    190				}
    191				bytelen--;
    192			}
    193			priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
    194			priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
    195					 (dumlen << SFCMD_DUMLEN_OFFSET);
    196			if (alen > 0)
    197				ltq_ebu_w32(val, SFADDR);
    198
    199			dev_dbg(dev, "wr %02X, alen=%d (addr=%06X) dlen=%d\n",
    200				priv->sfcmd & SFCMD_OPC_MASK,
    201				alen, val, dumlen);
    202
    203			if (bytelen > 0) {
    204				/* continue with write */
    205				state = state_write;
    206			} else if (flags & FALCON_SPI_XFER_END) {
    207				/* end of sequence? */
    208				state = state_disable_cs;
    209			} else {
    210				/*
    211				 * go to end and expect another
    212				 * call (read or write)
    213				 */
    214				state = state_end;
    215			}
    216			break;
    217		}
    218		case state_write:
    219		{
    220			/* txp still valid */
    221			priv->sfcmd |= SFCMD_DIR_WRITE;
    222			len = 0;
    223			val = 0;
    224			do {
    225				if (bytelen--)
    226					val |= (*txp++) << (8 * len++);
    227				if ((flags & FALCON_SPI_XFER_END)
    228				    && (bytelen == 0)) {
    229					priv->sfcmd &=
    230						~SFCMD_KEEP_CS_KEEP_SELECTED;
    231				}
    232				if ((len == 4) || (bytelen == 0)) {
    233					ltq_ebu_w32(val, SFDATA);
    234					ltq_ebu_w32(priv->sfcmd
    235						| (len<<SFCMD_DLEN_OFFSET),
    236						SFCMD);
    237					len = 0;
    238					val = 0;
    239					priv->sfcmd &= ~(SFCMD_ALEN_MASK
    240							 | SFCMD_DUMLEN_MASK);
    241				}
    242			} while (bytelen);
    243			state = state_end;
    244			break;
    245		}
    246		case state_read:
    247		{
    248			/* read data */
    249			priv->sfcmd &= ~SFCMD_DIR_WRITE;
    250			do {
    251				if ((flags & FALCON_SPI_XFER_END)
    252				    && (bytelen <= 4)) {
    253					priv->sfcmd &=
    254						~SFCMD_KEEP_CS_KEEP_SELECTED;
    255				}
    256				len = (bytelen > 4) ? 4 : bytelen;
    257				bytelen -= len;
    258				ltq_ebu_w32(priv->sfcmd
    259					| (len << SFCMD_DLEN_OFFSET), SFCMD);
    260				priv->sfcmd &= ~(SFCMD_ALEN_MASK
    261						 | SFCMD_DUMLEN_MASK);
    262				do {
    263					val = ltq_ebu_r32(SFSTAT);
    264					if (val & SFSTAT_CMD_ERR) {
    265						/* reset error status */
    266						dev_err(dev, "SFSTAT: CMD_ERR");
    267						dev_err(dev, " (%x)\n", val);
    268						ltq_ebu_w32(SFSTAT_CMD_ERR,
    269							SFSTAT);
    270						return -EBADE;
    271					}
    272				} while (val & SFSTAT_CMD_PEND);
    273				val = ltq_ebu_r32(SFDATA);
    274				do {
    275					*rxp = (val & 0xFF);
    276					rxp++;
    277					val >>= 8;
    278					len--;
    279				} while (len);
    280			} while (bytelen);
    281			state = state_end;
    282			break;
    283		}
    284		case state_disable_cs:
    285		{
    286			priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
    287			ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET),
    288				SFCMD);
    289			val = ltq_ebu_r32(SFSTAT);
    290			if (val & SFSTAT_CMD_ERR) {
    291				/* reset error status */
    292				dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
    293				ltq_ebu_w32(SFSTAT_CMD_ERR, SFSTAT);
    294				return -EBADE;
    295			}
    296			state = state_end;
    297			break;
    298		}
    299		case state_end:
    300			break;
    301		}
    302	} while (state != state_end);
    303
    304	return 0;
    305}
    306
    307static int falcon_sflash_setup(struct spi_device *spi)
    308{
    309	unsigned int i;
    310	unsigned long flags;
    311
    312	spin_lock_irqsave(&ebu_lock, flags);
    313
    314	if (spi->max_speed_hz >= CLOCK_100M) {
    315		/* set EBU clock to 100 MHz */
    316		ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, EBUCC);
    317		i = 1; /* divider */
    318	} else {
    319		/* set EBU clock to 50 MHz */
    320		ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, EBUCC);
    321
    322		/* search for suitable divider */
    323		for (i = 1; i < 7; i++) {
    324			if (CLOCK_50M / i <= spi->max_speed_hz)
    325				break;
    326		}
    327	}
    328
    329	/* setup period of serial clock */
    330	ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK
    331		     | SFTIME_SCKR_POS_MASK
    332		     | SFTIME_SCK_PER_MASK,
    333		     (i << SFTIME_SCKR_POS_OFFSET)
    334		     | (i << (SFTIME_SCK_PER_OFFSET + 1)),
    335		     SFTIME);
    336
    337	/*
    338	 * set some bits of unused_wd, to not trigger HOLD/WP
    339	 * signals on non QUAD flashes
    340	 */
    341	ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), SFIO);
    342
    343	ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
    344			BUSRCON0);
    345	ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, BUSWCON0);
    346	/* set address wrap around to maximum for 24-bit addresses */
    347	ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, SFCON);
    348
    349	spin_unlock_irqrestore(&ebu_lock, flags);
    350
    351	return 0;
    352}
    353
    354static int falcon_sflash_xfer_one(struct spi_master *master,
    355					struct spi_message *m)
    356{
    357	struct falcon_sflash *priv = spi_master_get_devdata(master);
    358	struct spi_transfer *t;
    359	unsigned long spi_flags;
    360	unsigned long flags;
    361	int ret = 0;
    362
    363	priv->sfcmd = 0;
    364	m->actual_length = 0;
    365
    366	spi_flags = FALCON_SPI_XFER_BEGIN;
    367	list_for_each_entry(t, &m->transfers, transfer_list) {
    368		if (list_is_last(&t->transfer_list, &m->transfers))
    369			spi_flags |= FALCON_SPI_XFER_END;
    370
    371		spin_lock_irqsave(&ebu_lock, flags);
    372		ret = falcon_sflash_xfer(m->spi, t, spi_flags);
    373		spin_unlock_irqrestore(&ebu_lock, flags);
    374
    375		if (ret)
    376			break;
    377
    378		m->actual_length += t->len;
    379
    380		WARN_ON(t->delay.value || t->cs_change);
    381		spi_flags = 0;
    382	}
    383
    384	m->status = ret;
    385	spi_finalize_current_message(master);
    386
    387	return 0;
    388}
    389
    390static int falcon_sflash_probe(struct platform_device *pdev)
    391{
    392	struct falcon_sflash *priv;
    393	struct spi_master *master;
    394	int ret;
    395
    396	master = spi_alloc_master(&pdev->dev, sizeof(*priv));
    397	if (!master)
    398		return -ENOMEM;
    399
    400	priv = spi_master_get_devdata(master);
    401	priv->master = master;
    402
    403	master->mode_bits = SPI_MODE_3;
    404	master->flags = SPI_MASTER_HALF_DUPLEX;
    405	master->setup = falcon_sflash_setup;
    406	master->transfer_one_message = falcon_sflash_xfer_one;
    407	master->dev.of_node = pdev->dev.of_node;
    408
    409	ret = devm_spi_register_master(&pdev->dev, master);
    410	if (ret)
    411		spi_master_put(master);
    412	return ret;
    413}
    414
    415static const struct of_device_id falcon_sflash_match[] = {
    416	{ .compatible = "lantiq,sflash-falcon" },
    417	{},
    418};
    419MODULE_DEVICE_TABLE(of, falcon_sflash_match);
    420
    421static struct platform_driver falcon_sflash_driver = {
    422	.probe	= falcon_sflash_probe,
    423	.driver = {
    424		.name	= DRV_NAME,
    425		.of_match_table = falcon_sflash_match,
    426	}
    427};
    428
    429module_platform_driver(falcon_sflash_driver);
    430
    431MODULE_LICENSE("GPL");
    432MODULE_DESCRIPTION("Lantiq Falcon SPI/SFLASH controller driver");