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-xlp.c (11259B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2003-2015 Broadcom Corporation
      4 * All Rights Reserved
      5 */
      6#include <linux/acpi.h>
      7#include <linux/clk.h>
      8#include <linux/kernel.h>
      9#include <linux/module.h>
     10#include <linux/platform_device.h>
     11#include <linux/spi/spi.h>
     12#include <linux/interrupt.h>
     13
     14/* SPI Configuration Register */
     15#define XLP_SPI_CONFIG			0x00
     16#define XLP_SPI_CPHA			BIT(0)
     17#define XLP_SPI_CPOL			BIT(1)
     18#define XLP_SPI_CS_POL			BIT(2)
     19#define XLP_SPI_TXMISO_EN		BIT(3)
     20#define XLP_SPI_TXMOSI_EN		BIT(4)
     21#define XLP_SPI_RXMISO_EN		BIT(5)
     22#define XLP_SPI_CS_LSBFE		BIT(10)
     23#define XLP_SPI_RXCAP_EN		BIT(11)
     24
     25/* SPI Frequency Divider Register */
     26#define XLP_SPI_FDIV			0x04
     27
     28/* SPI Command Register */
     29#define XLP_SPI_CMD			0x08
     30#define XLP_SPI_CMD_IDLE_MASK		0x0
     31#define XLP_SPI_CMD_TX_MASK		0x1
     32#define XLP_SPI_CMD_RX_MASK		0x2
     33#define XLP_SPI_CMD_TXRX_MASK		0x3
     34#define XLP_SPI_CMD_CONT		BIT(4)
     35#define XLP_SPI_XFR_BITCNT_SHIFT	16
     36
     37/* SPI Status Register */
     38#define XLP_SPI_STATUS			0x0c
     39#define XLP_SPI_XFR_PENDING		BIT(0)
     40#define XLP_SPI_XFR_DONE		BIT(1)
     41#define XLP_SPI_TX_INT			BIT(2)
     42#define XLP_SPI_RX_INT			BIT(3)
     43#define XLP_SPI_TX_UF			BIT(4)
     44#define XLP_SPI_RX_OF			BIT(5)
     45#define XLP_SPI_STAT_MASK		0x3f
     46
     47/* SPI Interrupt Enable Register */
     48#define XLP_SPI_INTR_EN			0x10
     49#define XLP_SPI_INTR_DONE		BIT(0)
     50#define XLP_SPI_INTR_TXTH		BIT(1)
     51#define XLP_SPI_INTR_RXTH		BIT(2)
     52#define XLP_SPI_INTR_TXUF		BIT(3)
     53#define XLP_SPI_INTR_RXOF		BIT(4)
     54
     55/* SPI FIFO Threshold Register */
     56#define XLP_SPI_FIFO_THRESH		0x14
     57
     58/* SPI FIFO Word Count Register */
     59#define XLP_SPI_FIFO_WCNT		0x18
     60#define XLP_SPI_RXFIFO_WCNT_MASK	0xf
     61#define XLP_SPI_TXFIFO_WCNT_MASK	0xf0
     62#define XLP_SPI_TXFIFO_WCNT_SHIFT	4
     63
     64/* SPI Transmit Data FIFO Register */
     65#define XLP_SPI_TXDATA_FIFO		0x1c
     66
     67/* SPI Receive Data FIFO Register */
     68#define XLP_SPI_RXDATA_FIFO		0x20
     69
     70/* SPI System Control Register */
     71#define XLP_SPI_SYSCTRL			0x100
     72#define XLP_SPI_SYS_RESET		BIT(0)
     73#define XLP_SPI_SYS_CLKDIS		BIT(1)
     74#define XLP_SPI_SYS_PMEN		BIT(8)
     75
     76#define SPI_CS_OFFSET			0x40
     77#define XLP_SPI_TXRXTH			0x80
     78#define XLP_SPI_FIFO_SIZE		8
     79#define XLP_SPI_MAX_CS			4
     80#define XLP_SPI_DEFAULT_FREQ		133333333
     81#define XLP_SPI_FDIV_MIN		4
     82#define XLP_SPI_FDIV_MAX		65535
     83/*
     84 * SPI can transfer only 28 bytes properly at a time. So split the
     85 * transfer into 28 bytes size.
     86 */
     87#define XLP_SPI_XFER_SIZE		28
     88
     89struct xlp_spi_priv {
     90	struct device		dev;		/* device structure */
     91	void __iomem		*base;		/* spi registers base address */
     92	const u8		*tx_buf;	/* tx data buffer */
     93	u8			*rx_buf;	/* rx data buffer */
     94	int			tx_len;		/* tx xfer length */
     95	int			rx_len;		/* rx xfer length */
     96	int			txerrors;	/* TXFIFO underflow count */
     97	int			rxerrors;	/* RXFIFO overflow count */
     98	int			cs;		/* slave device chip select */
     99	u32			spi_clk;	/* spi clock frequency */
    100	bool			cmd_cont;	/* cs active */
    101	struct completion	done;		/* completion notification */
    102};
    103
    104static inline u32 xlp_spi_reg_read(struct xlp_spi_priv *priv,
    105				int cs, int regoff)
    106{
    107	return readl(priv->base + regoff + cs * SPI_CS_OFFSET);
    108}
    109
    110static inline void xlp_spi_reg_write(struct xlp_spi_priv *priv, int cs,
    111				int regoff, u32 val)
    112{
    113	writel(val, priv->base + regoff + cs * SPI_CS_OFFSET);
    114}
    115
    116static inline void xlp_spi_sysctl_write(struct xlp_spi_priv *priv,
    117				int regoff, u32 val)
    118{
    119	writel(val, priv->base + regoff);
    120}
    121
    122/*
    123 * Setup global SPI_SYSCTRL register for all SPI channels.
    124 */
    125static void xlp_spi_sysctl_setup(struct xlp_spi_priv *xspi)
    126{
    127	int cs;
    128
    129	for (cs = 0; cs < XLP_SPI_MAX_CS; cs++)
    130		xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL,
    131				XLP_SPI_SYS_RESET << cs);
    132	xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL, XLP_SPI_SYS_PMEN);
    133}
    134
    135static int xlp_spi_setup(struct spi_device *spi)
    136{
    137	struct xlp_spi_priv *xspi;
    138	u32 fdiv, cfg;
    139	int cs;
    140
    141	xspi = spi_master_get_devdata(spi->master);
    142	cs = spi->chip_select;
    143	/*
    144	 * The value of fdiv must be between 4 and 65535.
    145	 */
    146	fdiv = DIV_ROUND_UP(xspi->spi_clk, spi->max_speed_hz);
    147	if (fdiv > XLP_SPI_FDIV_MAX)
    148		fdiv = XLP_SPI_FDIV_MAX;
    149	else if (fdiv < XLP_SPI_FDIV_MIN)
    150		fdiv = XLP_SPI_FDIV_MIN;
    151
    152	xlp_spi_reg_write(xspi, cs, XLP_SPI_FDIV, fdiv);
    153	xlp_spi_reg_write(xspi, cs, XLP_SPI_FIFO_THRESH, XLP_SPI_TXRXTH);
    154	cfg = xlp_spi_reg_read(xspi, cs, XLP_SPI_CONFIG);
    155	if (spi->mode & SPI_CPHA)
    156		cfg |= XLP_SPI_CPHA;
    157	else
    158		cfg &= ~XLP_SPI_CPHA;
    159	if (spi->mode & SPI_CPOL)
    160		cfg |= XLP_SPI_CPOL;
    161	else
    162		cfg &= ~XLP_SPI_CPOL;
    163	if (!(spi->mode & SPI_CS_HIGH))
    164		cfg |= XLP_SPI_CS_POL;
    165	else
    166		cfg &= ~XLP_SPI_CS_POL;
    167	if (spi->mode & SPI_LSB_FIRST)
    168		cfg |= XLP_SPI_CS_LSBFE;
    169	else
    170		cfg &= ~XLP_SPI_CS_LSBFE;
    171
    172	cfg |= XLP_SPI_TXMOSI_EN | XLP_SPI_RXMISO_EN;
    173	if (fdiv == 4)
    174		cfg |= XLP_SPI_RXCAP_EN;
    175	xlp_spi_reg_write(xspi, cs, XLP_SPI_CONFIG, cfg);
    176
    177	return 0;
    178}
    179
    180static void xlp_spi_read_rxfifo(struct xlp_spi_priv *xspi)
    181{
    182	u32 rx_data, rxfifo_cnt;
    183	int i, j, nbytes;
    184
    185	rxfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT);
    186	rxfifo_cnt &= XLP_SPI_RXFIFO_WCNT_MASK;
    187	while (rxfifo_cnt) {
    188		rx_data = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_RXDATA_FIFO);
    189		j = 0;
    190		nbytes = min(xspi->rx_len, 4);
    191		for (i = nbytes - 1; i >= 0; i--, j++)
    192			xspi->rx_buf[i] = (rx_data >> (j * 8)) & 0xff;
    193
    194		xspi->rx_len -= nbytes;
    195		xspi->rx_buf += nbytes;
    196		rxfifo_cnt--;
    197	}
    198}
    199
    200static void xlp_spi_fill_txfifo(struct xlp_spi_priv *xspi)
    201{
    202	u32 tx_data, txfifo_cnt;
    203	int i, j, nbytes;
    204
    205	txfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT);
    206	txfifo_cnt &= XLP_SPI_TXFIFO_WCNT_MASK;
    207	txfifo_cnt >>= XLP_SPI_TXFIFO_WCNT_SHIFT;
    208	while (xspi->tx_len && (txfifo_cnt < XLP_SPI_FIFO_SIZE)) {
    209		j = 0;
    210		tx_data = 0;
    211		nbytes = min(xspi->tx_len, 4);
    212		for (i = nbytes - 1; i >= 0; i--, j++)
    213			tx_data |= xspi->tx_buf[i] << (j * 8);
    214
    215		xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_TXDATA_FIFO, tx_data);
    216		xspi->tx_len -= nbytes;
    217		xspi->tx_buf += nbytes;
    218		txfifo_cnt++;
    219	}
    220}
    221
    222static irqreturn_t xlp_spi_interrupt(int irq, void *dev_id)
    223{
    224	struct xlp_spi_priv *xspi = dev_id;
    225	u32 stat;
    226
    227	stat = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_STATUS) &
    228		XLP_SPI_STAT_MASK;
    229	if (!stat)
    230		return IRQ_NONE;
    231
    232	if (stat & XLP_SPI_TX_INT) {
    233		if (xspi->tx_len)
    234			xlp_spi_fill_txfifo(xspi);
    235		if (stat & XLP_SPI_TX_UF)
    236			xspi->txerrors++;
    237	}
    238
    239	if (stat & XLP_SPI_RX_INT) {
    240		if (xspi->rx_len)
    241			xlp_spi_read_rxfifo(xspi);
    242		if (stat & XLP_SPI_RX_OF)
    243			xspi->rxerrors++;
    244	}
    245
    246	/* write status back to clear interrupts */
    247	xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_STATUS, stat);
    248	if (stat & XLP_SPI_XFR_DONE)
    249		complete(&xspi->done);
    250
    251	return IRQ_HANDLED;
    252}
    253
    254static void xlp_spi_send_cmd(struct xlp_spi_priv *xspi, int xfer_len,
    255			int cmd_cont)
    256{
    257	u32 cmd = 0;
    258
    259	if (xspi->tx_buf)
    260		cmd |= XLP_SPI_CMD_TX_MASK;
    261	if (xspi->rx_buf)
    262		cmd |= XLP_SPI_CMD_RX_MASK;
    263	if (cmd_cont)
    264		cmd |= XLP_SPI_CMD_CONT;
    265	cmd |= ((xfer_len * 8 - 1) << XLP_SPI_XFR_BITCNT_SHIFT);
    266	xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_CMD, cmd);
    267}
    268
    269static int xlp_spi_xfer_block(struct  xlp_spi_priv *xs,
    270		const unsigned char *tx_buf,
    271		unsigned char *rx_buf, int xfer_len, int cmd_cont)
    272{
    273	int timeout;
    274	u32 intr_mask = 0;
    275
    276	xs->tx_buf = tx_buf;
    277	xs->rx_buf = rx_buf;
    278	xs->tx_len = (xs->tx_buf == NULL) ? 0 : xfer_len;
    279	xs->rx_len = (xs->rx_buf == NULL) ? 0 : xfer_len;
    280	xs->txerrors = xs->rxerrors = 0;
    281
    282	/* fill TXDATA_FIFO, then send the CMD */
    283	if (xs->tx_len)
    284		xlp_spi_fill_txfifo(xs);
    285
    286	xlp_spi_send_cmd(xs, xfer_len, cmd_cont);
    287
    288	/*
    289	 * We are getting some spurious tx interrupts, so avoid enabling
    290	 * tx interrupts when only rx is in process.
    291	 * Enable all the interrupts in tx case.
    292	 */
    293	if (xs->tx_len)
    294		intr_mask |= XLP_SPI_INTR_TXTH | XLP_SPI_INTR_TXUF |
    295				XLP_SPI_INTR_RXTH | XLP_SPI_INTR_RXOF;
    296	else
    297		intr_mask |= XLP_SPI_INTR_RXTH | XLP_SPI_INTR_RXOF;
    298
    299	intr_mask |= XLP_SPI_INTR_DONE;
    300	xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, intr_mask);
    301
    302	timeout = wait_for_completion_timeout(&xs->done,
    303				msecs_to_jiffies(1000));
    304	/* Disable interrupts */
    305	xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, 0x0);
    306	if (!timeout) {
    307		dev_err(&xs->dev, "xfer timedout!\n");
    308		goto out;
    309	}
    310	if (xs->txerrors || xs->rxerrors)
    311		dev_err(&xs->dev, "Over/Underflow rx %d tx %d xfer %d!\n",
    312				xs->rxerrors, xs->txerrors, xfer_len);
    313
    314	return xfer_len;
    315out:
    316	return -ETIMEDOUT;
    317}
    318
    319static int xlp_spi_txrx_bufs(struct xlp_spi_priv *xs, struct spi_transfer *t)
    320{
    321	int bytesleft, sz;
    322	unsigned char *rx_buf;
    323	const unsigned char *tx_buf;
    324
    325	tx_buf = t->tx_buf;
    326	rx_buf = t->rx_buf;
    327	bytesleft = t->len;
    328	while (bytesleft) {
    329		if (bytesleft > XLP_SPI_XFER_SIZE)
    330			sz = xlp_spi_xfer_block(xs, tx_buf, rx_buf,
    331					XLP_SPI_XFER_SIZE, 1);
    332		else
    333			sz = xlp_spi_xfer_block(xs, tx_buf, rx_buf,
    334					bytesleft, xs->cmd_cont);
    335		if (sz < 0)
    336			return sz;
    337		bytesleft -= sz;
    338		if (tx_buf)
    339			tx_buf += sz;
    340		if (rx_buf)
    341			rx_buf += sz;
    342	}
    343	return bytesleft;
    344}
    345
    346static int xlp_spi_transfer_one(struct spi_master *master,
    347					struct spi_device *spi,
    348					struct spi_transfer *t)
    349{
    350	struct xlp_spi_priv *xspi = spi_master_get_devdata(master);
    351	int ret = 0;
    352
    353	xspi->cs = spi->chip_select;
    354	xspi->dev = spi->dev;
    355
    356	if (spi_transfer_is_last(master, t))
    357		xspi->cmd_cont = 0;
    358	else
    359		xspi->cmd_cont = 1;
    360
    361	if (xlp_spi_txrx_bufs(xspi, t))
    362		ret = -EIO;
    363
    364	spi_finalize_current_transfer(master);
    365	return ret;
    366}
    367
    368static int xlp_spi_probe(struct platform_device *pdev)
    369{
    370	struct spi_master *master;
    371	struct xlp_spi_priv *xspi;
    372	struct clk *clk;
    373	int irq, err;
    374
    375	xspi = devm_kzalloc(&pdev->dev, sizeof(*xspi), GFP_KERNEL);
    376	if (!xspi)
    377		return -ENOMEM;
    378
    379	xspi->base = devm_platform_ioremap_resource(pdev, 0);
    380	if (IS_ERR(xspi->base))
    381		return PTR_ERR(xspi->base);
    382
    383	irq = platform_get_irq(pdev, 0);
    384	if (irq < 0)
    385		return irq;
    386	err = devm_request_irq(&pdev->dev, irq, xlp_spi_interrupt, 0,
    387			pdev->name, xspi);
    388	if (err) {
    389		dev_err(&pdev->dev, "unable to request irq %d\n", irq);
    390		return err;
    391	}
    392
    393	clk = devm_clk_get(&pdev->dev, NULL);
    394	if (IS_ERR(clk)) {
    395		dev_err(&pdev->dev, "could not get spi clock\n");
    396		return PTR_ERR(clk);
    397	}
    398
    399	xspi->spi_clk = clk_get_rate(clk);
    400
    401	master = spi_alloc_master(&pdev->dev, 0);
    402	if (!master) {
    403		dev_err(&pdev->dev, "could not alloc master\n");
    404		return -ENOMEM;
    405	}
    406
    407	master->bus_num = 0;
    408	master->num_chipselect = XLP_SPI_MAX_CS;
    409	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
    410	master->setup = xlp_spi_setup;
    411	master->transfer_one = xlp_spi_transfer_one;
    412	master->dev.of_node = pdev->dev.of_node;
    413
    414	init_completion(&xspi->done);
    415	spi_master_set_devdata(master, xspi);
    416	xlp_spi_sysctl_setup(xspi);
    417
    418	/* register spi controller */
    419	err = devm_spi_register_master(&pdev->dev, master);
    420	if (err) {
    421		dev_err(&pdev->dev, "spi register master failed!\n");
    422		spi_master_put(master);
    423		return err;
    424	}
    425
    426	return 0;
    427}
    428
    429#ifdef CONFIG_ACPI
    430static const struct acpi_device_id xlp_spi_acpi_match[] = {
    431	{ "BRCM900D", 0 },
    432	{ "CAV900D",  0 },
    433	{ },
    434};
    435MODULE_DEVICE_TABLE(acpi, xlp_spi_acpi_match);
    436#endif
    437
    438static struct platform_driver xlp_spi_driver = {
    439	.probe	= xlp_spi_probe,
    440	.driver = {
    441		.name	= "xlp-spi",
    442		.acpi_match_table = ACPI_PTR(xlp_spi_acpi_match),
    443	},
    444};
    445module_platform_driver(xlp_spi_driver);
    446
    447MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");
    448MODULE_DESCRIPTION("Netlogic XLP SPI controller driver");
    449MODULE_LICENSE("GPL v2");