xref: /openbmc/u-boot/drivers/spi/sh_qspi.c (revision d94604d5)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0
216f47c9cSNobuhiro Iwamatsu /*
316f47c9cSNobuhiro Iwamatsu  * SH QSPI (Quad SPI) driver
416f47c9cSNobuhiro Iwamatsu  *
516f47c9cSNobuhiro Iwamatsu  * Copyright (C) 2013 Renesas Electronics Corporation
616f47c9cSNobuhiro Iwamatsu  * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
716f47c9cSNobuhiro Iwamatsu  */
816f47c9cSNobuhiro Iwamatsu 
916f47c9cSNobuhiro Iwamatsu #include <common.h>
1024b852a7SSimon Glass #include <console.h>
1116f47c9cSNobuhiro Iwamatsu #include <malloc.h>
1216f47c9cSNobuhiro Iwamatsu #include <spi.h>
139573db65SMarek Vasut #include <wait_bit.h>
1422e75d6dSNobuhiro Iwamatsu #include <asm/arch/rmobile.h>
1516f47c9cSNobuhiro Iwamatsu #include <asm/io.h>
1616f47c9cSNobuhiro Iwamatsu 
1716f47c9cSNobuhiro Iwamatsu /* SH QSPI register bit masks <REG>_<BIT> */
1816f47c9cSNobuhiro Iwamatsu #define SPCR_MSTR	0x08
1916f47c9cSNobuhiro Iwamatsu #define SPCR_SPE	0x40
2016f47c9cSNobuhiro Iwamatsu #define SPSR_SPRFF	0x80
2116f47c9cSNobuhiro Iwamatsu #define SPSR_SPTEF	0x20
2216f47c9cSNobuhiro Iwamatsu #define SPPCR_IO3FV	0x04
2316f47c9cSNobuhiro Iwamatsu #define SPPCR_IO2FV	0x02
2416f47c9cSNobuhiro Iwamatsu #define SPPCR_IO1FV	0x01
25ccaa9485SJagan Teki #define SPBDCR_RXBC0	BIT(0)
26ccaa9485SJagan Teki #define SPCMD_SCKDEN	BIT(15)
27ccaa9485SJagan Teki #define SPCMD_SLNDEN	BIT(14)
28ccaa9485SJagan Teki #define SPCMD_SPNDEN	BIT(13)
29ccaa9485SJagan Teki #define SPCMD_SSLKP	BIT(7)
30ccaa9485SJagan Teki #define SPCMD_BRDV0	BIT(2)
3116f47c9cSNobuhiro Iwamatsu #define SPCMD_INIT1	SPCMD_SCKDEN | SPCMD_SLNDEN | \
3216f47c9cSNobuhiro Iwamatsu 			SPCMD_SPNDEN | SPCMD_SSLKP | \
3316f47c9cSNobuhiro Iwamatsu 			SPCMD_BRDV0
3416f47c9cSNobuhiro Iwamatsu #define SPCMD_INIT2	SPCMD_SPNDEN | SPCMD_SSLKP | \
3516f47c9cSNobuhiro Iwamatsu 			SPCMD_BRDV0
36ccaa9485SJagan Teki #define SPBFCR_TXRST	BIT(7)
37ccaa9485SJagan Teki #define SPBFCR_RXRST	BIT(6)
38ea5512ebSMarek Vasut #define SPBFCR_TXTRG	0x30
39ea5512ebSMarek Vasut #define SPBFCR_RXTRG	0x07
4016f47c9cSNobuhiro Iwamatsu 
4116f47c9cSNobuhiro Iwamatsu /* SH QSPI register set */
4216f47c9cSNobuhiro Iwamatsu struct sh_qspi_regs {
430e6fa20bSMarek Vasut 	u8	spcr;
440e6fa20bSMarek Vasut 	u8	sslp;
450e6fa20bSMarek Vasut 	u8	sppcr;
460e6fa20bSMarek Vasut 	u8	spsr;
470e6fa20bSMarek Vasut 	u32	spdr;
480e6fa20bSMarek Vasut 	u8	spscr;
490e6fa20bSMarek Vasut 	u8	spssr;
500e6fa20bSMarek Vasut 	u8	spbr;
510e6fa20bSMarek Vasut 	u8	spdcr;
520e6fa20bSMarek Vasut 	u8	spckd;
530e6fa20bSMarek Vasut 	u8	sslnd;
540e6fa20bSMarek Vasut 	u8	spnd;
550e6fa20bSMarek Vasut 	u8	dummy0;
560e6fa20bSMarek Vasut 	u16	spcmd0;
570e6fa20bSMarek Vasut 	u16	spcmd1;
580e6fa20bSMarek Vasut 	u16	spcmd2;
590e6fa20bSMarek Vasut 	u16	spcmd3;
600e6fa20bSMarek Vasut 	u8	spbfcr;
610e6fa20bSMarek Vasut 	u8	dummy1;
620e6fa20bSMarek Vasut 	u16	spbdcr;
630e6fa20bSMarek Vasut 	u32	spbmul0;
640e6fa20bSMarek Vasut 	u32	spbmul1;
650e6fa20bSMarek Vasut 	u32	spbmul2;
660e6fa20bSMarek Vasut 	u32	spbmul3;
6716f47c9cSNobuhiro Iwamatsu };
6816f47c9cSNobuhiro Iwamatsu 
6916f47c9cSNobuhiro Iwamatsu struct sh_qspi_slave {
70*b3bec252SMarek Vasut #ifndef CONFIG_DM_SPI
7116f47c9cSNobuhiro Iwamatsu 	struct spi_slave	slave;
72*b3bec252SMarek Vasut #endif
7316f47c9cSNobuhiro Iwamatsu 	struct sh_qspi_regs	*regs;
7416f47c9cSNobuhiro Iwamatsu };
7516f47c9cSNobuhiro Iwamatsu 
sh_qspi_init(struct sh_qspi_slave * ss)7616f47c9cSNobuhiro Iwamatsu static void sh_qspi_init(struct sh_qspi_slave *ss)
7716f47c9cSNobuhiro Iwamatsu {
7816f47c9cSNobuhiro Iwamatsu 	/* QSPI initialize */
7916f47c9cSNobuhiro Iwamatsu 	/* Set master mode only */
8016f47c9cSNobuhiro Iwamatsu 	writeb(SPCR_MSTR, &ss->regs->spcr);
8116f47c9cSNobuhiro Iwamatsu 
8216f47c9cSNobuhiro Iwamatsu 	/* Set SSL signal level */
8316f47c9cSNobuhiro Iwamatsu 	writeb(0x00, &ss->regs->sslp);
8416f47c9cSNobuhiro Iwamatsu 
8516f47c9cSNobuhiro Iwamatsu 	/* Set MOSI signal value when transfer is in idle state */
8616f47c9cSNobuhiro Iwamatsu 	writeb(SPPCR_IO3FV|SPPCR_IO2FV, &ss->regs->sppcr);
8716f47c9cSNobuhiro Iwamatsu 
8816f47c9cSNobuhiro Iwamatsu 	/* Set bit rate. See 58.3.8 Quad Serial Peripheral Interface */
8916f47c9cSNobuhiro Iwamatsu 	writeb(0x01, &ss->regs->spbr);
9016f47c9cSNobuhiro Iwamatsu 
9116f47c9cSNobuhiro Iwamatsu 	/* Disable Dummy Data Transmission */
9216f47c9cSNobuhiro Iwamatsu 	writeb(0x00, &ss->regs->spdcr);
9316f47c9cSNobuhiro Iwamatsu 
9416f47c9cSNobuhiro Iwamatsu 	/* Set clock delay value */
9516f47c9cSNobuhiro Iwamatsu 	writeb(0x00, &ss->regs->spckd);
9616f47c9cSNobuhiro Iwamatsu 
9716f47c9cSNobuhiro Iwamatsu 	/* Set SSL negation delay value */
9816f47c9cSNobuhiro Iwamatsu 	writeb(0x00, &ss->regs->sslnd);
9916f47c9cSNobuhiro Iwamatsu 
10016f47c9cSNobuhiro Iwamatsu 	/* Set next-access delay value */
10116f47c9cSNobuhiro Iwamatsu 	writeb(0x00, &ss->regs->spnd);
10216f47c9cSNobuhiro Iwamatsu 
10316f47c9cSNobuhiro Iwamatsu 	/* Set equence command */
10416f47c9cSNobuhiro Iwamatsu 	writew(SPCMD_INIT2, &ss->regs->spcmd0);
10516f47c9cSNobuhiro Iwamatsu 
10616f47c9cSNobuhiro Iwamatsu 	/* Reset transfer and receive Buffer */
10716f47c9cSNobuhiro Iwamatsu 	setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
10816f47c9cSNobuhiro Iwamatsu 
10916f47c9cSNobuhiro Iwamatsu 	/* Clear transfer and receive Buffer control bit */
11016f47c9cSNobuhiro Iwamatsu 	clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
11116f47c9cSNobuhiro Iwamatsu 
11216f47c9cSNobuhiro Iwamatsu 	/* Set equence control method. Use equence0 only */
11316f47c9cSNobuhiro Iwamatsu 	writeb(0x00, &ss->regs->spscr);
11416f47c9cSNobuhiro Iwamatsu 
11516f47c9cSNobuhiro Iwamatsu 	/* Enable SPI function */
11616f47c9cSNobuhiro Iwamatsu 	setbits_8(&ss->regs->spcr, SPCR_SPE);
11716f47c9cSNobuhiro Iwamatsu }
11816f47c9cSNobuhiro Iwamatsu 
sh_qspi_cs_activate(struct sh_qspi_slave * ss)119*b3bec252SMarek Vasut static void sh_qspi_cs_activate(struct sh_qspi_slave *ss)
12016f47c9cSNobuhiro Iwamatsu {
12116f47c9cSNobuhiro Iwamatsu 	/* Set master mode only */
12216f47c9cSNobuhiro Iwamatsu 	writeb(SPCR_MSTR, &ss->regs->spcr);
12316f47c9cSNobuhiro Iwamatsu 
12416f47c9cSNobuhiro Iwamatsu 	/* Set command */
12516f47c9cSNobuhiro Iwamatsu 	writew(SPCMD_INIT1, &ss->regs->spcmd0);
12616f47c9cSNobuhiro Iwamatsu 
12716f47c9cSNobuhiro Iwamatsu 	/* Reset transfer and receive Buffer */
12816f47c9cSNobuhiro Iwamatsu 	setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
12916f47c9cSNobuhiro Iwamatsu 
13016f47c9cSNobuhiro Iwamatsu 	/* Clear transfer and receive Buffer control bit */
13116f47c9cSNobuhiro Iwamatsu 	clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
13216f47c9cSNobuhiro Iwamatsu 
13316f47c9cSNobuhiro Iwamatsu 	/* Set equence control method. Use equence0 only */
13416f47c9cSNobuhiro Iwamatsu 	writeb(0x00, &ss->regs->spscr);
13516f47c9cSNobuhiro Iwamatsu 
13616f47c9cSNobuhiro Iwamatsu 	/* Enable SPI function */
13716f47c9cSNobuhiro Iwamatsu 	setbits_8(&ss->regs->spcr, SPCR_SPE);
13816f47c9cSNobuhiro Iwamatsu }
13916f47c9cSNobuhiro Iwamatsu 
sh_qspi_cs_deactivate(struct sh_qspi_slave * ss)140*b3bec252SMarek Vasut static void sh_qspi_cs_deactivate(struct sh_qspi_slave *ss)
14116f47c9cSNobuhiro Iwamatsu {
14216f47c9cSNobuhiro Iwamatsu 	/* Disable SPI Function */
14316f47c9cSNobuhiro Iwamatsu 	clrbits_8(&ss->regs->spcr, SPCR_SPE);
14416f47c9cSNobuhiro Iwamatsu }
14516f47c9cSNobuhiro Iwamatsu 
sh_qspi_xfer_common(struct sh_qspi_slave * ss,unsigned int bitlen,const void * dout,void * din,unsigned long flags)146*b3bec252SMarek Vasut static int sh_qspi_xfer_common(struct sh_qspi_slave *ss, unsigned int bitlen,
147*b3bec252SMarek Vasut 			       const void *dout, void *din, unsigned long flags)
14816f47c9cSNobuhiro Iwamatsu {
149ea5512ebSMarek Vasut 	u32 nbyte, chunk;
150ea5512ebSMarek Vasut 	int i, ret = 0;
1510e6fa20bSMarek Vasut 	u8 dtdata = 0, drdata;
1520e6fa20bSMarek Vasut 	u8 *tdata = &dtdata, *rdata = &drdata;
1530e6fa20bSMarek Vasut 	u32 *spbmul0 = &ss->regs->spbmul0;
15416f47c9cSNobuhiro Iwamatsu 
15516f47c9cSNobuhiro Iwamatsu 	if (dout == NULL && din == NULL) {
15616f47c9cSNobuhiro Iwamatsu 		if (flags & SPI_XFER_END)
157*b3bec252SMarek Vasut 			sh_qspi_cs_deactivate(ss);
15816f47c9cSNobuhiro Iwamatsu 		return 0;
15916f47c9cSNobuhiro Iwamatsu 	}
16016f47c9cSNobuhiro Iwamatsu 
16116f47c9cSNobuhiro Iwamatsu 	if (bitlen % 8) {
16216f47c9cSNobuhiro Iwamatsu 		printf("%s: bitlen is not 8bit alined %d", __func__, bitlen);
16316f47c9cSNobuhiro Iwamatsu 		return 1;
16416f47c9cSNobuhiro Iwamatsu 	}
16516f47c9cSNobuhiro Iwamatsu 
16616f47c9cSNobuhiro Iwamatsu 	nbyte = bitlen / 8;
16716f47c9cSNobuhiro Iwamatsu 
16816f47c9cSNobuhiro Iwamatsu 	if (flags & SPI_XFER_BEGIN) {
169*b3bec252SMarek Vasut 		sh_qspi_cs_activate(ss);
17016f47c9cSNobuhiro Iwamatsu 
17116f47c9cSNobuhiro Iwamatsu 		/* Set 1048576 byte */
17216f47c9cSNobuhiro Iwamatsu 		writel(0x100000, spbmul0);
17316f47c9cSNobuhiro Iwamatsu 	}
17416f47c9cSNobuhiro Iwamatsu 
17516f47c9cSNobuhiro Iwamatsu 	if (flags & SPI_XFER_END)
17616f47c9cSNobuhiro Iwamatsu 		writel(nbyte, spbmul0);
17716f47c9cSNobuhiro Iwamatsu 
17816f47c9cSNobuhiro Iwamatsu 	if (dout != NULL)
1790e6fa20bSMarek Vasut 		tdata = (u8 *)dout;
18016f47c9cSNobuhiro Iwamatsu 
18116f47c9cSNobuhiro Iwamatsu 	if (din != NULL)
18216f47c9cSNobuhiro Iwamatsu 		rdata = din;
18316f47c9cSNobuhiro Iwamatsu 
18416f47c9cSNobuhiro Iwamatsu 	while (nbyte > 0) {
185ea5512ebSMarek Vasut 		/*
186ea5512ebSMarek Vasut 		 * Check if there is 32 Byte chunk and if there is, transfer
187ea5512ebSMarek Vasut 		 * it in one burst, otherwise transfer on byte-by-byte basis.
188ea5512ebSMarek Vasut 		 */
189ea5512ebSMarek Vasut 		chunk = (nbyte >= 32) ? 32 : 1;
190ea5512ebSMarek Vasut 
191ea5512ebSMarek Vasut 		clrsetbits_8(&ss->regs->spbfcr, SPBFCR_TXTRG | SPBFCR_RXTRG,
192ea5512ebSMarek Vasut 			     chunk == 32 ? SPBFCR_TXTRG | SPBFCR_RXTRG : 0);
193ea5512ebSMarek Vasut 
1949573db65SMarek Vasut 		ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPTEF,
1959573db65SMarek Vasut 				     true, 1000, true);
1969573db65SMarek Vasut 		if (ret)
1979573db65SMarek Vasut 			return ret;
19816f47c9cSNobuhiro Iwamatsu 
199ea5512ebSMarek Vasut 		for (i = 0; i < chunk; i++) {
200ea5512ebSMarek Vasut 			writeb(*tdata, &ss->regs->spdr);
201ea5512ebSMarek Vasut 			if (dout != NULL)
202ea5512ebSMarek Vasut 				tdata++;
203ea5512ebSMarek Vasut 		}
20416f47c9cSNobuhiro Iwamatsu 
2059573db65SMarek Vasut 		ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPRFF,
2069573db65SMarek Vasut 				     true, 1000, true);
2079573db65SMarek Vasut 		if (ret)
2089573db65SMarek Vasut 			return ret;
20916f47c9cSNobuhiro Iwamatsu 
210ea5512ebSMarek Vasut 		for (i = 0; i < chunk; i++) {
211ea5512ebSMarek Vasut 			*rdata = readb(&ss->regs->spdr);
21216f47c9cSNobuhiro Iwamatsu 			if (din != NULL)
21316f47c9cSNobuhiro Iwamatsu 				rdata++;
214ea5512ebSMarek Vasut 		}
21516f47c9cSNobuhiro Iwamatsu 
216ea5512ebSMarek Vasut 		nbyte -= chunk;
21716f47c9cSNobuhiro Iwamatsu 	}
21816f47c9cSNobuhiro Iwamatsu 
21916f47c9cSNobuhiro Iwamatsu 	if (flags & SPI_XFER_END)
220*b3bec252SMarek Vasut 		sh_qspi_cs_deactivate(ss);
22116f47c9cSNobuhiro Iwamatsu 
22216f47c9cSNobuhiro Iwamatsu 	return ret;
22316f47c9cSNobuhiro Iwamatsu }
224*b3bec252SMarek Vasut 
225*b3bec252SMarek Vasut #ifndef CONFIG_DM_SPI
to_sh_qspi(struct spi_slave * slave)226*b3bec252SMarek Vasut static inline struct sh_qspi_slave *to_sh_qspi(struct spi_slave *slave)
227*b3bec252SMarek Vasut {
228*b3bec252SMarek Vasut 	return container_of(slave, struct sh_qspi_slave, slave);
229*b3bec252SMarek Vasut }
230*b3bec252SMarek Vasut 
spi_cs_is_valid(unsigned int bus,unsigned int cs)231*b3bec252SMarek Vasut int spi_cs_is_valid(unsigned int bus, unsigned int cs)
232*b3bec252SMarek Vasut {
233*b3bec252SMarek Vasut 	return 1;
234*b3bec252SMarek Vasut }
235*b3bec252SMarek Vasut 
spi_cs_activate(struct spi_slave * slave)236*b3bec252SMarek Vasut void spi_cs_activate(struct spi_slave *slave)
237*b3bec252SMarek Vasut {
238*b3bec252SMarek Vasut 	struct sh_qspi_slave *ss = to_sh_qspi(slave);
239*b3bec252SMarek Vasut 
240*b3bec252SMarek Vasut 	sh_qspi_cs_activate(ss);
241*b3bec252SMarek Vasut }
242*b3bec252SMarek Vasut 
spi_cs_deactivate(struct spi_slave * slave)243*b3bec252SMarek Vasut void spi_cs_deactivate(struct spi_slave *slave)
244*b3bec252SMarek Vasut {
245*b3bec252SMarek Vasut 	struct sh_qspi_slave *ss = to_sh_qspi(slave);
246*b3bec252SMarek Vasut 
247*b3bec252SMarek Vasut 	sh_qspi_cs_deactivate(ss);
248*b3bec252SMarek Vasut }
249*b3bec252SMarek Vasut 
spi_setup_slave(unsigned int bus,unsigned int cs,unsigned int max_hz,unsigned int mode)250*b3bec252SMarek Vasut struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
251*b3bec252SMarek Vasut 		unsigned int max_hz, unsigned int mode)
252*b3bec252SMarek Vasut {
253*b3bec252SMarek Vasut 	struct sh_qspi_slave *ss;
254*b3bec252SMarek Vasut 
255*b3bec252SMarek Vasut 	if (!spi_cs_is_valid(bus, cs))
256*b3bec252SMarek Vasut 		return NULL;
257*b3bec252SMarek Vasut 
258*b3bec252SMarek Vasut 	ss = spi_alloc_slave(struct sh_qspi_slave, bus, cs);
259*b3bec252SMarek Vasut 	if (!ss) {
260*b3bec252SMarek Vasut 		printf("SPI_error: Fail to allocate sh_qspi_slave\n");
261*b3bec252SMarek Vasut 		return NULL;
262*b3bec252SMarek Vasut 	}
263*b3bec252SMarek Vasut 
264*b3bec252SMarek Vasut 	ss->regs = (struct sh_qspi_regs *)SH_QSPI_BASE;
265*b3bec252SMarek Vasut 
266*b3bec252SMarek Vasut 	/* Init SH QSPI */
267*b3bec252SMarek Vasut 	sh_qspi_init(ss);
268*b3bec252SMarek Vasut 
269*b3bec252SMarek Vasut 	return &ss->slave;
270*b3bec252SMarek Vasut }
271*b3bec252SMarek Vasut 
spi_free_slave(struct spi_slave * slave)272*b3bec252SMarek Vasut void spi_free_slave(struct spi_slave *slave)
273*b3bec252SMarek Vasut {
274*b3bec252SMarek Vasut 	struct sh_qspi_slave *spi = to_sh_qspi(slave);
275*b3bec252SMarek Vasut 
276*b3bec252SMarek Vasut 	free(spi);
277*b3bec252SMarek Vasut }
278*b3bec252SMarek Vasut 
spi_claim_bus(struct spi_slave * slave)279*b3bec252SMarek Vasut int spi_claim_bus(struct spi_slave *slave)
280*b3bec252SMarek Vasut {
281*b3bec252SMarek Vasut 	return 0;
282*b3bec252SMarek Vasut }
283*b3bec252SMarek Vasut 
spi_release_bus(struct spi_slave * slave)284*b3bec252SMarek Vasut void spi_release_bus(struct spi_slave *slave)
285*b3bec252SMarek Vasut {
286*b3bec252SMarek Vasut }
287*b3bec252SMarek Vasut 
spi_xfer(struct spi_slave * slave,unsigned int bitlen,const void * dout,void * din,unsigned long flags)288*b3bec252SMarek Vasut int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
289*b3bec252SMarek Vasut 	     const void *dout, void *din, unsigned long flags)
290*b3bec252SMarek Vasut {
291*b3bec252SMarek Vasut 	struct sh_qspi_slave *ss = to_sh_qspi(slave);
292*b3bec252SMarek Vasut 
293*b3bec252SMarek Vasut 	return sh_qspi_xfer_common(ss, bitlen, dout, din, flags);
294*b3bec252SMarek Vasut }
295*b3bec252SMarek Vasut 
296*b3bec252SMarek Vasut #else
297*b3bec252SMarek Vasut 
298*b3bec252SMarek Vasut #include <dm.h>
299*b3bec252SMarek Vasut 
sh_qspi_xfer(struct udevice * dev,unsigned int bitlen,const void * dout,void * din,unsigned long flags)300*b3bec252SMarek Vasut static int sh_qspi_xfer(struct udevice *dev, unsigned int bitlen,
301*b3bec252SMarek Vasut 			const void *dout, void *din, unsigned long flags)
302*b3bec252SMarek Vasut {
303*b3bec252SMarek Vasut 	struct udevice *bus = dev->parent;
304*b3bec252SMarek Vasut 	struct sh_qspi_slave *ss = dev_get_platdata(bus);
305*b3bec252SMarek Vasut 
306*b3bec252SMarek Vasut 	return sh_qspi_xfer_common(ss, bitlen, dout, din, flags);
307*b3bec252SMarek Vasut }
308*b3bec252SMarek Vasut 
sh_qspi_set_speed(struct udevice * dev,uint speed)309*b3bec252SMarek Vasut static int sh_qspi_set_speed(struct udevice *dev, uint speed)
310*b3bec252SMarek Vasut {
311*b3bec252SMarek Vasut 	/* This is a SPI NOR controller, do nothing. */
312*b3bec252SMarek Vasut 	return 0;
313*b3bec252SMarek Vasut }
314*b3bec252SMarek Vasut 
sh_qspi_set_mode(struct udevice * dev,uint mode)315*b3bec252SMarek Vasut static int sh_qspi_set_mode(struct udevice *dev, uint mode)
316*b3bec252SMarek Vasut {
317*b3bec252SMarek Vasut 	/* This is a SPI NOR controller, do nothing. */
318*b3bec252SMarek Vasut 	return 0;
319*b3bec252SMarek Vasut }
320*b3bec252SMarek Vasut 
sh_qspi_probe(struct udevice * dev)321*b3bec252SMarek Vasut static int sh_qspi_probe(struct udevice *dev)
322*b3bec252SMarek Vasut {
323*b3bec252SMarek Vasut 	struct sh_qspi_slave *ss = dev_get_platdata(dev);
324*b3bec252SMarek Vasut 
325*b3bec252SMarek Vasut 	sh_qspi_init(ss);
326*b3bec252SMarek Vasut 
327*b3bec252SMarek Vasut 	return 0;
328*b3bec252SMarek Vasut }
329*b3bec252SMarek Vasut 
sh_qspi_ofdata_to_platdata(struct udevice * dev)330*b3bec252SMarek Vasut static int sh_qspi_ofdata_to_platdata(struct udevice *dev)
331*b3bec252SMarek Vasut {
332*b3bec252SMarek Vasut 	struct sh_qspi_slave *plat = dev_get_platdata(dev);
333*b3bec252SMarek Vasut 
334*b3bec252SMarek Vasut 	plat->regs = (struct sh_qspi_regs *)dev_read_addr(dev);
335*b3bec252SMarek Vasut 
336*b3bec252SMarek Vasut 	return 0;
337*b3bec252SMarek Vasut }
338*b3bec252SMarek Vasut 
339*b3bec252SMarek Vasut static const struct dm_spi_ops sh_qspi_ops = {
340*b3bec252SMarek Vasut 	.xfer		= sh_qspi_xfer,
341*b3bec252SMarek Vasut 	.set_speed	= sh_qspi_set_speed,
342*b3bec252SMarek Vasut 	.set_mode	= sh_qspi_set_mode,
343*b3bec252SMarek Vasut };
344*b3bec252SMarek Vasut 
345*b3bec252SMarek Vasut static const struct udevice_id sh_qspi_ids[] = {
346*b3bec252SMarek Vasut 	{ .compatible = "renesas,qspi" },
347*b3bec252SMarek Vasut 	{ }
348*b3bec252SMarek Vasut };
349*b3bec252SMarek Vasut 
350*b3bec252SMarek Vasut U_BOOT_DRIVER(sh_qspi) = {
351*b3bec252SMarek Vasut 	.name		= "sh_qspi",
352*b3bec252SMarek Vasut 	.id		= UCLASS_SPI,
353*b3bec252SMarek Vasut 	.of_match	= sh_qspi_ids,
354*b3bec252SMarek Vasut 	.ops		= &sh_qspi_ops,
355*b3bec252SMarek Vasut 	.ofdata_to_platdata = sh_qspi_ofdata_to_platdata,
356*b3bec252SMarek Vasut 	.platdata_auto_alloc_size = sizeof(struct sh_qspi_slave),
357*b3bec252SMarek Vasut 	.probe		= sh_qspi_probe,
358*b3bec252SMarek Vasut };
359*b3bec252SMarek Vasut #endif
360