]> git.sur5r.net Git - u-boot/blob - drivers/spi/sh_qspi.c
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[u-boot] / drivers / spi / sh_qspi.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * SH QSPI (Quad SPI) driver
4  *
5  * Copyright (C) 2013 Renesas Electronics Corporation
6  * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
7  */
8
9 #include <common.h>
10 #include <console.h>
11 #include <malloc.h>
12 #include <spi.h>
13 #include <wait_bit.h>
14 #include <asm/arch/rmobile.h>
15 #include <asm/io.h>
16
17 /* SH QSPI register bit masks <REG>_<BIT> */
18 #define SPCR_MSTR       0x08
19 #define SPCR_SPE        0x40
20 #define SPSR_SPRFF      0x80
21 #define SPSR_SPTEF      0x20
22 #define SPPCR_IO3FV     0x04
23 #define SPPCR_IO2FV     0x02
24 #define SPPCR_IO1FV     0x01
25 #define SPBDCR_RXBC0    BIT(0)
26 #define SPCMD_SCKDEN    BIT(15)
27 #define SPCMD_SLNDEN    BIT(14)
28 #define SPCMD_SPNDEN    BIT(13)
29 #define SPCMD_SSLKP     BIT(7)
30 #define SPCMD_BRDV0     BIT(2)
31 #define SPCMD_INIT1     SPCMD_SCKDEN | SPCMD_SLNDEN | \
32                         SPCMD_SPNDEN | SPCMD_SSLKP | \
33                         SPCMD_BRDV0
34 #define SPCMD_INIT2     SPCMD_SPNDEN | SPCMD_SSLKP | \
35                         SPCMD_BRDV0
36 #define SPBFCR_TXRST    BIT(7)
37 #define SPBFCR_RXRST    BIT(6)
38 #define SPBFCR_TXTRG    0x30
39 #define SPBFCR_RXTRG    0x07
40
41 /* SH QSPI register set */
42 struct sh_qspi_regs {
43         u8      spcr;
44         u8      sslp;
45         u8      sppcr;
46         u8      spsr;
47         u32     spdr;
48         u8      spscr;
49         u8      spssr;
50         u8      spbr;
51         u8      spdcr;
52         u8      spckd;
53         u8      sslnd;
54         u8      spnd;
55         u8      dummy0;
56         u16     spcmd0;
57         u16     spcmd1;
58         u16     spcmd2;
59         u16     spcmd3;
60         u8      spbfcr;
61         u8      dummy1;
62         u16     spbdcr;
63         u32     spbmul0;
64         u32     spbmul1;
65         u32     spbmul2;
66         u32     spbmul3;
67 };
68
69 struct sh_qspi_slave {
70         struct spi_slave        slave;
71         struct sh_qspi_regs     *regs;
72 };
73
74 static inline struct sh_qspi_slave *to_sh_qspi(struct spi_slave *slave)
75 {
76         return container_of(slave, struct sh_qspi_slave, slave);
77 }
78
79 static void sh_qspi_init(struct sh_qspi_slave *ss)
80 {
81         /* QSPI initialize */
82         /* Set master mode only */
83         writeb(SPCR_MSTR, &ss->regs->spcr);
84
85         /* Set SSL signal level */
86         writeb(0x00, &ss->regs->sslp);
87
88         /* Set MOSI signal value when transfer is in idle state */
89         writeb(SPPCR_IO3FV|SPPCR_IO2FV, &ss->regs->sppcr);
90
91         /* Set bit rate. See 58.3.8 Quad Serial Peripheral Interface */
92         writeb(0x01, &ss->regs->spbr);
93
94         /* Disable Dummy Data Transmission */
95         writeb(0x00, &ss->regs->spdcr);
96
97         /* Set clock delay value */
98         writeb(0x00, &ss->regs->spckd);
99
100         /* Set SSL negation delay value */
101         writeb(0x00, &ss->regs->sslnd);
102
103         /* Set next-access delay value */
104         writeb(0x00, &ss->regs->spnd);
105
106         /* Set equence command */
107         writew(SPCMD_INIT2, &ss->regs->spcmd0);
108
109         /* Reset transfer and receive Buffer */
110         setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
111
112         /* Clear transfer and receive Buffer control bit */
113         clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
114
115         /* Set equence control method. Use equence0 only */
116         writeb(0x00, &ss->regs->spscr);
117
118         /* Enable SPI function */
119         setbits_8(&ss->regs->spcr, SPCR_SPE);
120 }
121
122 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
123 {
124         return 1;
125 }
126
127 void spi_cs_activate(struct spi_slave *slave)
128 {
129         struct sh_qspi_slave *ss = to_sh_qspi(slave);
130
131         /* Set master mode only */
132         writeb(SPCR_MSTR, &ss->regs->spcr);
133
134         /* Set command */
135         writew(SPCMD_INIT1, &ss->regs->spcmd0);
136
137         /* Reset transfer and receive Buffer */
138         setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
139
140         /* Clear transfer and receive Buffer control bit */
141         clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);
142
143         /* Set equence control method. Use equence0 only */
144         writeb(0x00, &ss->regs->spscr);
145
146         /* Enable SPI function */
147         setbits_8(&ss->regs->spcr, SPCR_SPE);
148 }
149
150 void spi_cs_deactivate(struct spi_slave *slave)
151 {
152         struct sh_qspi_slave *ss = to_sh_qspi(slave);
153
154         /* Disable SPI Function */
155         clrbits_8(&ss->regs->spcr, SPCR_SPE);
156 }
157
158 void spi_init(void)
159 {
160         /* nothing to do */
161 }
162
163 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
164                 unsigned int max_hz, unsigned int mode)
165 {
166         struct sh_qspi_slave *ss;
167
168         if (!spi_cs_is_valid(bus, cs))
169                 return NULL;
170
171         ss = spi_alloc_slave(struct sh_qspi_slave, bus, cs);
172         if (!ss) {
173                 printf("SPI_error: Fail to allocate sh_qspi_slave\n");
174                 return NULL;
175         }
176
177         ss->regs = (struct sh_qspi_regs *)SH_QSPI_BASE;
178
179         /* Init SH QSPI */
180         sh_qspi_init(ss);
181
182         return &ss->slave;
183 }
184
185 void spi_free_slave(struct spi_slave *slave)
186 {
187         struct sh_qspi_slave *spi = to_sh_qspi(slave);
188
189         free(spi);
190 }
191
192 int spi_claim_bus(struct spi_slave *slave)
193 {
194         return 0;
195 }
196
197 void spi_release_bus(struct spi_slave *slave)
198 {
199 }
200
201 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
202              void *din, unsigned long flags)
203 {
204         struct sh_qspi_slave *ss = to_sh_qspi(slave);
205         u32 nbyte, chunk;
206         int i, ret = 0;
207         u8 dtdata = 0, drdata;
208         u8 *tdata = &dtdata, *rdata = &drdata;
209         u32 *spbmul0 = &ss->regs->spbmul0;
210
211         if (dout == NULL && din == NULL) {
212                 if (flags & SPI_XFER_END)
213                         spi_cs_deactivate(slave);
214                 return 0;
215         }
216
217         if (bitlen % 8) {
218                 printf("%s: bitlen is not 8bit alined %d", __func__, bitlen);
219                 return 1;
220         }
221
222         nbyte = bitlen / 8;
223
224         if (flags & SPI_XFER_BEGIN) {
225                 spi_cs_activate(slave);
226
227                 /* Set 1048576 byte */
228                 writel(0x100000, spbmul0);
229         }
230
231         if (flags & SPI_XFER_END)
232                 writel(nbyte, spbmul0);
233
234         if (dout != NULL)
235                 tdata = (u8 *)dout;
236
237         if (din != NULL)
238                 rdata = din;
239
240         while (nbyte > 0) {
241                 /*
242                  * Check if there is 32 Byte chunk and if there is, transfer
243                  * it in one burst, otherwise transfer on byte-by-byte basis.
244                  */
245                 chunk = (nbyte >= 32) ? 32 : 1;
246
247                 clrsetbits_8(&ss->regs->spbfcr, SPBFCR_TXTRG | SPBFCR_RXTRG,
248                              chunk == 32 ? SPBFCR_TXTRG | SPBFCR_RXTRG : 0);
249
250                 ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPTEF,
251                                      true, 1000, true);
252                 if (ret)
253                         return ret;
254
255                 for (i = 0; i < chunk; i++) {
256                         writeb(*tdata, &ss->regs->spdr);
257                         if (dout != NULL)
258                                 tdata++;
259                 }
260
261                 ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPRFF,
262                                      true, 1000, true);
263                 if (ret)
264                         return ret;
265
266                 for (i = 0; i < chunk; i++) {
267                         *rdata = readb(&ss->regs->spdr);
268                         if (din != NULL)
269                                 rdata++;
270                 }
271
272                 nbyte -= chunk;
273         }
274
275         if (flags & SPI_XFER_END)
276                 spi_cs_deactivate(slave);
277
278         return ret;
279 }