162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * SH RSPI driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2012, 2013  Renesas Solutions Corp.
662306a36Sopenharmony_ci * Copyright (C) 2014 Glider bvba
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Based on spi-sh.c:
962306a36Sopenharmony_ci * Copyright (C) 2011 Renesas Solutions Corp.
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/module.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/sched.h>
1562306a36Sopenharmony_ci#include <linux/errno.h>
1662306a36Sopenharmony_ci#include <linux/interrupt.h>
1762306a36Sopenharmony_ci#include <linux/platform_device.h>
1862306a36Sopenharmony_ci#include <linux/io.h>
1962306a36Sopenharmony_ci#include <linux/clk.h>
2062306a36Sopenharmony_ci#include <linux/dmaengine.h>
2162306a36Sopenharmony_ci#include <linux/dma-mapping.h>
2262306a36Sopenharmony_ci#include <linux/of.h>
2362306a36Sopenharmony_ci#include <linux/pm_runtime.h>
2462306a36Sopenharmony_ci#include <linux/reset.h>
2562306a36Sopenharmony_ci#include <linux/sh_dma.h>
2662306a36Sopenharmony_ci#include <linux/spi/spi.h>
2762306a36Sopenharmony_ci#include <linux/spi/rspi.h>
2862306a36Sopenharmony_ci#include <linux/spinlock.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#define RSPI_SPCR		0x00	/* Control Register */
3162306a36Sopenharmony_ci#define RSPI_SSLP		0x01	/* Slave Select Polarity Register */
3262306a36Sopenharmony_ci#define RSPI_SPPCR		0x02	/* Pin Control Register */
3362306a36Sopenharmony_ci#define RSPI_SPSR		0x03	/* Status Register */
3462306a36Sopenharmony_ci#define RSPI_SPDR		0x04	/* Data Register */
3562306a36Sopenharmony_ci#define RSPI_SPSCR		0x08	/* Sequence Control Register */
3662306a36Sopenharmony_ci#define RSPI_SPSSR		0x09	/* Sequence Status Register */
3762306a36Sopenharmony_ci#define RSPI_SPBR		0x0a	/* Bit Rate Register */
3862306a36Sopenharmony_ci#define RSPI_SPDCR		0x0b	/* Data Control Register */
3962306a36Sopenharmony_ci#define RSPI_SPCKD		0x0c	/* Clock Delay Register */
4062306a36Sopenharmony_ci#define RSPI_SSLND		0x0d	/* Slave Select Negation Delay Register */
4162306a36Sopenharmony_ci#define RSPI_SPND		0x0e	/* Next-Access Delay Register */
4262306a36Sopenharmony_ci#define RSPI_SPCR2		0x0f	/* Control Register 2 (SH only) */
4362306a36Sopenharmony_ci#define RSPI_SPCMD0		0x10	/* Command Register 0 */
4462306a36Sopenharmony_ci#define RSPI_SPCMD1		0x12	/* Command Register 1 */
4562306a36Sopenharmony_ci#define RSPI_SPCMD2		0x14	/* Command Register 2 */
4662306a36Sopenharmony_ci#define RSPI_SPCMD3		0x16	/* Command Register 3 */
4762306a36Sopenharmony_ci#define RSPI_SPCMD4		0x18	/* Command Register 4 */
4862306a36Sopenharmony_ci#define RSPI_SPCMD5		0x1a	/* Command Register 5 */
4962306a36Sopenharmony_ci#define RSPI_SPCMD6		0x1c	/* Command Register 6 */
5062306a36Sopenharmony_ci#define RSPI_SPCMD7		0x1e	/* Command Register 7 */
5162306a36Sopenharmony_ci#define RSPI_SPCMD(i)		(RSPI_SPCMD0 + (i) * 2)
5262306a36Sopenharmony_ci#define RSPI_NUM_SPCMD		8
5362306a36Sopenharmony_ci#define RSPI_RZ_NUM_SPCMD	4
5462306a36Sopenharmony_ci#define QSPI_NUM_SPCMD		4
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/* RSPI on RZ only */
5762306a36Sopenharmony_ci#define RSPI_SPBFCR		0x20	/* Buffer Control Register */
5862306a36Sopenharmony_ci#define RSPI_SPBFDR		0x22	/* Buffer Data Count Setting Register */
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci/* QSPI only */
6162306a36Sopenharmony_ci#define QSPI_SPBFCR		0x18	/* Buffer Control Register */
6262306a36Sopenharmony_ci#define QSPI_SPBDCR		0x1a	/* Buffer Data Count Register */
6362306a36Sopenharmony_ci#define QSPI_SPBMUL0		0x1c	/* Transfer Data Length Multiplier Setting Register 0 */
6462306a36Sopenharmony_ci#define QSPI_SPBMUL1		0x20	/* Transfer Data Length Multiplier Setting Register 1 */
6562306a36Sopenharmony_ci#define QSPI_SPBMUL2		0x24	/* Transfer Data Length Multiplier Setting Register 2 */
6662306a36Sopenharmony_ci#define QSPI_SPBMUL3		0x28	/* Transfer Data Length Multiplier Setting Register 3 */
6762306a36Sopenharmony_ci#define QSPI_SPBMUL(i)		(QSPI_SPBMUL0 + (i) * 4)
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci/* SPCR - Control Register */
7062306a36Sopenharmony_ci#define SPCR_SPRIE		0x80	/* Receive Interrupt Enable */
7162306a36Sopenharmony_ci#define SPCR_SPE		0x40	/* Function Enable */
7262306a36Sopenharmony_ci#define SPCR_SPTIE		0x20	/* Transmit Interrupt Enable */
7362306a36Sopenharmony_ci#define SPCR_SPEIE		0x10	/* Error Interrupt Enable */
7462306a36Sopenharmony_ci#define SPCR_MSTR		0x08	/* Master/Slave Mode Select */
7562306a36Sopenharmony_ci#define SPCR_MODFEN		0x04	/* Mode Fault Error Detection Enable */
7662306a36Sopenharmony_ci/* RSPI on SH only */
7762306a36Sopenharmony_ci#define SPCR_TXMD		0x02	/* TX Only Mode (vs. Full Duplex) */
7862306a36Sopenharmony_ci#define SPCR_SPMS		0x01	/* 3-wire Mode (vs. 4-wire) */
7962306a36Sopenharmony_ci/* QSPI on R-Car Gen2 only */
8062306a36Sopenharmony_ci#define SPCR_WSWAP		0x02	/* Word Swap of read-data for DMAC */
8162306a36Sopenharmony_ci#define SPCR_BSWAP		0x01	/* Byte Swap of read-data for DMAC */
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci/* SSLP - Slave Select Polarity Register */
8462306a36Sopenharmony_ci#define SSLP_SSLP(i)		BIT(i)	/* SSLi Signal Polarity Setting */
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/* SPPCR - Pin Control Register */
8762306a36Sopenharmony_ci#define SPPCR_MOIFE		0x20	/* MOSI Idle Value Fixing Enable */
8862306a36Sopenharmony_ci#define SPPCR_MOIFV		0x10	/* MOSI Idle Fixed Value */
8962306a36Sopenharmony_ci#define SPPCR_SPOM		0x04
9062306a36Sopenharmony_ci#define SPPCR_SPLP2		0x02	/* Loopback Mode 2 (non-inverting) */
9162306a36Sopenharmony_ci#define SPPCR_SPLP		0x01	/* Loopback Mode (inverting) */
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci#define SPPCR_IO3FV		0x04	/* Single-/Dual-SPI Mode IO3 Output Fixed Value */
9462306a36Sopenharmony_ci#define SPPCR_IO2FV		0x04	/* Single-/Dual-SPI Mode IO2 Output Fixed Value */
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/* SPSR - Status Register */
9762306a36Sopenharmony_ci#define SPSR_SPRF		0x80	/* Receive Buffer Full Flag */
9862306a36Sopenharmony_ci#define SPSR_TEND		0x40	/* Transmit End */
9962306a36Sopenharmony_ci#define SPSR_SPTEF		0x20	/* Transmit Buffer Empty Flag */
10062306a36Sopenharmony_ci#define SPSR_PERF		0x08	/* Parity Error Flag */
10162306a36Sopenharmony_ci#define SPSR_MODF		0x04	/* Mode Fault Error Flag */
10262306a36Sopenharmony_ci#define SPSR_IDLNF		0x02	/* RSPI Idle Flag */
10362306a36Sopenharmony_ci#define SPSR_OVRF		0x01	/* Overrun Error Flag (RSPI only) */
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/* SPSCR - Sequence Control Register */
10662306a36Sopenharmony_ci#define SPSCR_SPSLN_MASK	0x07	/* Sequence Length Specification */
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/* SPSSR - Sequence Status Register */
10962306a36Sopenharmony_ci#define SPSSR_SPECM_MASK	0x70	/* Command Error Mask */
11062306a36Sopenharmony_ci#define SPSSR_SPCP_MASK		0x07	/* Command Pointer Mask */
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/* SPDCR - Data Control Register */
11362306a36Sopenharmony_ci#define SPDCR_TXDMY		0x80	/* Dummy Data Transmission Enable */
11462306a36Sopenharmony_ci#define SPDCR_SPLW1		0x40	/* Access Width Specification (RZ) */
11562306a36Sopenharmony_ci#define SPDCR_SPLW0		0x20	/* Access Width Specification (RZ) */
11662306a36Sopenharmony_ci#define SPDCR_SPLLWORD		(SPDCR_SPLW1 | SPDCR_SPLW0)
11762306a36Sopenharmony_ci#define SPDCR_SPLWORD		SPDCR_SPLW1
11862306a36Sopenharmony_ci#define SPDCR_SPLBYTE		SPDCR_SPLW0
11962306a36Sopenharmony_ci#define SPDCR_SPLW		0x20	/* Access Width Specification (SH) */
12062306a36Sopenharmony_ci#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select (SH) */
12162306a36Sopenharmony_ci#define SPDCR_SLSEL1		0x08
12262306a36Sopenharmony_ci#define SPDCR_SLSEL0		0x04
12362306a36Sopenharmony_ci#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select (SH) */
12462306a36Sopenharmony_ci#define SPDCR_SPFC1		0x02
12562306a36Sopenharmony_ci#define SPDCR_SPFC0		0x01
12662306a36Sopenharmony_ci#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) (SH) */
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/* SPCKD - Clock Delay Register */
12962306a36Sopenharmony_ci#define SPCKD_SCKDL_MASK	0x07	/* Clock Delay Setting (1-8) */
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci/* SSLND - Slave Select Negation Delay Register */
13262306a36Sopenharmony_ci#define SSLND_SLNDL_MASK	0x07	/* SSL Negation Delay Setting (1-8) */
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/* SPND - Next-Access Delay Register */
13562306a36Sopenharmony_ci#define SPND_SPNDL_MASK		0x07	/* Next-Access Delay Setting (1-8) */
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/* SPCR2 - Control Register 2 */
13862306a36Sopenharmony_ci#define SPCR2_PTE		0x08	/* Parity Self-Test Enable */
13962306a36Sopenharmony_ci#define SPCR2_SPIE		0x04	/* Idle Interrupt Enable */
14062306a36Sopenharmony_ci#define SPCR2_SPOE		0x02	/* Odd Parity Enable (vs. Even) */
14162306a36Sopenharmony_ci#define SPCR2_SPPE		0x01	/* Parity Enable */
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci/* SPCMDn - Command Registers */
14462306a36Sopenharmony_ci#define SPCMD_SCKDEN		0x8000	/* Clock Delay Setting Enable */
14562306a36Sopenharmony_ci#define SPCMD_SLNDEN		0x4000	/* SSL Negation Delay Setting Enable */
14662306a36Sopenharmony_ci#define SPCMD_SPNDEN		0x2000	/* Next-Access Delay Enable */
14762306a36Sopenharmony_ci#define SPCMD_LSBF		0x1000	/* LSB First */
14862306a36Sopenharmony_ci#define SPCMD_SPB_MASK		0x0f00	/* Data Length Setting */
14962306a36Sopenharmony_ci#define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK)
15062306a36Sopenharmony_ci#define SPCMD_SPB_8BIT		0x0000	/* QSPI only */
15162306a36Sopenharmony_ci#define SPCMD_SPB_16BIT		0x0100
15262306a36Sopenharmony_ci#define SPCMD_SPB_20BIT		0x0000
15362306a36Sopenharmony_ci#define SPCMD_SPB_24BIT		0x0100
15462306a36Sopenharmony_ci#define SPCMD_SPB_32BIT		0x0200
15562306a36Sopenharmony_ci#define SPCMD_SSLKP		0x0080	/* SSL Signal Level Keeping */
15662306a36Sopenharmony_ci#define SPCMD_SPIMOD_MASK	0x0060	/* SPI Operating Mode (QSPI only) */
15762306a36Sopenharmony_ci#define SPCMD_SPIMOD1		0x0040
15862306a36Sopenharmony_ci#define SPCMD_SPIMOD0		0x0020
15962306a36Sopenharmony_ci#define SPCMD_SPIMOD_SINGLE	0
16062306a36Sopenharmony_ci#define SPCMD_SPIMOD_DUAL	SPCMD_SPIMOD0
16162306a36Sopenharmony_ci#define SPCMD_SPIMOD_QUAD	SPCMD_SPIMOD1
16262306a36Sopenharmony_ci#define SPCMD_SPRW		0x0010	/* SPI Read/Write Access (Dual/Quad) */
16362306a36Sopenharmony_ci#define SPCMD_SSLA(i)		((i) << 4)	/* SSL Assert Signal Setting */
16462306a36Sopenharmony_ci#define SPCMD_BRDV_MASK		0x000c	/* Bit Rate Division Setting */
16562306a36Sopenharmony_ci#define SPCMD_BRDV(brdv)	((brdv) << 2)
16662306a36Sopenharmony_ci#define SPCMD_CPOL		0x0002	/* Clock Polarity Setting */
16762306a36Sopenharmony_ci#define SPCMD_CPHA		0x0001	/* Clock Phase Setting */
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/* SPBFCR - Buffer Control Register */
17062306a36Sopenharmony_ci#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset */
17162306a36Sopenharmony_ci#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset */
17262306a36Sopenharmony_ci#define SPBFCR_TXTRG_MASK	0x30	/* Transmit Buffer Data Triggering Number */
17362306a36Sopenharmony_ci#define SPBFCR_RXTRG_MASK	0x07	/* Receive Buffer Data Triggering Number */
17462306a36Sopenharmony_ci/* QSPI on R-Car Gen2 */
17562306a36Sopenharmony_ci#define SPBFCR_TXTRG_1B		0x00	/* 31 bytes (1 byte available) */
17662306a36Sopenharmony_ci#define SPBFCR_TXTRG_32B	0x30	/* 0 byte (32 bytes available) */
17762306a36Sopenharmony_ci#define SPBFCR_RXTRG_1B		0x00	/* 1 byte (31 bytes available) */
17862306a36Sopenharmony_ci#define SPBFCR_RXTRG_32B	0x07	/* 32 bytes (0 byte available) */
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci#define QSPI_BUFFER_SIZE        32u
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistruct rspi_data {
18362306a36Sopenharmony_ci	void __iomem *addr;
18462306a36Sopenharmony_ci	u32 speed_hz;
18562306a36Sopenharmony_ci	struct spi_controller *ctlr;
18662306a36Sopenharmony_ci	struct platform_device *pdev;
18762306a36Sopenharmony_ci	wait_queue_head_t wait;
18862306a36Sopenharmony_ci	spinlock_t lock;		/* Protects RMW-access to RSPI_SSLP */
18962306a36Sopenharmony_ci	struct clk *clk;
19062306a36Sopenharmony_ci	u16 spcmd;
19162306a36Sopenharmony_ci	u8 spsr;
19262306a36Sopenharmony_ci	u8 sppcr;
19362306a36Sopenharmony_ci	int rx_irq, tx_irq;
19462306a36Sopenharmony_ci	const struct spi_ops *ops;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	unsigned dma_callbacked:1;
19762306a36Sopenharmony_ci	unsigned byte_access:1;
19862306a36Sopenharmony_ci};
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	iowrite8(data, rspi->addr + offset);
20362306a36Sopenharmony_ci}
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cistatic void rspi_write16(const struct rspi_data *rspi, u16 data, u16 offset)
20662306a36Sopenharmony_ci{
20762306a36Sopenharmony_ci	iowrite16(data, rspi->addr + offset);
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic void rspi_write32(const struct rspi_data *rspi, u32 data, u16 offset)
21162306a36Sopenharmony_ci{
21262306a36Sopenharmony_ci	iowrite32(data, rspi->addr + offset);
21362306a36Sopenharmony_ci}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_cistatic u8 rspi_read8(const struct rspi_data *rspi, u16 offset)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	return ioread8(rspi->addr + offset);
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_cistatic u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
22162306a36Sopenharmony_ci{
22262306a36Sopenharmony_ci	return ioread16(rspi->addr + offset);
22362306a36Sopenharmony_ci}
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_cistatic void rspi_write_data(const struct rspi_data *rspi, u16 data)
22662306a36Sopenharmony_ci{
22762306a36Sopenharmony_ci	if (rspi->byte_access)
22862306a36Sopenharmony_ci		rspi_write8(rspi, data, RSPI_SPDR);
22962306a36Sopenharmony_ci	else /* 16 bit */
23062306a36Sopenharmony_ci		rspi_write16(rspi, data, RSPI_SPDR);
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic u16 rspi_read_data(const struct rspi_data *rspi)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	if (rspi->byte_access)
23662306a36Sopenharmony_ci		return rspi_read8(rspi, RSPI_SPDR);
23762306a36Sopenharmony_ci	else /* 16 bit */
23862306a36Sopenharmony_ci		return rspi_read16(rspi, RSPI_SPDR);
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci/* optional functions */
24262306a36Sopenharmony_cistruct spi_ops {
24362306a36Sopenharmony_ci	int (*set_config_register)(struct rspi_data *rspi, int access_size);
24462306a36Sopenharmony_ci	int (*transfer_one)(struct spi_controller *ctlr,
24562306a36Sopenharmony_ci			    struct spi_device *spi, struct spi_transfer *xfer);
24662306a36Sopenharmony_ci	u16 extra_mode_bits;
24762306a36Sopenharmony_ci	u16 min_div;
24862306a36Sopenharmony_ci	u16 max_div;
24962306a36Sopenharmony_ci	u16 flags;
25062306a36Sopenharmony_ci	u16 fifo_size;
25162306a36Sopenharmony_ci	u8 num_hw_ss;
25262306a36Sopenharmony_ci};
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic void rspi_set_rate(struct rspi_data *rspi)
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci	unsigned long clksrc;
25762306a36Sopenharmony_ci	int brdv = 0, spbr;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	clksrc = clk_get_rate(rspi->clk);
26062306a36Sopenharmony_ci	spbr = DIV_ROUND_UP(clksrc, 2 * rspi->speed_hz) - 1;
26162306a36Sopenharmony_ci	while (spbr > 255 && brdv < 3) {
26262306a36Sopenharmony_ci		brdv++;
26362306a36Sopenharmony_ci		spbr = DIV_ROUND_UP(spbr + 1, 2) - 1;
26462306a36Sopenharmony_ci	}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
26762306a36Sopenharmony_ci	rspi->spcmd |= SPCMD_BRDV(brdv);
26862306a36Sopenharmony_ci	rspi->speed_hz = DIV_ROUND_UP(clksrc, (2U << brdv) * (spbr + 1));
26962306a36Sopenharmony_ci}
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci/*
27262306a36Sopenharmony_ci * functions for RSPI on legacy SH
27362306a36Sopenharmony_ci */
27462306a36Sopenharmony_cistatic int rspi_set_config_register(struct rspi_data *rspi, int access_size)
27562306a36Sopenharmony_ci{
27662306a36Sopenharmony_ci	/* Sets output mode, MOSI signal, and (optionally) loopback */
27762306a36Sopenharmony_ci	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	/* Sets transfer bit rate */
28062306a36Sopenharmony_ci	rspi_set_rate(rspi);
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	/* Disable dummy transmission, set 16-bit word access, 1 frame */
28362306a36Sopenharmony_ci	rspi_write8(rspi, 0, RSPI_SPDCR);
28462306a36Sopenharmony_ci	rspi->byte_access = 0;
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	/* Sets RSPCK, SSL, next-access delay value */
28762306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SPCKD);
28862306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SSLND);
28962306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SPND);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	/* Sets parity, interrupt mask */
29262306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SPCR2);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	/* Resets sequencer */
29562306a36Sopenharmony_ci	rspi_write8(rspi, 0, RSPI_SPSCR);
29662306a36Sopenharmony_ci	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
29762306a36Sopenharmony_ci	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	/* Sets RSPI mode */
30062306a36Sopenharmony_ci	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	return 0;
30362306a36Sopenharmony_ci}
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci/*
30662306a36Sopenharmony_ci * functions for RSPI on RZ
30762306a36Sopenharmony_ci */
30862306a36Sopenharmony_cistatic int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	/* Sets output mode, MOSI signal, and (optionally) loopback */
31162306a36Sopenharmony_ci	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	/* Sets transfer bit rate */
31462306a36Sopenharmony_ci	rspi_set_rate(rspi);
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	/* Disable dummy transmission, set byte access */
31762306a36Sopenharmony_ci	rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR);
31862306a36Sopenharmony_ci	rspi->byte_access = 1;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	/* Sets RSPCK, SSL, next-access delay value */
32162306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SPCKD);
32262306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SSLND);
32362306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SPND);
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	/* Resets sequencer */
32662306a36Sopenharmony_ci	rspi_write8(rspi, 0, RSPI_SPSCR);
32762306a36Sopenharmony_ci	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
32862306a36Sopenharmony_ci	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	/* Sets RSPI mode */
33162306a36Sopenharmony_ci	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	return 0;
33462306a36Sopenharmony_ci}
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci/*
33762306a36Sopenharmony_ci * functions for QSPI
33862306a36Sopenharmony_ci */
33962306a36Sopenharmony_cistatic int qspi_set_config_register(struct rspi_data *rspi, int access_size)
34062306a36Sopenharmony_ci{
34162306a36Sopenharmony_ci	unsigned long clksrc;
34262306a36Sopenharmony_ci	int brdv = 0, spbr;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	/* Sets output mode, MOSI signal, and (optionally) loopback */
34562306a36Sopenharmony_ci	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	/* Sets transfer bit rate */
34862306a36Sopenharmony_ci	clksrc = clk_get_rate(rspi->clk);
34962306a36Sopenharmony_ci	if (rspi->speed_hz >= clksrc) {
35062306a36Sopenharmony_ci		spbr = 0;
35162306a36Sopenharmony_ci		rspi->speed_hz = clksrc;
35262306a36Sopenharmony_ci	} else {
35362306a36Sopenharmony_ci		spbr = DIV_ROUND_UP(clksrc, 2 * rspi->speed_hz);
35462306a36Sopenharmony_ci		while (spbr > 255 && brdv < 3) {
35562306a36Sopenharmony_ci			brdv++;
35662306a36Sopenharmony_ci			spbr = DIV_ROUND_UP(spbr, 2);
35762306a36Sopenharmony_ci		}
35862306a36Sopenharmony_ci		spbr = clamp(spbr, 0, 255);
35962306a36Sopenharmony_ci		rspi->speed_hz = DIV_ROUND_UP(clksrc, (2U << brdv) * spbr);
36062306a36Sopenharmony_ci	}
36162306a36Sopenharmony_ci	rspi_write8(rspi, spbr, RSPI_SPBR);
36262306a36Sopenharmony_ci	rspi->spcmd |= SPCMD_BRDV(brdv);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	/* Disable dummy transmission, set byte access */
36562306a36Sopenharmony_ci	rspi_write8(rspi, 0, RSPI_SPDCR);
36662306a36Sopenharmony_ci	rspi->byte_access = 1;
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	/* Sets RSPCK, SSL, next-access delay value */
36962306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SPCKD);
37062306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SSLND);
37162306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, RSPI_SPND);
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	/* Data Length Setting */
37462306a36Sopenharmony_ci	if (access_size == 8)
37562306a36Sopenharmony_ci		rspi->spcmd |= SPCMD_SPB_8BIT;
37662306a36Sopenharmony_ci	else if (access_size == 16)
37762306a36Sopenharmony_ci		rspi->spcmd |= SPCMD_SPB_16BIT;
37862306a36Sopenharmony_ci	else
37962306a36Sopenharmony_ci		rspi->spcmd |= SPCMD_SPB_32BIT;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	rspi->spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SPNDEN;
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	/* Resets transfer data length */
38462306a36Sopenharmony_ci	rspi_write32(rspi, 0, QSPI_SPBMUL0);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	/* Resets transmit and receive buffer */
38762306a36Sopenharmony_ci	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
38862306a36Sopenharmony_ci	/* Sets buffer to allow normal operation */
38962306a36Sopenharmony_ci	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	/* Resets sequencer */
39262306a36Sopenharmony_ci	rspi_write8(rspi, 0, RSPI_SPSCR);
39362306a36Sopenharmony_ci	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	/* Sets RSPI mode */
39662306a36Sopenharmony_ci	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	return 0;
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic void qspi_update(const struct rspi_data *rspi, u8 mask, u8 val, u8 reg)
40262306a36Sopenharmony_ci{
40362306a36Sopenharmony_ci	u8 data;
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	data = rspi_read8(rspi, reg);
40662306a36Sopenharmony_ci	data &= ~mask;
40762306a36Sopenharmony_ci	data |= (val & mask);
40862306a36Sopenharmony_ci	rspi_write8(rspi, data, reg);
40962306a36Sopenharmony_ci}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_cistatic unsigned int qspi_set_send_trigger(struct rspi_data *rspi,
41262306a36Sopenharmony_ci					  unsigned int len)
41362306a36Sopenharmony_ci{
41462306a36Sopenharmony_ci	unsigned int n;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	n = min(len, QSPI_BUFFER_SIZE);
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	if (len >= QSPI_BUFFER_SIZE) {
41962306a36Sopenharmony_ci		/* sets triggering number to 32 bytes */
42062306a36Sopenharmony_ci		qspi_update(rspi, SPBFCR_TXTRG_MASK,
42162306a36Sopenharmony_ci			     SPBFCR_TXTRG_32B, QSPI_SPBFCR);
42262306a36Sopenharmony_ci	} else {
42362306a36Sopenharmony_ci		/* sets triggering number to 1 byte */
42462306a36Sopenharmony_ci		qspi_update(rspi, SPBFCR_TXTRG_MASK,
42562306a36Sopenharmony_ci			     SPBFCR_TXTRG_1B, QSPI_SPBFCR);
42662306a36Sopenharmony_ci	}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	return n;
42962306a36Sopenharmony_ci}
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_cistatic int qspi_set_receive_trigger(struct rspi_data *rspi, unsigned int len)
43262306a36Sopenharmony_ci{
43362306a36Sopenharmony_ci	unsigned int n;
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci	n = min(len, QSPI_BUFFER_SIZE);
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	if (len >= QSPI_BUFFER_SIZE) {
43862306a36Sopenharmony_ci		/* sets triggering number to 32 bytes */
43962306a36Sopenharmony_ci		qspi_update(rspi, SPBFCR_RXTRG_MASK,
44062306a36Sopenharmony_ci			     SPBFCR_RXTRG_32B, QSPI_SPBFCR);
44162306a36Sopenharmony_ci	} else {
44262306a36Sopenharmony_ci		/* sets triggering number to 1 byte */
44362306a36Sopenharmony_ci		qspi_update(rspi, SPBFCR_RXTRG_MASK,
44462306a36Sopenharmony_ci			     SPBFCR_RXTRG_1B, QSPI_SPBFCR);
44562306a36Sopenharmony_ci	}
44662306a36Sopenharmony_ci	return n;
44762306a36Sopenharmony_ci}
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_cistatic void rspi_enable_irq(const struct rspi_data *rspi, u8 enable)
45062306a36Sopenharmony_ci{
45162306a36Sopenharmony_ci	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR);
45262306a36Sopenharmony_ci}
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_cistatic void rspi_disable_irq(const struct rspi_data *rspi, u8 disable)
45562306a36Sopenharmony_ci{
45662306a36Sopenharmony_ci	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~disable, RSPI_SPCR);
45762306a36Sopenharmony_ci}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_cistatic int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
46062306a36Sopenharmony_ci				   u8 enable_bit)
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci	int ret;
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	rspi->spsr = rspi_read8(rspi, RSPI_SPSR);
46562306a36Sopenharmony_ci	if (rspi->spsr & wait_mask)
46662306a36Sopenharmony_ci		return 0;
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	rspi_enable_irq(rspi, enable_bit);
46962306a36Sopenharmony_ci	ret = wait_event_timeout(rspi->wait, rspi->spsr & wait_mask, HZ);
47062306a36Sopenharmony_ci	if (ret == 0 && !(rspi->spsr & wait_mask))
47162306a36Sopenharmony_ci		return -ETIMEDOUT;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	return 0;
47462306a36Sopenharmony_ci}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistatic inline int rspi_wait_for_tx_empty(struct rspi_data *rspi)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	return rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_cistatic inline int rspi_wait_for_rx_full(struct rspi_data *rspi)
48262306a36Sopenharmony_ci{
48362306a36Sopenharmony_ci	return rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE);
48462306a36Sopenharmony_ci}
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_cistatic int rspi_data_out(struct rspi_data *rspi, u8 data)
48762306a36Sopenharmony_ci{
48862306a36Sopenharmony_ci	int error = rspi_wait_for_tx_empty(rspi);
48962306a36Sopenharmony_ci	if (error < 0) {
49062306a36Sopenharmony_ci		dev_err(&rspi->ctlr->dev, "transmit timeout\n");
49162306a36Sopenharmony_ci		return error;
49262306a36Sopenharmony_ci	}
49362306a36Sopenharmony_ci	rspi_write_data(rspi, data);
49462306a36Sopenharmony_ci	return 0;
49562306a36Sopenharmony_ci}
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_cistatic int rspi_data_in(struct rspi_data *rspi)
49862306a36Sopenharmony_ci{
49962306a36Sopenharmony_ci	int error;
50062306a36Sopenharmony_ci	u8 data;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	error = rspi_wait_for_rx_full(rspi);
50362306a36Sopenharmony_ci	if (error < 0) {
50462306a36Sopenharmony_ci		dev_err(&rspi->ctlr->dev, "receive timeout\n");
50562306a36Sopenharmony_ci		return error;
50662306a36Sopenharmony_ci	}
50762306a36Sopenharmony_ci	data = rspi_read_data(rspi);
50862306a36Sopenharmony_ci	return data;
50962306a36Sopenharmony_ci}
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_cistatic int rspi_pio_transfer(struct rspi_data *rspi, const u8 *tx, u8 *rx,
51262306a36Sopenharmony_ci			     unsigned int n)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	while (n-- > 0) {
51562306a36Sopenharmony_ci		if (tx) {
51662306a36Sopenharmony_ci			int ret = rspi_data_out(rspi, *tx++);
51762306a36Sopenharmony_ci			if (ret < 0)
51862306a36Sopenharmony_ci				return ret;
51962306a36Sopenharmony_ci		}
52062306a36Sopenharmony_ci		if (rx) {
52162306a36Sopenharmony_ci			int ret = rspi_data_in(rspi);
52262306a36Sopenharmony_ci			if (ret < 0)
52362306a36Sopenharmony_ci				return ret;
52462306a36Sopenharmony_ci			*rx++ = ret;
52562306a36Sopenharmony_ci		}
52662306a36Sopenharmony_ci	}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	return 0;
52962306a36Sopenharmony_ci}
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_cistatic void rspi_dma_complete(void *arg)
53262306a36Sopenharmony_ci{
53362306a36Sopenharmony_ci	struct rspi_data *rspi = arg;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	rspi->dma_callbacked = 1;
53662306a36Sopenharmony_ci	wake_up_interruptible(&rspi->wait);
53762306a36Sopenharmony_ci}
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_cistatic int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
54062306a36Sopenharmony_ci			     struct sg_table *rx)
54162306a36Sopenharmony_ci{
54262306a36Sopenharmony_ci	struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
54362306a36Sopenharmony_ci	u8 irq_mask = 0;
54462306a36Sopenharmony_ci	unsigned int other_irq = 0;
54562306a36Sopenharmony_ci	dma_cookie_t cookie;
54662306a36Sopenharmony_ci	int ret;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	/* First prepare and submit the DMA request(s), as this may fail */
54962306a36Sopenharmony_ci	if (rx) {
55062306a36Sopenharmony_ci		desc_rx = dmaengine_prep_slave_sg(rspi->ctlr->dma_rx, rx->sgl,
55162306a36Sopenharmony_ci					rx->nents, DMA_DEV_TO_MEM,
55262306a36Sopenharmony_ci					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
55362306a36Sopenharmony_ci		if (!desc_rx) {
55462306a36Sopenharmony_ci			ret = -EAGAIN;
55562306a36Sopenharmony_ci			goto no_dma_rx;
55662306a36Sopenharmony_ci		}
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci		desc_rx->callback = rspi_dma_complete;
55962306a36Sopenharmony_ci		desc_rx->callback_param = rspi;
56062306a36Sopenharmony_ci		cookie = dmaengine_submit(desc_rx);
56162306a36Sopenharmony_ci		if (dma_submit_error(cookie)) {
56262306a36Sopenharmony_ci			ret = cookie;
56362306a36Sopenharmony_ci			goto no_dma_rx;
56462306a36Sopenharmony_ci		}
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci		irq_mask |= SPCR_SPRIE;
56762306a36Sopenharmony_ci	}
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	if (tx) {
57062306a36Sopenharmony_ci		desc_tx = dmaengine_prep_slave_sg(rspi->ctlr->dma_tx, tx->sgl,
57162306a36Sopenharmony_ci					tx->nents, DMA_MEM_TO_DEV,
57262306a36Sopenharmony_ci					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
57362306a36Sopenharmony_ci		if (!desc_tx) {
57462306a36Sopenharmony_ci			ret = -EAGAIN;
57562306a36Sopenharmony_ci			goto no_dma_tx;
57662306a36Sopenharmony_ci		}
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci		if (rx) {
57962306a36Sopenharmony_ci			/* No callback */
58062306a36Sopenharmony_ci			desc_tx->callback = NULL;
58162306a36Sopenharmony_ci		} else {
58262306a36Sopenharmony_ci			desc_tx->callback = rspi_dma_complete;
58362306a36Sopenharmony_ci			desc_tx->callback_param = rspi;
58462306a36Sopenharmony_ci		}
58562306a36Sopenharmony_ci		cookie = dmaengine_submit(desc_tx);
58662306a36Sopenharmony_ci		if (dma_submit_error(cookie)) {
58762306a36Sopenharmony_ci			ret = cookie;
58862306a36Sopenharmony_ci			goto no_dma_tx;
58962306a36Sopenharmony_ci		}
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci		irq_mask |= SPCR_SPTIE;
59262306a36Sopenharmony_ci	}
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	/*
59562306a36Sopenharmony_ci	 * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be
59662306a36Sopenharmony_ci	 * called. So, this driver disables the IRQ while DMA transfer.
59762306a36Sopenharmony_ci	 */
59862306a36Sopenharmony_ci	if (tx)
59962306a36Sopenharmony_ci		disable_irq(other_irq = rspi->tx_irq);
60062306a36Sopenharmony_ci	if (rx && rspi->rx_irq != other_irq)
60162306a36Sopenharmony_ci		disable_irq(rspi->rx_irq);
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	rspi_enable_irq(rspi, irq_mask);
60462306a36Sopenharmony_ci	rspi->dma_callbacked = 0;
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	/* Now start DMA */
60762306a36Sopenharmony_ci	if (rx)
60862306a36Sopenharmony_ci		dma_async_issue_pending(rspi->ctlr->dma_rx);
60962306a36Sopenharmony_ci	if (tx)
61062306a36Sopenharmony_ci		dma_async_issue_pending(rspi->ctlr->dma_tx);
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	ret = wait_event_interruptible_timeout(rspi->wait,
61362306a36Sopenharmony_ci					       rspi->dma_callbacked, HZ);
61462306a36Sopenharmony_ci	if (ret > 0 && rspi->dma_callbacked) {
61562306a36Sopenharmony_ci		ret = 0;
61662306a36Sopenharmony_ci		if (tx)
61762306a36Sopenharmony_ci			dmaengine_synchronize(rspi->ctlr->dma_tx);
61862306a36Sopenharmony_ci		if (rx)
61962306a36Sopenharmony_ci			dmaengine_synchronize(rspi->ctlr->dma_rx);
62062306a36Sopenharmony_ci	} else {
62162306a36Sopenharmony_ci		if (!ret) {
62262306a36Sopenharmony_ci			dev_err(&rspi->ctlr->dev, "DMA timeout\n");
62362306a36Sopenharmony_ci			ret = -ETIMEDOUT;
62462306a36Sopenharmony_ci		}
62562306a36Sopenharmony_ci		if (tx)
62662306a36Sopenharmony_ci			dmaengine_terminate_sync(rspi->ctlr->dma_tx);
62762306a36Sopenharmony_ci		if (rx)
62862306a36Sopenharmony_ci			dmaengine_terminate_sync(rspi->ctlr->dma_rx);
62962306a36Sopenharmony_ci	}
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	rspi_disable_irq(rspi, irq_mask);
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	if (tx)
63462306a36Sopenharmony_ci		enable_irq(rspi->tx_irq);
63562306a36Sopenharmony_ci	if (rx && rspi->rx_irq != other_irq)
63662306a36Sopenharmony_ci		enable_irq(rspi->rx_irq);
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	return ret;
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_cino_dma_tx:
64162306a36Sopenharmony_ci	if (rx)
64262306a36Sopenharmony_ci		dmaengine_terminate_sync(rspi->ctlr->dma_rx);
64362306a36Sopenharmony_cino_dma_rx:
64462306a36Sopenharmony_ci	if (ret == -EAGAIN) {
64562306a36Sopenharmony_ci		dev_warn_once(&rspi->ctlr->dev,
64662306a36Sopenharmony_ci			      "DMA not available, falling back to PIO\n");
64762306a36Sopenharmony_ci	}
64862306a36Sopenharmony_ci	return ret;
64962306a36Sopenharmony_ci}
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_cistatic void rspi_receive_init(const struct rspi_data *rspi)
65262306a36Sopenharmony_ci{
65362306a36Sopenharmony_ci	u8 spsr;
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	spsr = rspi_read8(rspi, RSPI_SPSR);
65662306a36Sopenharmony_ci	if (spsr & SPSR_SPRF)
65762306a36Sopenharmony_ci		rspi_read_data(rspi);	/* dummy read */
65862306a36Sopenharmony_ci	if (spsr & SPSR_OVRF)
65962306a36Sopenharmony_ci		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
66062306a36Sopenharmony_ci			    RSPI_SPSR);
66162306a36Sopenharmony_ci}
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_cistatic void rspi_rz_receive_init(const struct rspi_data *rspi)
66462306a36Sopenharmony_ci{
66562306a36Sopenharmony_ci	rspi_receive_init(rspi);
66662306a36Sopenharmony_ci	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, RSPI_SPBFCR);
66762306a36Sopenharmony_ci	rspi_write8(rspi, 0, RSPI_SPBFCR);
66862306a36Sopenharmony_ci}
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_cistatic void qspi_receive_init(const struct rspi_data *rspi)
67162306a36Sopenharmony_ci{
67262306a36Sopenharmony_ci	u8 spsr;
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	spsr = rspi_read8(rspi, RSPI_SPSR);
67562306a36Sopenharmony_ci	if (spsr & SPSR_SPRF)
67662306a36Sopenharmony_ci		rspi_read_data(rspi);   /* dummy read */
67762306a36Sopenharmony_ci	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
67862306a36Sopenharmony_ci	rspi_write8(rspi, 0, QSPI_SPBFCR);
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cistatic bool __rspi_can_dma(const struct rspi_data *rspi,
68262306a36Sopenharmony_ci			   const struct spi_transfer *xfer)
68362306a36Sopenharmony_ci{
68462306a36Sopenharmony_ci	return xfer->len > rspi->ops->fifo_size;
68562306a36Sopenharmony_ci}
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_cistatic bool rspi_can_dma(struct spi_controller *ctlr, struct spi_device *spi,
68862306a36Sopenharmony_ci			 struct spi_transfer *xfer)
68962306a36Sopenharmony_ci{
69062306a36Sopenharmony_ci	struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	return __rspi_can_dma(rspi, xfer);
69362306a36Sopenharmony_ci}
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_cistatic int rspi_dma_check_then_transfer(struct rspi_data *rspi,
69662306a36Sopenharmony_ci					 struct spi_transfer *xfer)
69762306a36Sopenharmony_ci{
69862306a36Sopenharmony_ci	if (!rspi->ctlr->can_dma || !__rspi_can_dma(rspi, xfer))
69962306a36Sopenharmony_ci		return -EAGAIN;
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci	/* rx_buf can be NULL on RSPI on SH in TX-only Mode */
70262306a36Sopenharmony_ci	return rspi_dma_transfer(rspi, &xfer->tx_sg,
70362306a36Sopenharmony_ci				xfer->rx_buf ? &xfer->rx_sg : NULL);
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_cistatic int rspi_common_transfer(struct rspi_data *rspi,
70762306a36Sopenharmony_ci				struct spi_transfer *xfer)
70862306a36Sopenharmony_ci{
70962306a36Sopenharmony_ci	int ret;
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	xfer->effective_speed_hz = rspi->speed_hz;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	ret = rspi_dma_check_then_transfer(rspi, xfer);
71462306a36Sopenharmony_ci	if (ret != -EAGAIN)
71562306a36Sopenharmony_ci		return ret;
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len);
71862306a36Sopenharmony_ci	if (ret < 0)
71962306a36Sopenharmony_ci		return ret;
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	/* Wait for the last transmission */
72262306a36Sopenharmony_ci	rspi_wait_for_tx_empty(rspi);
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	return 0;
72562306a36Sopenharmony_ci}
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_cistatic int rspi_transfer_one(struct spi_controller *ctlr,
72862306a36Sopenharmony_ci			     struct spi_device *spi, struct spi_transfer *xfer)
72962306a36Sopenharmony_ci{
73062306a36Sopenharmony_ci	struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
73162306a36Sopenharmony_ci	u8 spcr;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	spcr = rspi_read8(rspi, RSPI_SPCR);
73462306a36Sopenharmony_ci	if (xfer->rx_buf) {
73562306a36Sopenharmony_ci		rspi_receive_init(rspi);
73662306a36Sopenharmony_ci		spcr &= ~SPCR_TXMD;
73762306a36Sopenharmony_ci	} else {
73862306a36Sopenharmony_ci		spcr |= SPCR_TXMD;
73962306a36Sopenharmony_ci	}
74062306a36Sopenharmony_ci	rspi_write8(rspi, spcr, RSPI_SPCR);
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	return rspi_common_transfer(rspi, xfer);
74362306a36Sopenharmony_ci}
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_cistatic int rspi_rz_transfer_one(struct spi_controller *ctlr,
74662306a36Sopenharmony_ci				struct spi_device *spi,
74762306a36Sopenharmony_ci				struct spi_transfer *xfer)
74862306a36Sopenharmony_ci{
74962306a36Sopenharmony_ci	struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	rspi_rz_receive_init(rspi);
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci	return rspi_common_transfer(rspi, xfer);
75462306a36Sopenharmony_ci}
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_cistatic int qspi_trigger_transfer_out_in(struct rspi_data *rspi, const u8 *tx,
75762306a36Sopenharmony_ci					u8 *rx, unsigned int len)
75862306a36Sopenharmony_ci{
75962306a36Sopenharmony_ci	unsigned int i, n;
76062306a36Sopenharmony_ci	int ret;
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	while (len > 0) {
76362306a36Sopenharmony_ci		n = qspi_set_send_trigger(rspi, len);
76462306a36Sopenharmony_ci		qspi_set_receive_trigger(rspi, len);
76562306a36Sopenharmony_ci		ret = rspi_wait_for_tx_empty(rspi);
76662306a36Sopenharmony_ci		if (ret < 0) {
76762306a36Sopenharmony_ci			dev_err(&rspi->ctlr->dev, "transmit timeout\n");
76862306a36Sopenharmony_ci			return ret;
76962306a36Sopenharmony_ci		}
77062306a36Sopenharmony_ci		for (i = 0; i < n; i++)
77162306a36Sopenharmony_ci			rspi_write_data(rspi, *tx++);
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci		ret = rspi_wait_for_rx_full(rspi);
77462306a36Sopenharmony_ci		if (ret < 0) {
77562306a36Sopenharmony_ci			dev_err(&rspi->ctlr->dev, "receive timeout\n");
77662306a36Sopenharmony_ci			return ret;
77762306a36Sopenharmony_ci		}
77862306a36Sopenharmony_ci		for (i = 0; i < n; i++)
77962306a36Sopenharmony_ci			*rx++ = rspi_read_data(rspi);
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci		len -= n;
78262306a36Sopenharmony_ci	}
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci	return 0;
78562306a36Sopenharmony_ci}
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_cistatic int qspi_transfer_out_in(struct rspi_data *rspi,
78862306a36Sopenharmony_ci				struct spi_transfer *xfer)
78962306a36Sopenharmony_ci{
79062306a36Sopenharmony_ci	int ret;
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci	qspi_receive_init(rspi);
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_ci	ret = rspi_dma_check_then_transfer(rspi, xfer);
79562306a36Sopenharmony_ci	if (ret != -EAGAIN)
79662306a36Sopenharmony_ci		return ret;
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci	return qspi_trigger_transfer_out_in(rspi, xfer->tx_buf,
79962306a36Sopenharmony_ci					    xfer->rx_buf, xfer->len);
80062306a36Sopenharmony_ci}
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_cistatic int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
80362306a36Sopenharmony_ci{
80462306a36Sopenharmony_ci	const u8 *tx = xfer->tx_buf;
80562306a36Sopenharmony_ci	unsigned int n = xfer->len;
80662306a36Sopenharmony_ci	unsigned int i, len;
80762306a36Sopenharmony_ci	int ret;
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci	if (rspi->ctlr->can_dma && __rspi_can_dma(rspi, xfer)) {
81062306a36Sopenharmony_ci		ret = rspi_dma_transfer(rspi, &xfer->tx_sg, NULL);
81162306a36Sopenharmony_ci		if (ret != -EAGAIN)
81262306a36Sopenharmony_ci			return ret;
81362306a36Sopenharmony_ci	}
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	while (n > 0) {
81662306a36Sopenharmony_ci		len = qspi_set_send_trigger(rspi, n);
81762306a36Sopenharmony_ci		ret = rspi_wait_for_tx_empty(rspi);
81862306a36Sopenharmony_ci		if (ret < 0) {
81962306a36Sopenharmony_ci			dev_err(&rspi->ctlr->dev, "transmit timeout\n");
82062306a36Sopenharmony_ci			return ret;
82162306a36Sopenharmony_ci		}
82262306a36Sopenharmony_ci		for (i = 0; i < len; i++)
82362306a36Sopenharmony_ci			rspi_write_data(rspi, *tx++);
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci		n -= len;
82662306a36Sopenharmony_ci	}
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	/* Wait for the last transmission */
82962306a36Sopenharmony_ci	rspi_wait_for_tx_empty(rspi);
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	return 0;
83262306a36Sopenharmony_ci}
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_cistatic int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
83562306a36Sopenharmony_ci{
83662306a36Sopenharmony_ci	u8 *rx = xfer->rx_buf;
83762306a36Sopenharmony_ci	unsigned int n = xfer->len;
83862306a36Sopenharmony_ci	unsigned int i, len;
83962306a36Sopenharmony_ci	int ret;
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	if (rspi->ctlr->can_dma && __rspi_can_dma(rspi, xfer)) {
84262306a36Sopenharmony_ci		ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
84362306a36Sopenharmony_ci		if (ret != -EAGAIN)
84462306a36Sopenharmony_ci			return ret;
84562306a36Sopenharmony_ci	}
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	while (n > 0) {
84862306a36Sopenharmony_ci		len = qspi_set_receive_trigger(rspi, n);
84962306a36Sopenharmony_ci		ret = rspi_wait_for_rx_full(rspi);
85062306a36Sopenharmony_ci		if (ret < 0) {
85162306a36Sopenharmony_ci			dev_err(&rspi->ctlr->dev, "receive timeout\n");
85262306a36Sopenharmony_ci			return ret;
85362306a36Sopenharmony_ci		}
85462306a36Sopenharmony_ci		for (i = 0; i < len; i++)
85562306a36Sopenharmony_ci			*rx++ = rspi_read_data(rspi);
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci		n -= len;
85862306a36Sopenharmony_ci	}
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	return 0;
86162306a36Sopenharmony_ci}
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_cistatic int qspi_transfer_one(struct spi_controller *ctlr,
86462306a36Sopenharmony_ci			     struct spi_device *spi, struct spi_transfer *xfer)
86562306a36Sopenharmony_ci{
86662306a36Sopenharmony_ci	struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	xfer->effective_speed_hz = rspi->speed_hz;
86962306a36Sopenharmony_ci	if (spi->mode & SPI_LOOP) {
87062306a36Sopenharmony_ci		return qspi_transfer_out_in(rspi, xfer);
87162306a36Sopenharmony_ci	} else if (xfer->tx_nbits > SPI_NBITS_SINGLE) {
87262306a36Sopenharmony_ci		/* Quad or Dual SPI Write */
87362306a36Sopenharmony_ci		return qspi_transfer_out(rspi, xfer);
87462306a36Sopenharmony_ci	} else if (xfer->rx_nbits > SPI_NBITS_SINGLE) {
87562306a36Sopenharmony_ci		/* Quad or Dual SPI Read */
87662306a36Sopenharmony_ci		return qspi_transfer_in(rspi, xfer);
87762306a36Sopenharmony_ci	} else {
87862306a36Sopenharmony_ci		/* Single SPI Transfer */
87962306a36Sopenharmony_ci		return qspi_transfer_out_in(rspi, xfer);
88062306a36Sopenharmony_ci	}
88162306a36Sopenharmony_ci}
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_cistatic u16 qspi_transfer_mode(const struct spi_transfer *xfer)
88462306a36Sopenharmony_ci{
88562306a36Sopenharmony_ci	if (xfer->tx_buf)
88662306a36Sopenharmony_ci		switch (xfer->tx_nbits) {
88762306a36Sopenharmony_ci		case SPI_NBITS_QUAD:
88862306a36Sopenharmony_ci			return SPCMD_SPIMOD_QUAD;
88962306a36Sopenharmony_ci		case SPI_NBITS_DUAL:
89062306a36Sopenharmony_ci			return SPCMD_SPIMOD_DUAL;
89162306a36Sopenharmony_ci		default:
89262306a36Sopenharmony_ci			return 0;
89362306a36Sopenharmony_ci		}
89462306a36Sopenharmony_ci	if (xfer->rx_buf)
89562306a36Sopenharmony_ci		switch (xfer->rx_nbits) {
89662306a36Sopenharmony_ci		case SPI_NBITS_QUAD:
89762306a36Sopenharmony_ci			return SPCMD_SPIMOD_QUAD | SPCMD_SPRW;
89862306a36Sopenharmony_ci		case SPI_NBITS_DUAL:
89962306a36Sopenharmony_ci			return SPCMD_SPIMOD_DUAL | SPCMD_SPRW;
90062306a36Sopenharmony_ci		default:
90162306a36Sopenharmony_ci			return 0;
90262306a36Sopenharmony_ci		}
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	return 0;
90562306a36Sopenharmony_ci}
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_cistatic int qspi_setup_sequencer(struct rspi_data *rspi,
90862306a36Sopenharmony_ci				const struct spi_message *msg)
90962306a36Sopenharmony_ci{
91062306a36Sopenharmony_ci	const struct spi_transfer *xfer;
91162306a36Sopenharmony_ci	unsigned int i = 0, len = 0;
91262306a36Sopenharmony_ci	u16 current_mode = 0xffff, mode;
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
91562306a36Sopenharmony_ci		mode = qspi_transfer_mode(xfer);
91662306a36Sopenharmony_ci		if (mode == current_mode) {
91762306a36Sopenharmony_ci			len += xfer->len;
91862306a36Sopenharmony_ci			continue;
91962306a36Sopenharmony_ci		}
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci		/* Transfer mode change */
92262306a36Sopenharmony_ci		if (i) {
92362306a36Sopenharmony_ci			/* Set transfer data length of previous transfer */
92462306a36Sopenharmony_ci			rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
92562306a36Sopenharmony_ci		}
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci		if (i >= QSPI_NUM_SPCMD) {
92862306a36Sopenharmony_ci			dev_err(&msg->spi->dev,
92962306a36Sopenharmony_ci				"Too many different transfer modes");
93062306a36Sopenharmony_ci			return -EINVAL;
93162306a36Sopenharmony_ci		}
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci		/* Program transfer mode for this transfer */
93462306a36Sopenharmony_ci		rspi_write16(rspi, rspi->spcmd | mode, RSPI_SPCMD(i));
93562306a36Sopenharmony_ci		current_mode = mode;
93662306a36Sopenharmony_ci		len = xfer->len;
93762306a36Sopenharmony_ci		i++;
93862306a36Sopenharmony_ci	}
93962306a36Sopenharmony_ci	if (i) {
94062306a36Sopenharmony_ci		/* Set final transfer data length and sequence length */
94162306a36Sopenharmony_ci		rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
94262306a36Sopenharmony_ci		rspi_write8(rspi, i - 1, RSPI_SPSCR);
94362306a36Sopenharmony_ci	}
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci	return 0;
94662306a36Sopenharmony_ci}
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_cistatic int rspi_setup(struct spi_device *spi)
94962306a36Sopenharmony_ci{
95062306a36Sopenharmony_ci	struct rspi_data *rspi = spi_controller_get_devdata(spi->controller);
95162306a36Sopenharmony_ci	u8 sslp;
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci	if (spi_get_csgpiod(spi, 0))
95462306a36Sopenharmony_ci		return 0;
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	pm_runtime_get_sync(&rspi->pdev->dev);
95762306a36Sopenharmony_ci	spin_lock_irq(&rspi->lock);
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci	sslp = rspi_read8(rspi, RSPI_SSLP);
96062306a36Sopenharmony_ci	if (spi->mode & SPI_CS_HIGH)
96162306a36Sopenharmony_ci		sslp |= SSLP_SSLP(spi_get_chipselect(spi, 0));
96262306a36Sopenharmony_ci	else
96362306a36Sopenharmony_ci		sslp &= ~SSLP_SSLP(spi_get_chipselect(spi, 0));
96462306a36Sopenharmony_ci	rspi_write8(rspi, sslp, RSPI_SSLP);
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci	spin_unlock_irq(&rspi->lock);
96762306a36Sopenharmony_ci	pm_runtime_put(&rspi->pdev->dev);
96862306a36Sopenharmony_ci	return 0;
96962306a36Sopenharmony_ci}
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_cistatic int rspi_prepare_message(struct spi_controller *ctlr,
97262306a36Sopenharmony_ci				struct spi_message *msg)
97362306a36Sopenharmony_ci{
97462306a36Sopenharmony_ci	struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
97562306a36Sopenharmony_ci	struct spi_device *spi = msg->spi;
97662306a36Sopenharmony_ci	const struct spi_transfer *xfer;
97762306a36Sopenharmony_ci	int ret;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	/*
98062306a36Sopenharmony_ci	 * As the Bit Rate Register must not be changed while the device is
98162306a36Sopenharmony_ci	 * active, all transfers in a message must use the same bit rate.
98262306a36Sopenharmony_ci	 * In theory, the sequencer could be enabled, and each Command Register
98362306a36Sopenharmony_ci	 * could divide the base bit rate by a different value.
98462306a36Sopenharmony_ci	 * However, most RSPI variants do not have Transfer Data Length
98562306a36Sopenharmony_ci	 * Multiplier Setting Registers, so each sequence step would be limited
98662306a36Sopenharmony_ci	 * to a single word, making this feature unsuitable for large
98762306a36Sopenharmony_ci	 * transfers, which would gain most from it.
98862306a36Sopenharmony_ci	 */
98962306a36Sopenharmony_ci	rspi->speed_hz = spi->max_speed_hz;
99062306a36Sopenharmony_ci	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
99162306a36Sopenharmony_ci		if (xfer->speed_hz < rspi->speed_hz)
99262306a36Sopenharmony_ci			rspi->speed_hz = xfer->speed_hz;
99362306a36Sopenharmony_ci	}
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci	rspi->spcmd = SPCMD_SSLKP;
99662306a36Sopenharmony_ci	if (spi->mode & SPI_CPOL)
99762306a36Sopenharmony_ci		rspi->spcmd |= SPCMD_CPOL;
99862306a36Sopenharmony_ci	if (spi->mode & SPI_CPHA)
99962306a36Sopenharmony_ci		rspi->spcmd |= SPCMD_CPHA;
100062306a36Sopenharmony_ci	if (spi->mode & SPI_LSB_FIRST)
100162306a36Sopenharmony_ci		rspi->spcmd |= SPCMD_LSBF;
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	/* Configure slave signal to assert */
100462306a36Sopenharmony_ci	rspi->spcmd |= SPCMD_SSLA(spi_get_csgpiod(spi, 0) ? rspi->ctlr->unused_native_cs
100562306a36Sopenharmony_ci						: spi_get_chipselect(spi, 0));
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci	/* CMOS output mode and MOSI signal from previous transfer */
100862306a36Sopenharmony_ci	rspi->sppcr = 0;
100962306a36Sopenharmony_ci	if (spi->mode & SPI_LOOP)
101062306a36Sopenharmony_ci		rspi->sppcr |= SPPCR_SPLP;
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	rspi->ops->set_config_register(rspi, 8);
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_ci	if (msg->spi->mode &
101562306a36Sopenharmony_ci	    (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)) {
101662306a36Sopenharmony_ci		/* Setup sequencer for messages with multiple transfer modes */
101762306a36Sopenharmony_ci		ret = qspi_setup_sequencer(rspi, msg);
101862306a36Sopenharmony_ci		if (ret < 0)
101962306a36Sopenharmony_ci			return ret;
102062306a36Sopenharmony_ci	}
102162306a36Sopenharmony_ci
102262306a36Sopenharmony_ci	/* Enable SPI function in master mode */
102362306a36Sopenharmony_ci	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
102462306a36Sopenharmony_ci	return 0;
102562306a36Sopenharmony_ci}
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_cistatic int rspi_unprepare_message(struct spi_controller *ctlr,
102862306a36Sopenharmony_ci				  struct spi_message *msg)
102962306a36Sopenharmony_ci{
103062306a36Sopenharmony_ci	struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	/* Disable SPI function */
103362306a36Sopenharmony_ci	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ci	/* Reset sequencer for Single SPI Transfers */
103662306a36Sopenharmony_ci	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
103762306a36Sopenharmony_ci	rspi_write8(rspi, 0, RSPI_SPSCR);
103862306a36Sopenharmony_ci	return 0;
103962306a36Sopenharmony_ci}
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_cistatic irqreturn_t rspi_irq_mux(int irq, void *_sr)
104262306a36Sopenharmony_ci{
104362306a36Sopenharmony_ci	struct rspi_data *rspi = _sr;
104462306a36Sopenharmony_ci	u8 spsr;
104562306a36Sopenharmony_ci	irqreturn_t ret = IRQ_NONE;
104662306a36Sopenharmony_ci	u8 disable_irq = 0;
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
104962306a36Sopenharmony_ci	if (spsr & SPSR_SPRF)
105062306a36Sopenharmony_ci		disable_irq |= SPCR_SPRIE;
105162306a36Sopenharmony_ci	if (spsr & SPSR_SPTEF)
105262306a36Sopenharmony_ci		disable_irq |= SPCR_SPTIE;
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	if (disable_irq) {
105562306a36Sopenharmony_ci		ret = IRQ_HANDLED;
105662306a36Sopenharmony_ci		rspi_disable_irq(rspi, disable_irq);
105762306a36Sopenharmony_ci		wake_up(&rspi->wait);
105862306a36Sopenharmony_ci	}
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ci	return ret;
106162306a36Sopenharmony_ci}
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_cistatic irqreturn_t rspi_irq_rx(int irq, void *_sr)
106462306a36Sopenharmony_ci{
106562306a36Sopenharmony_ci	struct rspi_data *rspi = _sr;
106662306a36Sopenharmony_ci	u8 spsr;
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
106962306a36Sopenharmony_ci	if (spsr & SPSR_SPRF) {
107062306a36Sopenharmony_ci		rspi_disable_irq(rspi, SPCR_SPRIE);
107162306a36Sopenharmony_ci		wake_up(&rspi->wait);
107262306a36Sopenharmony_ci		return IRQ_HANDLED;
107362306a36Sopenharmony_ci	}
107462306a36Sopenharmony_ci
107562306a36Sopenharmony_ci	return 0;
107662306a36Sopenharmony_ci}
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_cistatic irqreturn_t rspi_irq_tx(int irq, void *_sr)
107962306a36Sopenharmony_ci{
108062306a36Sopenharmony_ci	struct rspi_data *rspi = _sr;
108162306a36Sopenharmony_ci	u8 spsr;
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
108462306a36Sopenharmony_ci	if (spsr & SPSR_SPTEF) {
108562306a36Sopenharmony_ci		rspi_disable_irq(rspi, SPCR_SPTIE);
108662306a36Sopenharmony_ci		wake_up(&rspi->wait);
108762306a36Sopenharmony_ci		return IRQ_HANDLED;
108862306a36Sopenharmony_ci	}
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	return 0;
109162306a36Sopenharmony_ci}
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_cistatic struct dma_chan *rspi_request_dma_chan(struct device *dev,
109462306a36Sopenharmony_ci					      enum dma_transfer_direction dir,
109562306a36Sopenharmony_ci					      unsigned int id,
109662306a36Sopenharmony_ci					      dma_addr_t port_addr)
109762306a36Sopenharmony_ci{
109862306a36Sopenharmony_ci	dma_cap_mask_t mask;
109962306a36Sopenharmony_ci	struct dma_chan *chan;
110062306a36Sopenharmony_ci	struct dma_slave_config cfg;
110162306a36Sopenharmony_ci	int ret;
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci	dma_cap_zero(mask);
110462306a36Sopenharmony_ci	dma_cap_set(DMA_SLAVE, mask);
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci	chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
110762306a36Sopenharmony_ci				(void *)(unsigned long)id, dev,
110862306a36Sopenharmony_ci				dir == DMA_MEM_TO_DEV ? "tx" : "rx");
110962306a36Sopenharmony_ci	if (!chan) {
111062306a36Sopenharmony_ci		dev_warn(dev, "dma_request_slave_channel_compat failed\n");
111162306a36Sopenharmony_ci		return NULL;
111262306a36Sopenharmony_ci	}
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci	memset(&cfg, 0, sizeof(cfg));
111562306a36Sopenharmony_ci	cfg.dst_addr = port_addr + RSPI_SPDR;
111662306a36Sopenharmony_ci	cfg.src_addr = port_addr + RSPI_SPDR;
111762306a36Sopenharmony_ci	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
111862306a36Sopenharmony_ci	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
111962306a36Sopenharmony_ci	cfg.direction = dir;
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci	ret = dmaengine_slave_config(chan, &cfg);
112262306a36Sopenharmony_ci	if (ret) {
112362306a36Sopenharmony_ci		dev_warn(dev, "dmaengine_slave_config failed %d\n", ret);
112462306a36Sopenharmony_ci		dma_release_channel(chan);
112562306a36Sopenharmony_ci		return NULL;
112662306a36Sopenharmony_ci	}
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	return chan;
112962306a36Sopenharmony_ci}
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_cistatic int rspi_request_dma(struct device *dev, struct spi_controller *ctlr,
113262306a36Sopenharmony_ci			    const struct resource *res)
113362306a36Sopenharmony_ci{
113462306a36Sopenharmony_ci	const struct rspi_plat_data *rspi_pd = dev_get_platdata(dev);
113562306a36Sopenharmony_ci	unsigned int dma_tx_id, dma_rx_id;
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci	if (dev->of_node) {
113862306a36Sopenharmony_ci		/* In the OF case we will get the slave IDs from the DT */
113962306a36Sopenharmony_ci		dma_tx_id = 0;
114062306a36Sopenharmony_ci		dma_rx_id = 0;
114162306a36Sopenharmony_ci	} else if (rspi_pd && rspi_pd->dma_tx_id && rspi_pd->dma_rx_id) {
114262306a36Sopenharmony_ci		dma_tx_id = rspi_pd->dma_tx_id;
114362306a36Sopenharmony_ci		dma_rx_id = rspi_pd->dma_rx_id;
114462306a36Sopenharmony_ci	} else {
114562306a36Sopenharmony_ci		/* The driver assumes no error. */
114662306a36Sopenharmony_ci		return 0;
114762306a36Sopenharmony_ci	}
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	ctlr->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, dma_tx_id,
115062306a36Sopenharmony_ci					     res->start);
115162306a36Sopenharmony_ci	if (!ctlr->dma_tx)
115262306a36Sopenharmony_ci		return -ENODEV;
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	ctlr->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, dma_rx_id,
115562306a36Sopenharmony_ci					     res->start);
115662306a36Sopenharmony_ci	if (!ctlr->dma_rx) {
115762306a36Sopenharmony_ci		dma_release_channel(ctlr->dma_tx);
115862306a36Sopenharmony_ci		ctlr->dma_tx = NULL;
115962306a36Sopenharmony_ci		return -ENODEV;
116062306a36Sopenharmony_ci	}
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	ctlr->can_dma = rspi_can_dma;
116362306a36Sopenharmony_ci	dev_info(dev, "DMA available");
116462306a36Sopenharmony_ci	return 0;
116562306a36Sopenharmony_ci}
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_cistatic void rspi_release_dma(struct spi_controller *ctlr)
116862306a36Sopenharmony_ci{
116962306a36Sopenharmony_ci	if (ctlr->dma_tx)
117062306a36Sopenharmony_ci		dma_release_channel(ctlr->dma_tx);
117162306a36Sopenharmony_ci	if (ctlr->dma_rx)
117262306a36Sopenharmony_ci		dma_release_channel(ctlr->dma_rx);
117362306a36Sopenharmony_ci}
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_cistatic void rspi_remove(struct platform_device *pdev)
117662306a36Sopenharmony_ci{
117762306a36Sopenharmony_ci	struct rspi_data *rspi = platform_get_drvdata(pdev);
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ci	rspi_release_dma(rspi->ctlr);
118062306a36Sopenharmony_ci	pm_runtime_disable(&pdev->dev);
118162306a36Sopenharmony_ci}
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_cistatic const struct spi_ops rspi_ops = {
118462306a36Sopenharmony_ci	.set_config_register =	rspi_set_config_register,
118562306a36Sopenharmony_ci	.transfer_one =		rspi_transfer_one,
118662306a36Sopenharmony_ci	.min_div =		2,
118762306a36Sopenharmony_ci	.max_div =		4096,
118862306a36Sopenharmony_ci	.flags =		SPI_CONTROLLER_MUST_TX,
118962306a36Sopenharmony_ci	.fifo_size =		8,
119062306a36Sopenharmony_ci	.num_hw_ss =		2,
119162306a36Sopenharmony_ci};
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_cistatic const struct spi_ops rspi_rz_ops __maybe_unused = {
119462306a36Sopenharmony_ci	.set_config_register =	rspi_rz_set_config_register,
119562306a36Sopenharmony_ci	.transfer_one =		rspi_rz_transfer_one,
119662306a36Sopenharmony_ci	.min_div =		2,
119762306a36Sopenharmony_ci	.max_div =		4096,
119862306a36Sopenharmony_ci	.flags =		SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX,
119962306a36Sopenharmony_ci	.fifo_size =		8,	/* 8 for TX, 32 for RX */
120062306a36Sopenharmony_ci	.num_hw_ss =		1,
120162306a36Sopenharmony_ci};
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_cistatic const struct spi_ops qspi_ops __maybe_unused = {
120462306a36Sopenharmony_ci	.set_config_register =	qspi_set_config_register,
120562306a36Sopenharmony_ci	.transfer_one =		qspi_transfer_one,
120662306a36Sopenharmony_ci	.extra_mode_bits =	SPI_TX_DUAL | SPI_TX_QUAD |
120762306a36Sopenharmony_ci				SPI_RX_DUAL | SPI_RX_QUAD,
120862306a36Sopenharmony_ci	.min_div =		1,
120962306a36Sopenharmony_ci	.max_div =		4080,
121062306a36Sopenharmony_ci	.flags =		SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX,
121162306a36Sopenharmony_ci	.fifo_size =		32,
121262306a36Sopenharmony_ci	.num_hw_ss =		1,
121362306a36Sopenharmony_ci};
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_cistatic const struct of_device_id rspi_of_match[] __maybe_unused = {
121662306a36Sopenharmony_ci	/* RSPI on legacy SH */
121762306a36Sopenharmony_ci	{ .compatible = "renesas,rspi", .data = &rspi_ops },
121862306a36Sopenharmony_ci	/* RSPI on RZ/A1H */
121962306a36Sopenharmony_ci	{ .compatible = "renesas,rspi-rz", .data = &rspi_rz_ops },
122062306a36Sopenharmony_ci	/* QSPI on R-Car Gen2 */
122162306a36Sopenharmony_ci	{ .compatible = "renesas,qspi", .data = &qspi_ops },
122262306a36Sopenharmony_ci	{ /* sentinel */ }
122362306a36Sopenharmony_ci};
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, rspi_of_match);
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ci#ifdef CONFIG_OF
122862306a36Sopenharmony_cistatic void rspi_reset_control_assert(void *data)
122962306a36Sopenharmony_ci{
123062306a36Sopenharmony_ci	reset_control_assert(data);
123162306a36Sopenharmony_ci}
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_cistatic int rspi_parse_dt(struct device *dev, struct spi_controller *ctlr)
123462306a36Sopenharmony_ci{
123562306a36Sopenharmony_ci	struct reset_control *rstc;
123662306a36Sopenharmony_ci	u32 num_cs;
123762306a36Sopenharmony_ci	int error;
123862306a36Sopenharmony_ci
123962306a36Sopenharmony_ci	/* Parse DT properties */
124062306a36Sopenharmony_ci	error = of_property_read_u32(dev->of_node, "num-cs", &num_cs);
124162306a36Sopenharmony_ci	if (error) {
124262306a36Sopenharmony_ci		dev_err(dev, "of_property_read_u32 num-cs failed %d\n", error);
124362306a36Sopenharmony_ci		return error;
124462306a36Sopenharmony_ci	}
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci	ctlr->num_chipselect = num_cs;
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci	rstc = devm_reset_control_get_optional_exclusive(dev, NULL);
124962306a36Sopenharmony_ci	if (IS_ERR(rstc))
125062306a36Sopenharmony_ci		return dev_err_probe(dev, PTR_ERR(rstc),
125162306a36Sopenharmony_ci					     "failed to get reset ctrl\n");
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_ci	error = reset_control_deassert(rstc);
125462306a36Sopenharmony_ci	if (error) {
125562306a36Sopenharmony_ci		dev_err(dev, "failed to deassert reset %d\n", error);
125662306a36Sopenharmony_ci		return error;
125762306a36Sopenharmony_ci	}
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	error = devm_add_action_or_reset(dev, rspi_reset_control_assert, rstc);
126062306a36Sopenharmony_ci	if (error) {
126162306a36Sopenharmony_ci		dev_err(dev, "failed to register assert devm action, %d\n", error);
126262306a36Sopenharmony_ci		return error;
126362306a36Sopenharmony_ci	}
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	return 0;
126662306a36Sopenharmony_ci}
126762306a36Sopenharmony_ci#else
126862306a36Sopenharmony_ci#define rspi_of_match	NULL
126962306a36Sopenharmony_cistatic inline int rspi_parse_dt(struct device *dev, struct spi_controller *ctlr)
127062306a36Sopenharmony_ci{
127162306a36Sopenharmony_ci	return -EINVAL;
127262306a36Sopenharmony_ci}
127362306a36Sopenharmony_ci#endif /* CONFIG_OF */
127462306a36Sopenharmony_ci
127562306a36Sopenharmony_cistatic int rspi_request_irq(struct device *dev, unsigned int irq,
127662306a36Sopenharmony_ci			    irq_handler_t handler, const char *suffix,
127762306a36Sopenharmony_ci			    void *dev_id)
127862306a36Sopenharmony_ci{
127962306a36Sopenharmony_ci	const char *name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s",
128062306a36Sopenharmony_ci					  dev_name(dev), suffix);
128162306a36Sopenharmony_ci	if (!name)
128262306a36Sopenharmony_ci		return -ENOMEM;
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	return devm_request_irq(dev, irq, handler, 0, name, dev_id);
128562306a36Sopenharmony_ci}
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_cistatic int rspi_probe(struct platform_device *pdev)
128862306a36Sopenharmony_ci{
128962306a36Sopenharmony_ci	struct resource *res;
129062306a36Sopenharmony_ci	struct spi_controller *ctlr;
129162306a36Sopenharmony_ci	struct rspi_data *rspi;
129262306a36Sopenharmony_ci	int ret;
129362306a36Sopenharmony_ci	const struct rspi_plat_data *rspi_pd;
129462306a36Sopenharmony_ci	const struct spi_ops *ops;
129562306a36Sopenharmony_ci	unsigned long clksrc;
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_ci	ctlr = spi_alloc_host(&pdev->dev, sizeof(struct rspi_data));
129862306a36Sopenharmony_ci	if (ctlr == NULL)
129962306a36Sopenharmony_ci		return -ENOMEM;
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci	ops = of_device_get_match_data(&pdev->dev);
130262306a36Sopenharmony_ci	if (ops) {
130362306a36Sopenharmony_ci		ret = rspi_parse_dt(&pdev->dev, ctlr);
130462306a36Sopenharmony_ci		if (ret)
130562306a36Sopenharmony_ci			goto error1;
130662306a36Sopenharmony_ci	} else {
130762306a36Sopenharmony_ci		ops = (struct spi_ops *)pdev->id_entry->driver_data;
130862306a36Sopenharmony_ci		rspi_pd = dev_get_platdata(&pdev->dev);
130962306a36Sopenharmony_ci		if (rspi_pd && rspi_pd->num_chipselect)
131062306a36Sopenharmony_ci			ctlr->num_chipselect = rspi_pd->num_chipselect;
131162306a36Sopenharmony_ci		else
131262306a36Sopenharmony_ci			ctlr->num_chipselect = 2; /* default */
131362306a36Sopenharmony_ci	}
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci	rspi = spi_controller_get_devdata(ctlr);
131662306a36Sopenharmony_ci	platform_set_drvdata(pdev, rspi);
131762306a36Sopenharmony_ci	rspi->ops = ops;
131862306a36Sopenharmony_ci	rspi->ctlr = ctlr;
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_ci	rspi->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
132162306a36Sopenharmony_ci	if (IS_ERR(rspi->addr)) {
132262306a36Sopenharmony_ci		ret = PTR_ERR(rspi->addr);
132362306a36Sopenharmony_ci		goto error1;
132462306a36Sopenharmony_ci	}
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci	rspi->clk = devm_clk_get(&pdev->dev, NULL);
132762306a36Sopenharmony_ci	if (IS_ERR(rspi->clk)) {
132862306a36Sopenharmony_ci		dev_err(&pdev->dev, "cannot get clock\n");
132962306a36Sopenharmony_ci		ret = PTR_ERR(rspi->clk);
133062306a36Sopenharmony_ci		goto error1;
133162306a36Sopenharmony_ci	}
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	rspi->pdev = pdev;
133462306a36Sopenharmony_ci	pm_runtime_enable(&pdev->dev);
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci	init_waitqueue_head(&rspi->wait);
133762306a36Sopenharmony_ci	spin_lock_init(&rspi->lock);
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	ctlr->bus_num = pdev->id;
134062306a36Sopenharmony_ci	ctlr->setup = rspi_setup;
134162306a36Sopenharmony_ci	ctlr->auto_runtime_pm = true;
134262306a36Sopenharmony_ci	ctlr->transfer_one = ops->transfer_one;
134362306a36Sopenharmony_ci	ctlr->prepare_message = rspi_prepare_message;
134462306a36Sopenharmony_ci	ctlr->unprepare_message = rspi_unprepare_message;
134562306a36Sopenharmony_ci	ctlr->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST |
134662306a36Sopenharmony_ci			  SPI_LOOP | ops->extra_mode_bits;
134762306a36Sopenharmony_ci	clksrc = clk_get_rate(rspi->clk);
134862306a36Sopenharmony_ci	ctlr->min_speed_hz = DIV_ROUND_UP(clksrc, ops->max_div);
134962306a36Sopenharmony_ci	ctlr->max_speed_hz = DIV_ROUND_UP(clksrc, ops->min_div);
135062306a36Sopenharmony_ci	ctlr->flags = ops->flags;
135162306a36Sopenharmony_ci	ctlr->dev.of_node = pdev->dev.of_node;
135262306a36Sopenharmony_ci	ctlr->use_gpio_descriptors = true;
135362306a36Sopenharmony_ci	ctlr->max_native_cs = rspi->ops->num_hw_ss;
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci	ret = platform_get_irq_byname_optional(pdev, "rx");
135662306a36Sopenharmony_ci	if (ret < 0) {
135762306a36Sopenharmony_ci		ret = platform_get_irq_byname_optional(pdev, "mux");
135862306a36Sopenharmony_ci		if (ret < 0)
135962306a36Sopenharmony_ci			ret = platform_get_irq(pdev, 0);
136062306a36Sopenharmony_ci		if (ret >= 0)
136162306a36Sopenharmony_ci			rspi->rx_irq = rspi->tx_irq = ret;
136262306a36Sopenharmony_ci	} else {
136362306a36Sopenharmony_ci		rspi->rx_irq = ret;
136462306a36Sopenharmony_ci		ret = platform_get_irq_byname(pdev, "tx");
136562306a36Sopenharmony_ci		if (ret >= 0)
136662306a36Sopenharmony_ci			rspi->tx_irq = ret;
136762306a36Sopenharmony_ci	}
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	if (rspi->rx_irq == rspi->tx_irq) {
137062306a36Sopenharmony_ci		/* Single multiplexed interrupt */
137162306a36Sopenharmony_ci		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux,
137262306a36Sopenharmony_ci				       "mux", rspi);
137362306a36Sopenharmony_ci	} else {
137462306a36Sopenharmony_ci		/* Multi-interrupt mode, only SPRI and SPTI are used */
137562306a36Sopenharmony_ci		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx,
137662306a36Sopenharmony_ci				       "rx", rspi);
137762306a36Sopenharmony_ci		if (!ret)
137862306a36Sopenharmony_ci			ret = rspi_request_irq(&pdev->dev, rspi->tx_irq,
137962306a36Sopenharmony_ci					       rspi_irq_tx, "tx", rspi);
138062306a36Sopenharmony_ci	}
138162306a36Sopenharmony_ci	if (ret < 0) {
138262306a36Sopenharmony_ci		dev_err(&pdev->dev, "request_irq error\n");
138362306a36Sopenharmony_ci		goto error2;
138462306a36Sopenharmony_ci	}
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	ret = rspi_request_dma(&pdev->dev, ctlr, res);
138762306a36Sopenharmony_ci	if (ret < 0)
138862306a36Sopenharmony_ci		dev_warn(&pdev->dev, "DMA not available, using PIO\n");
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	ret = devm_spi_register_controller(&pdev->dev, ctlr);
139162306a36Sopenharmony_ci	if (ret < 0) {
139262306a36Sopenharmony_ci		dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
139362306a36Sopenharmony_ci		goto error3;
139462306a36Sopenharmony_ci	}
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci	dev_info(&pdev->dev, "probed\n");
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	return 0;
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_cierror3:
140162306a36Sopenharmony_ci	rspi_release_dma(ctlr);
140262306a36Sopenharmony_cierror2:
140362306a36Sopenharmony_ci	pm_runtime_disable(&pdev->dev);
140462306a36Sopenharmony_cierror1:
140562306a36Sopenharmony_ci	spi_controller_put(ctlr);
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci	return ret;
140862306a36Sopenharmony_ci}
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_cistatic const struct platform_device_id spi_driver_ids[] = {
141162306a36Sopenharmony_ci	{ "rspi",	(kernel_ulong_t)&rspi_ops },
141262306a36Sopenharmony_ci	{},
141362306a36Sopenharmony_ci};
141462306a36Sopenharmony_ci
141562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(platform, spi_driver_ids);
141662306a36Sopenharmony_ci
141762306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP
141862306a36Sopenharmony_cistatic int rspi_suspend(struct device *dev)
141962306a36Sopenharmony_ci{
142062306a36Sopenharmony_ci	struct rspi_data *rspi = dev_get_drvdata(dev);
142162306a36Sopenharmony_ci
142262306a36Sopenharmony_ci	return spi_controller_suspend(rspi->ctlr);
142362306a36Sopenharmony_ci}
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_cistatic int rspi_resume(struct device *dev)
142662306a36Sopenharmony_ci{
142762306a36Sopenharmony_ci	struct rspi_data *rspi = dev_get_drvdata(dev);
142862306a36Sopenharmony_ci
142962306a36Sopenharmony_ci	return spi_controller_resume(rspi->ctlr);
143062306a36Sopenharmony_ci}
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(rspi_pm_ops, rspi_suspend, rspi_resume);
143362306a36Sopenharmony_ci#define DEV_PM_OPS	&rspi_pm_ops
143462306a36Sopenharmony_ci#else
143562306a36Sopenharmony_ci#define DEV_PM_OPS	NULL
143662306a36Sopenharmony_ci#endif /* CONFIG_PM_SLEEP */
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_cistatic struct platform_driver rspi_driver = {
143962306a36Sopenharmony_ci	.probe =	rspi_probe,
144062306a36Sopenharmony_ci	.remove_new =	rspi_remove,
144162306a36Sopenharmony_ci	.id_table =	spi_driver_ids,
144262306a36Sopenharmony_ci	.driver		= {
144362306a36Sopenharmony_ci		.name = "renesas_spi",
144462306a36Sopenharmony_ci		.pm = DEV_PM_OPS,
144562306a36Sopenharmony_ci		.of_match_table = of_match_ptr(rspi_of_match),
144662306a36Sopenharmony_ci	},
144762306a36Sopenharmony_ci};
144862306a36Sopenharmony_cimodule_platform_driver(rspi_driver);
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ciMODULE_DESCRIPTION("Renesas RSPI bus driver");
145162306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
145262306a36Sopenharmony_ciMODULE_AUTHOR("Yoshihiro Shimoda");
1453