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-synquacer.c (22384B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Synquacer HSSPI controller driver
      4//
      5// Copyright (c) 2015-2018 Socionext Inc.
      6// Copyright (c) 2018-2019 Linaro Ltd.
      7//
      8
      9#include <linux/acpi.h>
     10#include <linux/delay.h>
     11#include <linux/interrupt.h>
     12#include <linux/io.h>
     13#include <linux/module.h>
     14#include <linux/of.h>
     15#include <linux/platform_device.h>
     16#include <linux/pm_runtime.h>
     17#include <linux/scatterlist.h>
     18#include <linux/slab.h>
     19#include <linux/spi/spi.h>
     20#include <linux/spinlock.h>
     21#include <linux/clk.h>
     22
     23/* HSSPI register address definitions */
     24#define SYNQUACER_HSSPI_REG_MCTRL	0x00
     25#define SYNQUACER_HSSPI_REG_PCC0	0x04
     26#define SYNQUACER_HSSPI_REG_PCC(n)	(SYNQUACER_HSSPI_REG_PCC0 + (n) * 4)
     27#define SYNQUACER_HSSPI_REG_TXF		0x14
     28#define SYNQUACER_HSSPI_REG_TXE		0x18
     29#define SYNQUACER_HSSPI_REG_TXC		0x1C
     30#define SYNQUACER_HSSPI_REG_RXF		0x20
     31#define SYNQUACER_HSSPI_REG_RXE		0x24
     32#define SYNQUACER_HSSPI_REG_RXC		0x28
     33#define SYNQUACER_HSSPI_REG_FAULTF	0x2C
     34#define SYNQUACER_HSSPI_REG_FAULTC	0x30
     35#define SYNQUACER_HSSPI_REG_DMCFG	0x34
     36#define SYNQUACER_HSSPI_REG_DMSTART	0x38
     37#define SYNQUACER_HSSPI_REG_DMBCC	0x3C
     38#define SYNQUACER_HSSPI_REG_DMSTATUS	0x40
     39#define SYNQUACER_HSSPI_REG_FIFOCFG	0x4C
     40#define SYNQUACER_HSSPI_REG_TX_FIFO	0x50
     41#define SYNQUACER_HSSPI_REG_RX_FIFO	0x90
     42#define SYNQUACER_HSSPI_REG_MID		0xFC
     43
     44/* HSSPI register bit definitions */
     45#define SYNQUACER_HSSPI_MCTRL_MEN			BIT(0)
     46#define SYNQUACER_HSSPI_MCTRL_COMMAND_SEQUENCE_EN	BIT(1)
     47#define SYNQUACER_HSSPI_MCTRL_CDSS			BIT(3)
     48#define SYNQUACER_HSSPI_MCTRL_MES			BIT(4)
     49#define SYNQUACER_HSSPI_MCTRL_SYNCON			BIT(5)
     50
     51#define SYNQUACER_HSSPI_PCC_CPHA		BIT(0)
     52#define SYNQUACER_HSSPI_PCC_CPOL		BIT(1)
     53#define SYNQUACER_HSSPI_PCC_ACES		BIT(2)
     54#define SYNQUACER_HSSPI_PCC_RTM			BIT(3)
     55#define SYNQUACER_HSSPI_PCC_SSPOL		BIT(4)
     56#define SYNQUACER_HSSPI_PCC_SDIR		BIT(7)
     57#define SYNQUACER_HSSPI_PCC_SENDIAN		BIT(8)
     58#define SYNQUACER_HSSPI_PCC_SAFESYNC		BIT(16)
     59#define SYNQUACER_HSSPI_PCC_SS2CD_SHIFT		5U
     60#define SYNQUACER_HSSPI_PCC_CDRS_MASK		0x7f
     61#define SYNQUACER_HSSPI_PCC_CDRS_SHIFT		9U
     62
     63#define SYNQUACER_HSSPI_TXF_FIFO_FULL		BIT(0)
     64#define SYNQUACER_HSSPI_TXF_FIFO_EMPTY		BIT(1)
     65#define SYNQUACER_HSSPI_TXF_SLAVE_RELEASED	BIT(6)
     66
     67#define SYNQUACER_HSSPI_TXE_FIFO_FULL		BIT(0)
     68#define SYNQUACER_HSSPI_TXE_FIFO_EMPTY		BIT(1)
     69#define SYNQUACER_HSSPI_TXE_SLAVE_RELEASED	BIT(6)
     70
     71#define SYNQUACER_HSSPI_RXF_FIFO_MORE_THAN_THRESHOLD		BIT(5)
     72#define SYNQUACER_HSSPI_RXF_SLAVE_RELEASED			BIT(6)
     73
     74#define SYNQUACER_HSSPI_RXE_FIFO_MORE_THAN_THRESHOLD		BIT(5)
     75#define SYNQUACER_HSSPI_RXE_SLAVE_RELEASED			BIT(6)
     76
     77#define SYNQUACER_HSSPI_DMCFG_SSDC		BIT(1)
     78#define SYNQUACER_HSSPI_DMCFG_MSTARTEN		BIT(2)
     79
     80#define SYNQUACER_HSSPI_DMSTART_START		BIT(0)
     81#define SYNQUACER_HSSPI_DMSTOP_STOP		BIT(8)
     82#define SYNQUACER_HSSPI_DMPSEL_CS_MASK		0x3
     83#define SYNQUACER_HSSPI_DMPSEL_CS_SHIFT		16U
     84#define SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT	24U
     85#define SYNQUACER_HSSPI_DMTRP_DATA_MASK		0x3
     86#define SYNQUACER_HSSPI_DMTRP_DATA_SHIFT	26U
     87#define SYNQUACER_HSSPI_DMTRP_DATA_TXRX		0
     88#define SYNQUACER_HSSPI_DMTRP_DATA_RX		1
     89#define SYNQUACER_HSSPI_DMTRP_DATA_TX		2
     90
     91#define SYNQUACER_HSSPI_DMSTATUS_RX_DATA_MASK	0x1f
     92#define SYNQUACER_HSSPI_DMSTATUS_RX_DATA_SHIFT	8U
     93#define SYNQUACER_HSSPI_DMSTATUS_TX_DATA_MASK	0x1f
     94#define SYNQUACER_HSSPI_DMSTATUS_TX_DATA_SHIFT	16U
     95
     96#define SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_MASK	0xf
     97#define SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT	0U
     98#define SYNQUACER_HSSPI_FIFOCFG_TX_THRESHOLD_MASK	0xf
     99#define SYNQUACER_HSSPI_FIFOCFG_TX_THRESHOLD_SHIFT	4U
    100#define SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_MASK		0x3
    101#define SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT	8U
    102#define SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH		BIT(11)
    103#define SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH		BIT(12)
    104
    105#define SYNQUACER_HSSPI_FIFO_DEPTH		16U
    106#define SYNQUACER_HSSPI_FIFO_TX_THRESHOLD	4U
    107#define SYNQUACER_HSSPI_FIFO_RX_THRESHOLD \
    108	(SYNQUACER_HSSPI_FIFO_DEPTH - SYNQUACER_HSSPI_FIFO_TX_THRESHOLD)
    109
    110#define SYNQUACER_HSSPI_TRANSFER_MODE_TX	BIT(1)
    111#define SYNQUACER_HSSPI_TRANSFER_MODE_RX	BIT(2)
    112#define SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC	2000U
    113#define SYNQUACER_HSSPI_ENABLE_TMOUT_MSEC	1000U
    114
    115#define SYNQUACER_HSSPI_CLOCK_SRC_IHCLK		0
    116#define SYNQUACER_HSSPI_CLOCK_SRC_IPCLK		1
    117
    118#define SYNQUACER_HSSPI_NUM_CHIP_SELECT		4U
    119#define SYNQUACER_HSSPI_IRQ_NAME_MAX		32U
    120
    121struct synquacer_spi {
    122	struct device *dev;
    123	struct completion transfer_done;
    124	unsigned int cs;
    125	unsigned int bpw;
    126	unsigned int mode;
    127	unsigned int speed;
    128	bool aces, rtm;
    129	void *rx_buf;
    130	const void *tx_buf;
    131	struct clk *clk;
    132	int clk_src_type;
    133	void __iomem *regs;
    134	u32 tx_words, rx_words;
    135	unsigned int bus_width;
    136	unsigned int transfer_mode;
    137	char rx_irq_name[SYNQUACER_HSSPI_IRQ_NAME_MAX];
    138	char tx_irq_name[SYNQUACER_HSSPI_IRQ_NAME_MAX];
    139};
    140
    141static int read_fifo(struct synquacer_spi *sspi)
    142{
    143	u32 len = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTATUS);
    144
    145	len = (len >> SYNQUACER_HSSPI_DMSTATUS_RX_DATA_SHIFT) &
    146	       SYNQUACER_HSSPI_DMSTATUS_RX_DATA_MASK;
    147	len = min(len, sspi->rx_words);
    148
    149	switch (sspi->bpw) {
    150	case 8: {
    151		u8 *buf = sspi->rx_buf;
    152
    153		ioread8_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
    154			    buf, len);
    155		sspi->rx_buf = buf + len;
    156		break;
    157	}
    158	case 16: {
    159		u16 *buf = sspi->rx_buf;
    160
    161		ioread16_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
    162			     buf, len);
    163		sspi->rx_buf = buf + len;
    164		break;
    165	}
    166	case 24:
    167		/* fallthrough, should use 32-bits access */
    168	case 32: {
    169		u32 *buf = sspi->rx_buf;
    170
    171		ioread32_rep(sspi->regs + SYNQUACER_HSSPI_REG_RX_FIFO,
    172			     buf, len);
    173		sspi->rx_buf = buf + len;
    174		break;
    175	}
    176	default:
    177		return -EINVAL;
    178	}
    179
    180	sspi->rx_words -= len;
    181	return 0;
    182}
    183
    184static int write_fifo(struct synquacer_spi *sspi)
    185{
    186	u32 len = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTATUS);
    187
    188	len = (len >> SYNQUACER_HSSPI_DMSTATUS_TX_DATA_SHIFT) &
    189	       SYNQUACER_HSSPI_DMSTATUS_TX_DATA_MASK;
    190	len = min(SYNQUACER_HSSPI_FIFO_DEPTH - len,
    191		    sspi->tx_words);
    192
    193	switch (sspi->bpw) {
    194	case 8: {
    195		const u8 *buf = sspi->tx_buf;
    196
    197		iowrite8_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
    198			     buf, len);
    199		sspi->tx_buf = buf + len;
    200		break;
    201	}
    202	case 16: {
    203		const u16 *buf = sspi->tx_buf;
    204
    205		iowrite16_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
    206			      buf, len);
    207		sspi->tx_buf = buf + len;
    208		break;
    209	}
    210	case 24:
    211		/* fallthrough, should use 32-bits access */
    212	case 32: {
    213		const u32 *buf = sspi->tx_buf;
    214
    215		iowrite32_rep(sspi->regs + SYNQUACER_HSSPI_REG_TX_FIFO,
    216			      buf, len);
    217		sspi->tx_buf = buf + len;
    218		break;
    219	}
    220	default:
    221		return -EINVAL;
    222	}
    223
    224	sspi->tx_words -= len;
    225	return 0;
    226}
    227
    228static int synquacer_spi_config(struct spi_master *master,
    229				struct spi_device *spi,
    230				struct spi_transfer *xfer)
    231{
    232	struct synquacer_spi *sspi = spi_master_get_devdata(master);
    233	unsigned int speed, mode, bpw, cs, bus_width, transfer_mode;
    234	u32 rate, val, div;
    235
    236	/* Full Duplex only on 1-bit wide bus */
    237	if (xfer->rx_buf && xfer->tx_buf &&
    238	    (xfer->rx_nbits != 1 || xfer->tx_nbits != 1)) {
    239		dev_err(sspi->dev,
    240			"RX and TX bus widths must be 1-bit for Full-Duplex!\n");
    241		return -EINVAL;
    242	}
    243
    244	if (xfer->tx_buf) {
    245		bus_width = xfer->tx_nbits;
    246		transfer_mode = SYNQUACER_HSSPI_TRANSFER_MODE_TX;
    247	} else {
    248		bus_width = xfer->rx_nbits;
    249		transfer_mode = SYNQUACER_HSSPI_TRANSFER_MODE_RX;
    250	}
    251
    252	mode = spi->mode;
    253	cs = spi->chip_select;
    254	speed = xfer->speed_hz;
    255	bpw = xfer->bits_per_word;
    256
    257	/* return if nothing to change */
    258	if (speed == sspi->speed &&
    259		bus_width == sspi->bus_width && bpw == sspi->bpw &&
    260		mode == sspi->mode && cs == sspi->cs &&
    261		transfer_mode == sspi->transfer_mode) {
    262		return 0;
    263	}
    264
    265	sspi->transfer_mode = transfer_mode;
    266	rate = master->max_speed_hz;
    267
    268	div = DIV_ROUND_UP(rate, speed);
    269	if (div > 254) {
    270		dev_err(sspi->dev, "Requested rate too low (%u)\n",
    271			sspi->speed);
    272		return -EINVAL;
    273	}
    274
    275	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_PCC(cs));
    276	val &= ~SYNQUACER_HSSPI_PCC_SAFESYNC;
    277	if (bpw == 8 &&	(mode & (SPI_TX_DUAL | SPI_RX_DUAL)) && div < 3)
    278		val |= SYNQUACER_HSSPI_PCC_SAFESYNC;
    279	if (bpw == 8 &&	(mode & (SPI_TX_QUAD | SPI_RX_QUAD)) && div < 6)
    280		val |= SYNQUACER_HSSPI_PCC_SAFESYNC;
    281	if (bpw == 16 && (mode & (SPI_TX_QUAD | SPI_RX_QUAD)) && div < 3)
    282		val |= SYNQUACER_HSSPI_PCC_SAFESYNC;
    283
    284	if (mode & SPI_CPHA)
    285		val |= SYNQUACER_HSSPI_PCC_CPHA;
    286	else
    287		val &= ~SYNQUACER_HSSPI_PCC_CPHA;
    288
    289	if (mode & SPI_CPOL)
    290		val |= SYNQUACER_HSSPI_PCC_CPOL;
    291	else
    292		val &= ~SYNQUACER_HSSPI_PCC_CPOL;
    293
    294	if (mode & SPI_CS_HIGH)
    295		val |= SYNQUACER_HSSPI_PCC_SSPOL;
    296	else
    297		val &= ~SYNQUACER_HSSPI_PCC_SSPOL;
    298
    299	if (mode & SPI_LSB_FIRST)
    300		val |= SYNQUACER_HSSPI_PCC_SDIR;
    301	else
    302		val &= ~SYNQUACER_HSSPI_PCC_SDIR;
    303
    304	if (sspi->aces)
    305		val |= SYNQUACER_HSSPI_PCC_ACES;
    306	else
    307		val &= ~SYNQUACER_HSSPI_PCC_ACES;
    308
    309	if (sspi->rtm)
    310		val |= SYNQUACER_HSSPI_PCC_RTM;
    311	else
    312		val &= ~SYNQUACER_HSSPI_PCC_RTM;
    313
    314	val |= (3 << SYNQUACER_HSSPI_PCC_SS2CD_SHIFT);
    315	val |= SYNQUACER_HSSPI_PCC_SENDIAN;
    316
    317	val &= ~(SYNQUACER_HSSPI_PCC_CDRS_MASK <<
    318		 SYNQUACER_HSSPI_PCC_CDRS_SHIFT);
    319	val |= ((div >> 1) << SYNQUACER_HSSPI_PCC_CDRS_SHIFT);
    320
    321	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_PCC(cs));
    322
    323	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
    324	val &= ~(SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_MASK <<
    325		 SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT);
    326	val |= ((bpw / 8 - 1) << SYNQUACER_HSSPI_FIFOCFG_FIFO_WIDTH_SHIFT);
    327	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
    328
    329	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    330	val &= ~(SYNQUACER_HSSPI_DMTRP_DATA_MASK <<
    331		 SYNQUACER_HSSPI_DMTRP_DATA_SHIFT);
    332
    333	if (xfer->rx_buf)
    334		val |= (SYNQUACER_HSSPI_DMTRP_DATA_RX <<
    335			SYNQUACER_HSSPI_DMTRP_DATA_SHIFT);
    336	else
    337		val |= (SYNQUACER_HSSPI_DMTRP_DATA_TX <<
    338			SYNQUACER_HSSPI_DMTRP_DATA_SHIFT);
    339
    340	val &= ~(3 << SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT);
    341	val |= ((bus_width >> 1) << SYNQUACER_HSSPI_DMTRP_BUS_WIDTH_SHIFT);
    342	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    343
    344	sspi->bpw = bpw;
    345	sspi->mode = mode;
    346	sspi->speed = speed;
    347	sspi->cs = spi->chip_select;
    348	sspi->bus_width = bus_width;
    349
    350	return 0;
    351}
    352
    353static int synquacer_spi_transfer_one(struct spi_master *master,
    354				      struct spi_device *spi,
    355				      struct spi_transfer *xfer)
    356{
    357	struct synquacer_spi *sspi = spi_master_get_devdata(master);
    358	int ret;
    359	int status = 0;
    360	u32 words;
    361	u8 bpw;
    362	u32 val;
    363
    364	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    365	val &= ~SYNQUACER_HSSPI_DMSTOP_STOP;
    366	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    367
    368	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
    369	val |= SYNQUACER_HSSPI_FIFOCFG_RX_FLUSH;
    370	val |= SYNQUACER_HSSPI_FIFOCFG_TX_FLUSH;
    371	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
    372
    373	/*
    374	 * See if we can transfer 4-bytes as 1 word
    375	 * to maximize the FIFO buffer efficiency.
    376	 */
    377	bpw = xfer->bits_per_word;
    378	if (bpw == 8 && !(xfer->len % 4) && !(spi->mode & SPI_LSB_FIRST))
    379		xfer->bits_per_word = 32;
    380
    381	ret = synquacer_spi_config(master, spi, xfer);
    382
    383	/* restore */
    384	xfer->bits_per_word = bpw;
    385
    386	if (ret)
    387		return ret;
    388
    389	reinit_completion(&sspi->transfer_done);
    390
    391	sspi->tx_buf = xfer->tx_buf;
    392	sspi->rx_buf = xfer->rx_buf;
    393
    394	switch (sspi->bpw) {
    395	case 8:
    396		words = xfer->len;
    397		break;
    398	case 16:
    399		words = xfer->len / 2;
    400		break;
    401	case 24:
    402		/* fallthrough, should use 32-bits access */
    403	case 32:
    404		words = xfer->len / 4;
    405		break;
    406	default:
    407		dev_err(sspi->dev, "unsupported bpw: %d\n", sspi->bpw);
    408		return -EINVAL;
    409	}
    410
    411	if (xfer->tx_buf)
    412		sspi->tx_words = words;
    413	else
    414		sspi->tx_words = 0;
    415
    416	if (xfer->rx_buf)
    417		sspi->rx_words = words;
    418	else
    419		sspi->rx_words = 0;
    420
    421	if (xfer->tx_buf) {
    422		status = write_fifo(sspi);
    423		if (status < 0) {
    424			dev_err(sspi->dev, "failed write_fifo. status: 0x%x\n",
    425				status);
    426			return status;
    427		}
    428	}
    429
    430	if (xfer->rx_buf) {
    431		val = readl(sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
    432		val &= ~(SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_MASK <<
    433			 SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT);
    434		val |= ((sspi->rx_words > SYNQUACER_HSSPI_FIFO_DEPTH ?
    435			SYNQUACER_HSSPI_FIFO_RX_THRESHOLD : sspi->rx_words) <<
    436			SYNQUACER_HSSPI_FIFOCFG_RX_THRESHOLD_SHIFT);
    437		writel(val, sspi->regs + SYNQUACER_HSSPI_REG_FIFOCFG);
    438	}
    439
    440	writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_TXC);
    441	writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_RXC);
    442
    443	/* Trigger */
    444	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    445	val |= SYNQUACER_HSSPI_DMSTART_START;
    446	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    447
    448	if (xfer->tx_buf) {
    449		val = SYNQUACER_HSSPI_TXE_FIFO_EMPTY;
    450		writel(val, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
    451		status = wait_for_completion_timeout(&sspi->transfer_done,
    452			msecs_to_jiffies(SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC));
    453		writel(0, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
    454	}
    455
    456	if (xfer->rx_buf) {
    457		u32 buf[SYNQUACER_HSSPI_FIFO_DEPTH];
    458
    459		val = SYNQUACER_HSSPI_RXE_FIFO_MORE_THAN_THRESHOLD |
    460		      SYNQUACER_HSSPI_RXE_SLAVE_RELEASED;
    461		writel(val, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
    462		status = wait_for_completion_timeout(&sspi->transfer_done,
    463			msecs_to_jiffies(SYNQUACER_HSSPI_TRANSFER_TMOUT_MSEC));
    464		writel(0, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
    465
    466		/* stop RX and clean RXFIFO */
    467		val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    468		val |= SYNQUACER_HSSPI_DMSTOP_STOP;
    469		writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    470		sspi->rx_buf = buf;
    471		sspi->rx_words = SYNQUACER_HSSPI_FIFO_DEPTH;
    472		read_fifo(sspi);
    473	}
    474
    475	if (status < 0) {
    476		dev_err(sspi->dev, "failed to transfer. status: 0x%x\n",
    477			status);
    478		return status;
    479	}
    480
    481	return 0;
    482}
    483
    484static void synquacer_spi_set_cs(struct spi_device *spi, bool enable)
    485{
    486	struct synquacer_spi *sspi = spi_master_get_devdata(spi->master);
    487	u32 val;
    488
    489	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    490	val &= ~(SYNQUACER_HSSPI_DMPSEL_CS_MASK <<
    491		 SYNQUACER_HSSPI_DMPSEL_CS_SHIFT);
    492	val |= spi->chip_select << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT;
    493
    494	if (!enable)
    495		val |= SYNQUACER_HSSPI_DMSTOP_STOP;
    496
    497	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
    498}
    499
    500static int synquacer_spi_wait_status_update(struct synquacer_spi *sspi,
    501					    bool enable)
    502{
    503	u32 val;
    504	unsigned long timeout = jiffies +
    505		msecs_to_jiffies(SYNQUACER_HSSPI_ENABLE_TMOUT_MSEC);
    506
    507	/* wait MES(Module Enable Status) is updated */
    508	do {
    509		val = readl(sspi->regs + SYNQUACER_HSSPI_REG_MCTRL) &
    510		      SYNQUACER_HSSPI_MCTRL_MES;
    511		if (enable && val)
    512			return 0;
    513		if (!enable && !val)
    514			return 0;
    515	} while (time_before(jiffies, timeout));
    516
    517	dev_err(sspi->dev, "timeout occurs in updating Module Enable Status\n");
    518	return -EBUSY;
    519}
    520
    521static int synquacer_spi_enable(struct spi_master *master)
    522{
    523	u32 val;
    524	int status;
    525	struct synquacer_spi *sspi = spi_master_get_devdata(master);
    526
    527	/* Disable module */
    528	writel(0, sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
    529	status = synquacer_spi_wait_status_update(sspi, false);
    530	if (status < 0)
    531		return status;
    532
    533	writel(0, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
    534	writel(0, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
    535	writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_TXC);
    536	writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_RXC);
    537	writel(~0, sspi->regs + SYNQUACER_HSSPI_REG_FAULTC);
    538
    539	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMCFG);
    540	val &= ~SYNQUACER_HSSPI_DMCFG_SSDC;
    541	val &= ~SYNQUACER_HSSPI_DMCFG_MSTARTEN;
    542	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMCFG);
    543
    544	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
    545	if (sspi->clk_src_type == SYNQUACER_HSSPI_CLOCK_SRC_IPCLK)
    546		val |= SYNQUACER_HSSPI_MCTRL_CDSS;
    547	else
    548		val &= ~SYNQUACER_HSSPI_MCTRL_CDSS;
    549
    550	val &= ~SYNQUACER_HSSPI_MCTRL_COMMAND_SEQUENCE_EN;
    551	val |= SYNQUACER_HSSPI_MCTRL_MEN;
    552	val |= SYNQUACER_HSSPI_MCTRL_SYNCON;
    553
    554	/* Enable module */
    555	writel(val, sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
    556	status = synquacer_spi_wait_status_update(sspi, true);
    557	if (status < 0)
    558		return status;
    559
    560	return 0;
    561}
    562
    563static irqreturn_t sq_spi_rx_handler(int irq, void *priv)
    564{
    565	uint32_t val;
    566	struct synquacer_spi *sspi = priv;
    567
    568	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_RXF);
    569	if ((val & SYNQUACER_HSSPI_RXF_SLAVE_RELEASED) ||
    570	    (val & SYNQUACER_HSSPI_RXF_FIFO_MORE_THAN_THRESHOLD)) {
    571		read_fifo(sspi);
    572
    573		if (sspi->rx_words == 0) {
    574			writel(0, sspi->regs + SYNQUACER_HSSPI_REG_RXE);
    575			complete(&sspi->transfer_done);
    576		}
    577		return IRQ_HANDLED;
    578	}
    579
    580	return IRQ_NONE;
    581}
    582
    583static irqreturn_t sq_spi_tx_handler(int irq, void *priv)
    584{
    585	uint32_t val;
    586	struct synquacer_spi *sspi = priv;
    587
    588	val = readl(sspi->regs + SYNQUACER_HSSPI_REG_TXF);
    589	if (val & SYNQUACER_HSSPI_TXF_FIFO_EMPTY) {
    590		if (sspi->tx_words == 0) {
    591			writel(0, sspi->regs + SYNQUACER_HSSPI_REG_TXE);
    592			complete(&sspi->transfer_done);
    593		} else {
    594			write_fifo(sspi);
    595		}
    596		return IRQ_HANDLED;
    597	}
    598
    599	return IRQ_NONE;
    600}
    601
    602static int synquacer_spi_probe(struct platform_device *pdev)
    603{
    604	struct device_node *np = pdev->dev.of_node;
    605	struct spi_master *master;
    606	struct synquacer_spi *sspi;
    607	int ret;
    608	int rx_irq, tx_irq;
    609
    610	master = spi_alloc_master(&pdev->dev, sizeof(*sspi));
    611	if (!master)
    612		return -ENOMEM;
    613
    614	platform_set_drvdata(pdev, master);
    615
    616	sspi = spi_master_get_devdata(master);
    617	sspi->dev = &pdev->dev;
    618
    619	init_completion(&sspi->transfer_done);
    620
    621	sspi->regs = devm_platform_ioremap_resource(pdev, 0);
    622	if (IS_ERR(sspi->regs)) {
    623		ret = PTR_ERR(sspi->regs);
    624		goto put_spi;
    625	}
    626
    627	sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IHCLK; /* Default */
    628	device_property_read_u32(&pdev->dev, "socionext,ihclk-rate",
    629				 &master->max_speed_hz); /* for ACPI */
    630
    631	if (dev_of_node(&pdev->dev)) {
    632		if (device_property_match_string(&pdev->dev,
    633					 "clock-names", "iHCLK") >= 0) {
    634			sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IHCLK;
    635			sspi->clk = devm_clk_get(sspi->dev, "iHCLK");
    636		} else if (device_property_match_string(&pdev->dev,
    637						"clock-names", "iPCLK") >= 0) {
    638			sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IPCLK;
    639			sspi->clk = devm_clk_get(sspi->dev, "iPCLK");
    640		} else {
    641			dev_err(&pdev->dev, "specified wrong clock source\n");
    642			ret = -EINVAL;
    643			goto put_spi;
    644		}
    645
    646		if (IS_ERR(sspi->clk)) {
    647			ret = dev_err_probe(&pdev->dev, PTR_ERR(sspi->clk),
    648					    "clock not found\n");
    649			goto put_spi;
    650		}
    651
    652		ret = clk_prepare_enable(sspi->clk);
    653		if (ret) {
    654			dev_err(&pdev->dev, "failed to enable clock (%d)\n",
    655				ret);
    656			goto put_spi;
    657		}
    658
    659		master->max_speed_hz = clk_get_rate(sspi->clk);
    660	}
    661
    662	if (!master->max_speed_hz) {
    663		dev_err(&pdev->dev, "missing clock source\n");
    664		ret = -EINVAL;
    665		goto disable_clk;
    666	}
    667	master->min_speed_hz = master->max_speed_hz / 254;
    668
    669	sspi->aces = device_property_read_bool(&pdev->dev,
    670					       "socionext,set-aces");
    671	sspi->rtm = device_property_read_bool(&pdev->dev, "socionext,use-rtm");
    672
    673	master->num_chipselect = SYNQUACER_HSSPI_NUM_CHIP_SELECT;
    674
    675	rx_irq = platform_get_irq(pdev, 0);
    676	if (rx_irq <= 0) {
    677		ret = rx_irq;
    678		goto disable_clk;
    679	}
    680	snprintf(sspi->rx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-rx",
    681		 dev_name(&pdev->dev));
    682	ret = devm_request_irq(&pdev->dev, rx_irq, sq_spi_rx_handler,
    683				0, sspi->rx_irq_name, sspi);
    684	if (ret) {
    685		dev_err(&pdev->dev, "request rx_irq failed (%d)\n", ret);
    686		goto disable_clk;
    687	}
    688
    689	tx_irq = platform_get_irq(pdev, 1);
    690	if (tx_irq <= 0) {
    691		ret = tx_irq;
    692		goto disable_clk;
    693	}
    694	snprintf(sspi->tx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-tx",
    695		 dev_name(&pdev->dev));
    696	ret = devm_request_irq(&pdev->dev, tx_irq, sq_spi_tx_handler,
    697				0, sspi->tx_irq_name, sspi);
    698	if (ret) {
    699		dev_err(&pdev->dev, "request tx_irq failed (%d)\n", ret);
    700		goto disable_clk;
    701	}
    702
    703	master->dev.of_node = np;
    704	master->dev.fwnode = pdev->dev.fwnode;
    705	master->auto_runtime_pm = true;
    706	master->bus_num = pdev->id;
    707
    708	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL |
    709			    SPI_TX_QUAD | SPI_RX_QUAD;
    710	master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
    711				     SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
    712
    713	master->set_cs = synquacer_spi_set_cs;
    714	master->transfer_one = synquacer_spi_transfer_one;
    715
    716	ret = synquacer_spi_enable(master);
    717	if (ret)
    718		goto disable_clk;
    719
    720	pm_runtime_set_active(sspi->dev);
    721	pm_runtime_enable(sspi->dev);
    722
    723	ret = devm_spi_register_master(sspi->dev, master);
    724	if (ret)
    725		goto disable_pm;
    726
    727	return 0;
    728
    729disable_pm:
    730	pm_runtime_disable(sspi->dev);
    731disable_clk:
    732	clk_disable_unprepare(sspi->clk);
    733put_spi:
    734	spi_master_put(master);
    735
    736	return ret;
    737}
    738
    739static int synquacer_spi_remove(struct platform_device *pdev)
    740{
    741	struct spi_master *master = platform_get_drvdata(pdev);
    742	struct synquacer_spi *sspi = spi_master_get_devdata(master);
    743
    744	pm_runtime_disable(sspi->dev);
    745
    746	clk_disable_unprepare(sspi->clk);
    747
    748	return 0;
    749}
    750
    751static int __maybe_unused synquacer_spi_suspend(struct device *dev)
    752{
    753	struct spi_master *master = dev_get_drvdata(dev);
    754	struct synquacer_spi *sspi = spi_master_get_devdata(master);
    755	int ret;
    756
    757	ret = spi_master_suspend(master);
    758	if (ret)
    759		return ret;
    760
    761	if (!pm_runtime_suspended(dev))
    762		clk_disable_unprepare(sspi->clk);
    763
    764	return ret;
    765}
    766
    767static int __maybe_unused synquacer_spi_resume(struct device *dev)
    768{
    769	struct spi_master *master = dev_get_drvdata(dev);
    770	struct synquacer_spi *sspi = spi_master_get_devdata(master);
    771	int ret;
    772
    773	if (!pm_runtime_suspended(dev)) {
    774		/* Ensure reconfigure during next xfer */
    775		sspi->speed = 0;
    776
    777		ret = clk_prepare_enable(sspi->clk);
    778		if (ret < 0) {
    779			dev_err(dev, "failed to enable clk (%d)\n",
    780				ret);
    781			return ret;
    782		}
    783
    784		ret = synquacer_spi_enable(master);
    785		if (ret) {
    786			dev_err(dev, "failed to enable spi (%d)\n", ret);
    787			return ret;
    788		}
    789	}
    790
    791	ret = spi_master_resume(master);
    792	if (ret < 0)
    793		clk_disable_unprepare(sspi->clk);
    794
    795	return ret;
    796}
    797
    798static SIMPLE_DEV_PM_OPS(synquacer_spi_pm_ops, synquacer_spi_suspend,
    799			 synquacer_spi_resume);
    800
    801static const struct of_device_id synquacer_spi_of_match[] = {
    802	{.compatible = "socionext,synquacer-spi"},
    803	{}
    804};
    805MODULE_DEVICE_TABLE(of, synquacer_spi_of_match);
    806
    807#ifdef CONFIG_ACPI
    808static const struct acpi_device_id synquacer_hsspi_acpi_ids[] = {
    809	{ "SCX0004" },
    810	{ /* sentinel */ }
    811};
    812MODULE_DEVICE_TABLE(acpi, synquacer_hsspi_acpi_ids);
    813#endif
    814
    815static struct platform_driver synquacer_spi_driver = {
    816	.driver = {
    817		.name = "synquacer-spi",
    818		.pm = &synquacer_spi_pm_ops,
    819		.of_match_table = synquacer_spi_of_match,
    820		.acpi_match_table = ACPI_PTR(synquacer_hsspi_acpi_ids),
    821	},
    822	.probe = synquacer_spi_probe,
    823	.remove = synquacer_spi_remove,
    824};
    825module_platform_driver(synquacer_spi_driver);
    826
    827MODULE_DESCRIPTION("Socionext Synquacer HS-SPI controller driver");
    828MODULE_AUTHOR("Masahisa Kojima <masahisa.kojima@linaro.org>");
    829MODULE_AUTHOR("Jassi Brar <jaswinder.singh@linaro.org>");
    830MODULE_LICENSE("GPL v2");