1
2
3
4
5
6
7
8
9
10#include <common.h>
11#include <dm.h>
12#include <log.h>
13#include <malloc.h>
14#include <spi.h>
15#include <asm/io.h>
16#include <asm/arch/soc.h>
17#ifdef CONFIG_ARCH_KIRKWOOD
18#include <asm/arch/mpp.h>
19#endif
20#include <asm/arch-mvebu/spi.h>
21
22struct mvebu_spi_dev {
23 bool is_errata_50mhz_ac;
24};
25
26struct mvebu_spi_plat {
27 struct kwspi_registers *spireg;
28 bool is_errata_50mhz_ac;
29};
30
31struct mvebu_spi_priv {
32 struct kwspi_registers *spireg;
33};
34
35static void _spi_cs_activate(struct kwspi_registers *reg)
36{
37 setbits_le32(®->ctrl, KWSPI_CSN_ACT);
38}
39
40static void _spi_cs_deactivate(struct kwspi_registers *reg)
41{
42 clrbits_le32(®->ctrl, KWSPI_CSN_ACT);
43}
44
45static int _spi_xfer(struct kwspi_registers *reg, unsigned int bitlen,
46 const void *dout, void *din, unsigned long flags)
47{
48 unsigned int tmpdout, tmpdin;
49 int tm, isread = 0;
50
51 debug("spi_xfer: dout %p din %p bitlen %u\n", dout, din, bitlen);
52
53 if (flags & SPI_XFER_BEGIN)
54 _spi_cs_activate(reg);
55
56
57
58
59
60 clrsetbits_le32(®->cfg, KWSPI_XFERLEN_MASK, KWSPI_XFERLEN_1BYTE);
61
62 while (bitlen > 4) {
63 debug("loopstart bitlen %d\n", bitlen);
64 tmpdout = 0;
65
66
67 if (dout)
68 tmpdout = *(u32 *)dout & 0xff;
69
70 clrbits_le32(®->irq_cause, KWSPI_SMEMRDIRQ);
71 writel(tmpdout, ®->dout);
72 debug("*** spi_xfer: ... %08x written, bitlen %d\n",
73 tmpdout, bitlen);
74
75
76
77
78
79
80 for (tm = 0, isread = 0; tm < KWSPI_TIMEOUT; ++tm) {
81 if (readl(®->irq_cause) & KWSPI_SMEMRDIRQ) {
82 isread = 1;
83 tmpdin = readl(®->din);
84 debug("spi_xfer: din %p..%08x read\n",
85 din, tmpdin);
86
87 if (din) {
88 *((u8 *)din) = (u8)tmpdin;
89 din += 1;
90 }
91 if (dout)
92 dout += 1;
93 bitlen -= 8;
94 }
95 if (isread)
96 break;
97 }
98 if (tm >= KWSPI_TIMEOUT)
99 printf("*** spi_xfer: Time out during SPI transfer\n");
100
101 debug("loopend bitlen %d\n", bitlen);
102 }
103
104 if (flags & SPI_XFER_END)
105 _spi_cs_deactivate(reg);
106
107 return 0;
108}
109
110static int mvebu_spi_set_speed(struct udevice *bus, uint hz)
111{
112 struct mvebu_spi_plat *plat = dev_get_plat(bus);
113 struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
114 struct kwspi_registers *reg = plat->spireg;
115 u32 data, divider;
116 unsigned int spr, sppr;
117
118 if (spi->max_hz && (hz > spi->max_hz)) {
119 debug("%s: limit speed to the max_hz of the bus %d\n",
120 __func__, spi->max_hz);
121 hz = spi->max_hz;
122 }
123
124
125
126
127
128
129
130
131
132
133
134 divider = DIV_ROUND_UP(CONFIG_SYS_TCLK, hz);
135 if (divider < 16) {
136
137 spr = divider;
138 sppr = 0;
139
140 } else {
141 unsigned int two_pow_sppr;
142
143
144
145
146
147
148 sppr = fls(divider) - 4;
149
150
151
152
153
154 two_pow_sppr = 1 << sppr;
155 divider = (divider + two_pow_sppr - 1) & -two_pow_sppr;
156
157
158
159
160
161
162
163
164 sppr = fls(divider) - 4;
165 spr = divider >> sppr;
166
167
168
169
170
171
172 if (sppr > 7)
173 return -EINVAL;
174 }
175
176 data = ((sppr & 0x6) << 5) | ((sppr & 0x1) << 4) | spr;
177
178
179 writel(KWSPI_ADRLEN_3BYTE | data, ®->cfg);
180 debug("data = 0x%08x\n", data);
181
182 return 0;
183}
184
185static void mvebu_spi_50mhz_ac_timing_erratum(struct udevice *bus, uint mode)
186{
187 struct mvebu_spi_plat *plat = dev_get_plat(bus);
188 struct kwspi_registers *reg = plat->spireg;
189 u32 data;
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 data = readl(®->timing1);
206 data &= ~KW_SPI_TMISO_SAMPLE_MASK;
207
208 if (CONFIG_SYS_TCLK == 250000000 &&
209 mode & SPI_CPOL &&
210 mode & SPI_CPHA)
211 data |= KW_SPI_TMISO_SAMPLE_2;
212 else
213 data |= KW_SPI_TMISO_SAMPLE_1;
214
215 writel(data, ®->timing1);
216}
217
218static int mvebu_spi_set_mode(struct udevice *bus, uint mode)
219{
220 struct mvebu_spi_plat *plat = dev_get_plat(bus);
221 struct kwspi_registers *reg = plat->spireg;
222 u32 data = readl(®->cfg);
223
224 data &= ~(KWSPI_CPHA | KWSPI_CPOL | KWSPI_RXLSBF | KWSPI_TXLSBF);
225
226 if (mode & SPI_CPHA)
227 data |= KWSPI_CPHA;
228 if (mode & SPI_CPOL)
229 data |= KWSPI_CPOL;
230 if (mode & SPI_LSB_FIRST)
231 data |= (KWSPI_RXLSBF | KWSPI_TXLSBF);
232
233 writel(data, ®->cfg);
234
235 if (plat->is_errata_50mhz_ac)
236 mvebu_spi_50mhz_ac_timing_erratum(bus, mode);
237
238 return 0;
239}
240
241static int mvebu_spi_xfer(struct udevice *dev, unsigned int bitlen,
242 const void *dout, void *din, unsigned long flags)
243{
244 struct udevice *bus = dev->parent;
245 struct mvebu_spi_plat *plat = dev_get_plat(bus);
246
247 return _spi_xfer(plat->spireg, bitlen, dout, din, flags);
248}
249
250__attribute__((weak)) int mvebu_board_spi_claim_bus(struct udevice *dev)
251{
252 return 0;
253}
254
255static int mvebu_spi_claim_bus(struct udevice *dev)
256{
257 struct udevice *bus = dev->parent;
258 struct mvebu_spi_plat *plat = dev_get_plat(bus);
259
260
261 clrsetbits_le32(&plat->spireg->ctrl,
262 KWSPI_CS_MASK << KWSPI_CS_SHIFT,
263 spi_chip_select(dev) << KWSPI_CS_SHIFT);
264
265 return mvebu_board_spi_claim_bus(dev);
266}
267
268__attribute__((weak)) int mvebu_board_spi_release_bus(struct udevice *dev)
269{
270 return 0;
271}
272
273static int mvebu_spi_release_bus(struct udevice *dev)
274{
275 return mvebu_board_spi_release_bus(dev);
276}
277
278static int mvebu_spi_probe(struct udevice *bus)
279{
280 struct mvebu_spi_plat *plat = dev_get_plat(bus);
281 struct kwspi_registers *reg = plat->spireg;
282
283 writel(KWSPI_SMEMRDY, ®->ctrl);
284 writel(KWSPI_SMEMRDIRQ, ®->irq_cause);
285 writel(KWSPI_IRQMASK, ®->irq_mask);
286
287 return 0;
288}
289
290static int mvebu_spi_of_to_plat(struct udevice *bus)
291{
292 struct mvebu_spi_plat *plat = dev_get_plat(bus);
293 const struct mvebu_spi_dev *drvdata =
294 (struct mvebu_spi_dev *)dev_get_driver_data(bus);
295
296 plat->spireg = dev_read_addr_ptr(bus);
297 plat->is_errata_50mhz_ac = drvdata->is_errata_50mhz_ac;
298
299 return 0;
300}
301
302static const struct dm_spi_ops mvebu_spi_ops = {
303 .claim_bus = mvebu_spi_claim_bus,
304 .release_bus = mvebu_spi_release_bus,
305 .xfer = mvebu_spi_xfer,
306 .set_speed = mvebu_spi_set_speed,
307 .set_mode = mvebu_spi_set_mode,
308
309
310
311
312};
313
314static const struct mvebu_spi_dev armada_spi_dev_data = {
315 .is_errata_50mhz_ac = false,
316};
317
318static const struct mvebu_spi_dev armada_xp_spi_dev_data = {
319 .is_errata_50mhz_ac = false,
320};
321
322static const struct mvebu_spi_dev armada_375_spi_dev_data = {
323 .is_errata_50mhz_ac = false,
324};
325
326static const struct mvebu_spi_dev armada_380_spi_dev_data = {
327 .is_errata_50mhz_ac = true,
328};
329
330static const struct udevice_id mvebu_spi_ids[] = {
331 {
332 .compatible = "marvell,orion-spi",
333 .data = (ulong)&armada_spi_dev_data,
334 },
335 {
336 .compatible = "marvell,armada-375-spi",
337 .data = (ulong)&armada_375_spi_dev_data
338 },
339 {
340 .compatible = "marvell,armada-380-spi",
341 .data = (ulong)&armada_380_spi_dev_data
342 },
343 {
344 .compatible = "marvell,armada-xp-spi",
345 .data = (ulong)&armada_xp_spi_dev_data
346 },
347 { }
348};
349
350U_BOOT_DRIVER(mvebu_spi) = {
351 .name = "mvebu_spi",
352 .id = UCLASS_SPI,
353 .of_match = mvebu_spi_ids,
354 .ops = &mvebu_spi_ops,
355 .of_to_plat = mvebu_spi_of_to_plat,
356 .plat_auto = sizeof(struct mvebu_spi_plat),
357 .priv_auto = sizeof(struct mvebu_spi_priv),
358 .probe = mvebu_spi_probe,
359};
360