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-npcm-pspi.c (10544B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (c) 2018 Nuvoton Technology corporation.
      3
      4#include <linux/kernel.h>
      5#include <linux/bitfield.h>
      6#include <linux/bitops.h>
      7#include <linux/clk.h>
      8#include <linux/interrupt.h>
      9#include <linux/io.h>
     10#include <linux/module.h>
     11#include <linux/platform_device.h>
     12#include <linux/spi/spi.h>
     13#include <linux/reset.h>
     14
     15#include <asm/unaligned.h>
     16
     17#include <linux/regmap.h>
     18#include <linux/mfd/syscon.h>
     19
     20struct npcm_pspi {
     21	struct completion xfer_done;
     22	struct reset_control *reset;
     23	struct spi_master *master;
     24	unsigned int tx_bytes;
     25	unsigned int rx_bytes;
     26	void __iomem *base;
     27	bool is_save_param;
     28	u8 bits_per_word;
     29	const u8 *tx_buf;
     30	struct clk *clk;
     31	u32 speed_hz;
     32	u8 *rx_buf;
     33	u16 mode;
     34	u32 id;
     35};
     36
     37#define DRIVER_NAME "npcm-pspi"
     38
     39#define NPCM_PSPI_DATA		0x00
     40#define NPCM_PSPI_CTL1		0x02
     41#define NPCM_PSPI_STAT		0x04
     42
     43/* definitions for control and status register */
     44#define NPCM_PSPI_CTL1_SPIEN	BIT(0)
     45#define NPCM_PSPI_CTL1_MOD	BIT(2)
     46#define NPCM_PSPI_CTL1_EIR	BIT(5)
     47#define NPCM_PSPI_CTL1_EIW	BIT(6)
     48#define NPCM_PSPI_CTL1_SCM	BIT(7)
     49#define NPCM_PSPI_CTL1_SCIDL	BIT(8)
     50#define NPCM_PSPI_CTL1_SCDV6_0	GENMASK(15, 9)
     51
     52#define NPCM_PSPI_STAT_BSY	BIT(0)
     53#define NPCM_PSPI_STAT_RBF	BIT(1)
     54
     55/* general definitions */
     56#define NPCM_PSPI_TIMEOUT_MS		2000
     57#define NPCM_PSPI_MAX_CLK_DIVIDER	256
     58#define NPCM_PSPI_MIN_CLK_DIVIDER	4
     59#define NPCM_PSPI_DEFAULT_CLK		25000000
     60
     61static inline unsigned int bytes_per_word(unsigned int bits)
     62{
     63	return bits <= 8 ? 1 : 2;
     64}
     65
     66static inline void npcm_pspi_irq_enable(struct npcm_pspi *priv, u16 mask)
     67{
     68	u16 val;
     69
     70	val = ioread16(priv->base + NPCM_PSPI_CTL1);
     71	val |= mask;
     72	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
     73}
     74
     75static inline void npcm_pspi_irq_disable(struct npcm_pspi *priv, u16 mask)
     76{
     77	u16 val;
     78
     79	val = ioread16(priv->base + NPCM_PSPI_CTL1);
     80	val &= ~mask;
     81	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
     82}
     83
     84static inline void npcm_pspi_enable(struct npcm_pspi *priv)
     85{
     86	u16 val;
     87
     88	val = ioread16(priv->base + NPCM_PSPI_CTL1);
     89	val |= NPCM_PSPI_CTL1_SPIEN;
     90	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
     91}
     92
     93static inline void npcm_pspi_disable(struct npcm_pspi *priv)
     94{
     95	u16 val;
     96
     97	val = ioread16(priv->base + NPCM_PSPI_CTL1);
     98	val &= ~NPCM_PSPI_CTL1_SPIEN;
     99	iowrite16(val, priv->base + NPCM_PSPI_CTL1);
    100}
    101
    102static void npcm_pspi_set_mode(struct spi_device *spi)
    103{
    104	struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
    105	u16 regtemp;
    106	u16 mode_val;
    107
    108	switch (spi->mode & SPI_MODE_X_MASK) {
    109	case SPI_MODE_0:
    110		mode_val = 0;
    111		break;
    112	case SPI_MODE_1:
    113		mode_val = NPCM_PSPI_CTL1_SCIDL;
    114		break;
    115	case SPI_MODE_2:
    116		mode_val = NPCM_PSPI_CTL1_SCM;
    117		break;
    118	case SPI_MODE_3:
    119		mode_val = NPCM_PSPI_CTL1_SCIDL | NPCM_PSPI_CTL1_SCM;
    120		break;
    121	}
    122
    123	regtemp = ioread16(priv->base + NPCM_PSPI_CTL1);
    124	regtemp &= ~(NPCM_PSPI_CTL1_SCM | NPCM_PSPI_CTL1_SCIDL);
    125	iowrite16(regtemp | mode_val, priv->base + NPCM_PSPI_CTL1);
    126}
    127
    128static void npcm_pspi_set_transfer_size(struct npcm_pspi *priv, int size)
    129{
    130	u16 regtemp;
    131
    132	regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
    133
    134	switch (size) {
    135	case 8:
    136		regtemp &= ~NPCM_PSPI_CTL1_MOD;
    137		break;
    138	case 16:
    139		regtemp |= NPCM_PSPI_CTL1_MOD;
    140		break;
    141	}
    142
    143	iowrite16(regtemp, NPCM_PSPI_CTL1 + priv->base);
    144}
    145
    146static void npcm_pspi_set_baudrate(struct npcm_pspi *priv, unsigned int speed)
    147{
    148	u32 ckdiv;
    149	u16 regtemp;
    150
    151	/* the supported rates are numbers from 4 to 256. */
    152	ckdiv = DIV_ROUND_CLOSEST(clk_get_rate(priv->clk), (2 * speed)) - 1;
    153
    154	regtemp = ioread16(NPCM_PSPI_CTL1 + priv->base);
    155	regtemp &= ~NPCM_PSPI_CTL1_SCDV6_0;
    156	iowrite16(regtemp | (ckdiv << 9), NPCM_PSPI_CTL1 + priv->base);
    157}
    158
    159static void npcm_pspi_setup_transfer(struct spi_device *spi,
    160				     struct spi_transfer *t)
    161{
    162	struct npcm_pspi *priv = spi_master_get_devdata(spi->master);
    163
    164	priv->tx_buf = t->tx_buf;
    165	priv->rx_buf = t->rx_buf;
    166	priv->tx_bytes = t->len;
    167	priv->rx_bytes = t->len;
    168
    169	if (!priv->is_save_param || priv->mode != spi->mode) {
    170		npcm_pspi_set_mode(spi);
    171		priv->mode = spi->mode;
    172	}
    173
    174	/*
    175	 * If transfer is even length, and 8 bits per word transfer,
    176	 * then implement 16 bits-per-word transfer.
    177	 */
    178	if (priv->bits_per_word == 8 && !(t->len & 0x1))
    179		t->bits_per_word = 16;
    180
    181	if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) {
    182		npcm_pspi_set_transfer_size(priv, t->bits_per_word);
    183		priv->bits_per_word = t->bits_per_word;
    184	}
    185
    186	if (!priv->is_save_param || priv->speed_hz != t->speed_hz) {
    187		npcm_pspi_set_baudrate(priv, t->speed_hz);
    188		priv->speed_hz = t->speed_hz;
    189	}
    190
    191	if (!priv->is_save_param)
    192		priv->is_save_param = true;
    193}
    194
    195static void npcm_pspi_send(struct npcm_pspi *priv)
    196{
    197	int wsize;
    198	u16 val;
    199
    200	wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
    201	priv->tx_bytes -= wsize;
    202
    203	if (!priv->tx_buf)
    204		return;
    205
    206	switch (wsize) {
    207	case 1:
    208		val = *priv->tx_buf++;
    209		iowrite8(val, NPCM_PSPI_DATA + priv->base);
    210		break;
    211	case 2:
    212		val = *priv->tx_buf++;
    213		val = *priv->tx_buf++ | (val << 8);
    214		iowrite16(val, NPCM_PSPI_DATA + priv->base);
    215		break;
    216	default:
    217		WARN_ON_ONCE(1);
    218		return;
    219	}
    220}
    221
    222static void npcm_pspi_recv(struct npcm_pspi *priv)
    223{
    224	int rsize;
    225	u16 val;
    226
    227	rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
    228	priv->rx_bytes -= rsize;
    229
    230	if (!priv->rx_buf)
    231		return;
    232
    233	switch (rsize) {
    234	case 1:
    235		*priv->rx_buf++ = ioread8(priv->base + NPCM_PSPI_DATA);
    236		break;
    237	case 2:
    238		val = ioread16(priv->base + NPCM_PSPI_DATA);
    239		*priv->rx_buf++ = (val >> 8);
    240		*priv->rx_buf++ = val & 0xff;
    241		break;
    242	default:
    243		WARN_ON_ONCE(1);
    244		return;
    245	}
    246}
    247
    248static int npcm_pspi_transfer_one(struct spi_master *master,
    249				  struct spi_device *spi,
    250				  struct spi_transfer *t)
    251{
    252	struct npcm_pspi *priv = spi_master_get_devdata(master);
    253	int status;
    254
    255	npcm_pspi_setup_transfer(spi, t);
    256	reinit_completion(&priv->xfer_done);
    257	npcm_pspi_enable(priv);
    258	status = wait_for_completion_timeout(&priv->xfer_done,
    259					     msecs_to_jiffies
    260					     (NPCM_PSPI_TIMEOUT_MS));
    261	if (status == 0) {
    262		npcm_pspi_disable(priv);
    263		return -ETIMEDOUT;
    264	}
    265
    266	return 0;
    267}
    268
    269static int npcm_pspi_prepare_transfer_hardware(struct spi_master *master)
    270{
    271	struct npcm_pspi *priv = spi_master_get_devdata(master);
    272
    273	npcm_pspi_irq_enable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
    274
    275	return 0;
    276}
    277
    278static int npcm_pspi_unprepare_transfer_hardware(struct spi_master *master)
    279{
    280	struct npcm_pspi *priv = spi_master_get_devdata(master);
    281
    282	npcm_pspi_irq_disable(priv, NPCM_PSPI_CTL1_EIR | NPCM_PSPI_CTL1_EIW);
    283
    284	return 0;
    285}
    286
    287static void npcm_pspi_reset_hw(struct npcm_pspi *priv)
    288{
    289	reset_control_assert(priv->reset);
    290	udelay(5);
    291	reset_control_deassert(priv->reset);
    292}
    293
    294static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
    295{
    296	struct npcm_pspi *priv = dev_id;
    297	u8 stat;
    298
    299	stat = ioread8(priv->base + NPCM_PSPI_STAT);
    300
    301	if (!priv->tx_buf && !priv->rx_buf)
    302		return IRQ_NONE;
    303
    304	if (priv->tx_buf) {
    305		if (stat & NPCM_PSPI_STAT_RBF) {
    306			ioread8(NPCM_PSPI_DATA + priv->base);
    307			if (priv->tx_bytes == 0) {
    308				npcm_pspi_disable(priv);
    309				complete(&priv->xfer_done);
    310				return IRQ_HANDLED;
    311			}
    312		}
    313
    314		if ((stat & NPCM_PSPI_STAT_BSY) == 0)
    315			if (priv->tx_bytes)
    316				npcm_pspi_send(priv);
    317	}
    318
    319	if (priv->rx_buf) {
    320		if (stat & NPCM_PSPI_STAT_RBF) {
    321			if (!priv->rx_bytes)
    322				return IRQ_NONE;
    323
    324			npcm_pspi_recv(priv);
    325
    326			if (!priv->rx_bytes) {
    327				npcm_pspi_disable(priv);
    328				complete(&priv->xfer_done);
    329				return IRQ_HANDLED;
    330			}
    331		}
    332
    333		if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
    334			iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
    335	}
    336
    337	return IRQ_HANDLED;
    338}
    339
    340static int npcm_pspi_probe(struct platform_device *pdev)
    341{
    342	struct npcm_pspi *priv;
    343	struct spi_master *master;
    344	unsigned long clk_hz;
    345	int irq;
    346	int ret;
    347
    348	master = spi_alloc_master(&pdev->dev, sizeof(*priv));
    349	if (!master)
    350		return -ENOMEM;
    351
    352	platform_set_drvdata(pdev, master);
    353
    354	priv = spi_master_get_devdata(master);
    355	priv->master = master;
    356	priv->is_save_param = false;
    357
    358	priv->base = devm_platform_ioremap_resource(pdev, 0);
    359	if (IS_ERR(priv->base)) {
    360		ret = PTR_ERR(priv->base);
    361		goto out_master_put;
    362	}
    363
    364	priv->clk = devm_clk_get(&pdev->dev, NULL);
    365	if (IS_ERR(priv->clk)) {
    366		dev_err(&pdev->dev, "failed to get clock\n");
    367		ret = PTR_ERR(priv->clk);
    368		goto out_master_put;
    369	}
    370
    371	ret = clk_prepare_enable(priv->clk);
    372	if (ret)
    373		goto out_master_put;
    374
    375	irq = platform_get_irq(pdev, 0);
    376	if (irq < 0) {
    377		ret = irq;
    378		goto out_disable_clk;
    379	}
    380
    381	priv->reset = devm_reset_control_get(&pdev->dev, NULL);
    382	if (IS_ERR(priv->reset)) {
    383		ret = PTR_ERR(priv->reset);
    384		goto out_disable_clk;
    385	}
    386
    387	/* reset SPI-HW block */
    388	npcm_pspi_reset_hw(priv);
    389
    390	ret = devm_request_irq(&pdev->dev, irq, npcm_pspi_handler, 0,
    391			       "npcm-pspi", priv);
    392	if (ret) {
    393		dev_err(&pdev->dev, "failed to request IRQ\n");
    394		goto out_disable_clk;
    395	}
    396
    397	init_completion(&priv->xfer_done);
    398
    399	clk_hz = clk_get_rate(priv->clk);
    400
    401	master->max_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MIN_CLK_DIVIDER);
    402	master->min_speed_hz = DIV_ROUND_UP(clk_hz, NPCM_PSPI_MAX_CLK_DIVIDER);
    403	master->mode_bits = SPI_CPHA | SPI_CPOL;
    404	master->dev.of_node = pdev->dev.of_node;
    405	master->bus_num = -1;
    406	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
    407	master->transfer_one = npcm_pspi_transfer_one;
    408	master->prepare_transfer_hardware =
    409		npcm_pspi_prepare_transfer_hardware;
    410	master->unprepare_transfer_hardware =
    411		npcm_pspi_unprepare_transfer_hardware;
    412	master->use_gpio_descriptors = true;
    413
    414	/* set to default clock rate */
    415	npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK);
    416
    417	ret = devm_spi_register_master(&pdev->dev, master);
    418	if (ret)
    419		goto out_disable_clk;
    420
    421	pr_info("NPCM Peripheral SPI %d probed\n", master->bus_num);
    422
    423	return 0;
    424
    425out_disable_clk:
    426	clk_disable_unprepare(priv->clk);
    427
    428out_master_put:
    429	spi_master_put(master);
    430	return ret;
    431}
    432
    433static int npcm_pspi_remove(struct platform_device *pdev)
    434{
    435	struct spi_master *master = platform_get_drvdata(pdev);
    436	struct npcm_pspi *priv = spi_master_get_devdata(master);
    437
    438	npcm_pspi_reset_hw(priv);
    439	clk_disable_unprepare(priv->clk);
    440
    441	return 0;
    442}
    443
    444static const struct of_device_id npcm_pspi_match[] = {
    445	{ .compatible = "nuvoton,npcm750-pspi", .data = NULL },
    446	{}
    447};
    448MODULE_DEVICE_TABLE(of, npcm_pspi_match);
    449
    450static struct platform_driver npcm_pspi_driver = {
    451	.driver		= {
    452		.name		= DRIVER_NAME,
    453		.of_match_table	= npcm_pspi_match,
    454	},
    455	.probe		= npcm_pspi_probe,
    456	.remove		= npcm_pspi_remove,
    457};
    458module_platform_driver(npcm_pspi_driver);
    459
    460MODULE_DESCRIPTION("NPCM peripheral SPI Controller driver");
    461MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
    462MODULE_LICENSE("GPL v2");
    463