Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / drivers / spi / andes_spi.c
1 /*
2  * Driver of Andes SPI Controller
3  *
4  * (C) Copyright 2011 Andes Technology
5  * Macpaul Lin <macpaul@andestech.com>
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include <common.h>
11 #include <malloc.h>
12 #include <spi.h>
13
14 #include <asm/io.h>
15 #include "andes_spi.h"
16
17 void spi_init(void)
18 {
19         /* do nothing */
20 }
21
22 static void andes_spi_spit_en(struct andes_spi_slave *ds)
23 {
24         unsigned int dcr = readl(&ds->regs->dcr);
25
26         debug("%s: dcr: %x, write value: %x\n",
27                         __func__, dcr, (dcr | ANDES_SPI_DCR_SPIT));
28
29         writel((dcr | ANDES_SPI_DCR_SPIT), &ds->regs->dcr);
30 }
31
32 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
33                         unsigned int max_hz, unsigned int mode)
34 {
35         struct andes_spi_slave  *ds;
36
37         if (!spi_cs_is_valid(bus, cs))
38                 return NULL;
39
40         ds = spi_alloc_slave(struct andes_spi_slave, bus, cs);
41         if (!ds)
42                 return NULL;
43
44         ds->regs = (struct andes_spi_regs *)CONFIG_SYS_SPI_BASE;
45
46         /*
47          * The hardware of andes_spi will set its frequency according
48          * to APB/AHB bus clock. Hence the hardware doesn't allow changing of
49          * requency and so the user requested speed is always ignored.
50          */
51         ds->freq = max_hz;
52
53         return &ds->slave;
54 }
55
56 void spi_free_slave(struct spi_slave *slave)
57 {
58         struct andes_spi_slave *ds = to_andes_spi(slave);
59
60         free(ds);
61 }
62
63 int spi_claim_bus(struct spi_slave *slave)
64 {
65         struct andes_spi_slave *ds = to_andes_spi(slave);
66         unsigned int apb;
67         unsigned int baud;
68
69         /* Enable the SPI hardware */
70         writel(ANDES_SPI_CR_SPIRST, &ds->regs->cr);
71         udelay(1000);
72
73         /* setup format */
74         baud = ((CONFIG_SYS_CLK_FREQ / CONFIG_SYS_SPI_CLK / 2) - 1) & 0xFF;
75
76         /*
77          * SPI_CLK = AHB bus clock / ((BAUD + 1)*2)
78          * BAUD = AHB bus clock / SPI_CLK / 2) - 1
79          */
80         apb = (readl(&ds->regs->apb) & 0xffffff00) | baud;
81         writel(apb, &ds->regs->apb);
82
83         /* no interrupts */
84         writel(0, &ds->regs->ie);
85
86         return 0;
87 }
88
89 void spi_release_bus(struct spi_slave *slave)
90 {
91         struct andes_spi_slave *ds = to_andes_spi(slave);
92
93         /* Disable the SPI hardware */
94         writel(ANDES_SPI_CR_SPIRST, &ds->regs->cr);
95 }
96
97 static int andes_spi_read(struct spi_slave *slave, unsigned int len,
98                             u8 *rxp, unsigned long flags)
99 {
100         struct andes_spi_slave *ds = to_andes_spi(slave);
101         unsigned int i, left;
102         unsigned int data;
103
104         debug("%s: slave: %x, len: %d, rxp: %x, flags: %d\n",
105                 __func__, slave, len, rxp, flags);
106
107         debug("%s: data: ", __func__);
108         while (len > 0) {
109                 left = min(len, 4);
110                 data = readl(&ds->regs->data);
111
112                 debug(" ");
113                 for (i = 0; i < left; i++) {
114                         debug("%02x ", data & 0xff);
115                         *rxp++ = data;
116                         data >>= 8;
117                         len--;
118                 }
119         }
120         debug("\n");
121
122         return 0;
123 }
124
125 static int andes_spi_write(struct spi_slave *slave, unsigned int wlen,
126                         unsigned int rlen, const u8 *txp, unsigned long flags)
127 {
128         struct andes_spi_slave *ds = to_andes_spi(slave);
129         unsigned int data;
130         unsigned int i, left;
131         unsigned int spit_enabled = 0;
132
133         debug("%s: slave: %x, wlen: %d, rlen: %d, txp: %x, flags: %x\n",
134                 __func__, slave, wlen, rlen, txp, flags);
135
136         /* The value of wlen and rlen wrote to register must minus 1 */
137         if (rlen == 0)                                  /* write only */
138                 writel(ANDES_SPI_DCR_MODE_WO | ANDES_SPI_DCR_WCNT(wlen-1) |
139                                 ANDES_SPI_DCR_RCNT(0), &ds->regs->dcr);
140         else                                            /* write then read */
141                 writel(ANDES_SPI_DCR_MODE_WR | ANDES_SPI_DCR_WCNT(wlen-1) |
142                                 ANDES_SPI_DCR_RCNT(rlen-1), &ds->regs->dcr);
143
144         /* wait till SPIBSY is cleared */
145         while (readl(&ds->regs->st) & ANDES_SPI_ST_SPIBSY)
146                 ;
147
148         /* data write process */
149         debug("%s: txp: ", __func__);
150         while (wlen > 0) {
151                 /* clear the data */
152                 data = 0;
153
154                 /* data are usually be read 32bits once a time */
155                 left = min(wlen, 4);
156
157                 for (i = 0; i < left; i++) {
158                         debug("%x ", *txp);
159                         data |= *txp++ << (i * 8);
160                         wlen--;
161                 }
162                 debug("\n");
163
164                 debug("data: %08x\n", data);
165                 debug("streg before write: %08x\n", readl(&ds->regs->st));
166                 /* wait till TXFULL is deasserted */
167                 while (readl(&ds->regs->st) & ANDES_SPI_ST_TXFEL)
168                         ;
169                 writel(data, &ds->regs->data);
170                 debug("streg after write: %08x\n", readl(&ds->regs->st));
171
172
173                 if (spit_enabled == 0) {
174                         /* enable SPIT bit -  trigger the tx and rx progress */
175                         andes_spi_spit_en(ds);
176                         spit_enabled = 1;
177                 }
178
179         }
180         debug("\n");
181
182         return 0;
183 }
184
185 /*
186  * spi_xfer:
187  *      Since andes_spi doesn't support independent command transaction,
188  *      that is, write and than read must be operated in continuous
189  *      execution, there is no need to set dcr and trigger spit again in
190  *      RX process.
191  */
192 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
193              const void *dout, void *din, unsigned long flags)
194 {
195         unsigned int len;
196         static int op_nextime;
197         static u8 tmp_cmd[5];
198         static int tmp_wlen;
199         unsigned int i;
200
201         if (bitlen == 0)
202                 /* Finish any previously submitted transfers */
203                 goto out;
204
205         if (bitlen % 8) {
206                 /* Errors always terminate an ongoing transfer */
207                 flags |= SPI_XFER_END;
208                 goto out;
209         }
210
211         len = bitlen / 8;
212
213         debug("%s: slave: %08x, bitlen: %d, dout: "
214                 "%08x, din: %08x, flags: %d, len: %d\n",
215                 __func__, slave, bitlen, dout, din, flags, len);
216
217         /*
218          * Important:
219          *      andes_spi's hardware doesn't support 2 data channel. The read
220          *      and write cmd/data share the same register (data register).
221          *
222          *      If a command has write and read transaction, you cannot do write
223          *      this time and then do read on next time.
224          *
225          *      A command writes first with a read response must indicating
226          *      the read length in write operation. Hence the write action must
227          *      be stored temporary and wait until the next read action has been
228          *      arrived. Then we flush the write and read action out together.
229          */
230         if (!dout) {
231                 if (op_nextime == 1) {
232                         /* flags should be SPI_XFER_END, value is 2 */
233                         op_nextime = 0;
234                         andes_spi_write(slave, tmp_wlen, len, tmp_cmd, flags);
235                 }
236                 return andes_spi_read(slave, len, din, flags);
237         } else if (!din) {
238                 if (flags == SPI_XFER_BEGIN) {
239                         /* store the write command and do operation next time */
240                         op_nextime = 1;
241                         memset(tmp_cmd, 0, sizeof(tmp_cmd));
242                         memcpy(tmp_cmd, dout, len);
243
244                         debug("%s: tmp_cmd: ", __func__);
245                         for (i = 0; i < len; i++)
246                                 debug("%x ", *(tmp_cmd + i));
247                         debug("\n");
248
249                         tmp_wlen = len;
250                 } else {
251                         /*
252                          * flags should be (SPI_XFER_BEGIN | SPI_XFER_END),
253                          * the value is 3.
254                          */
255                         if (op_nextime == 1) {
256                                 /* flags should be SPI_XFER_END, value is 2 */
257                                 op_nextime = 0;
258                                 /* flags 3 implies write only */
259                                 andes_spi_write(slave, tmp_wlen, 0, tmp_cmd, 3);
260                         }
261
262                         debug("flags: %x\n", flags);
263                         return andes_spi_write(slave, len, 0, dout, flags);
264                 }
265         }
266
267 out:
268         return 0;
269 }
270
271 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
272 {
273         return bus == 0 && cs == 0;
274 }
275
276 void spi_cs_activate(struct spi_slave *slave)
277 {
278         /* do nothing */
279 }
280
281 void spi_cs_deactivate(struct spi_slave *slave)
282 {
283         /* do nothing */
284 }