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