blob: 445d8652f903ba40e756174f7868833da50f87b0 [file] [log] [blame]
Hans-Christian Egtvedt9b4381b2008-05-16 11:10:32 +02001/*
2 * Copyright (C) 2007 Atmel Corporation
3 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Hans-Christian Egtvedt9b4381b2008-05-16 11:10:32 +02005 */
6#include <common.h>
Wenyou Yangda8ee982016-10-28 14:17:49 +08007#include <clk.h>
8#include <dm.h>
9#include <fdtdec.h>
Hans-Christian Egtvedt9b4381b2008-05-16 11:10:32 +020010#include <spi.h>
11#include <malloc.h>
Wenyou Yangda8ee982016-10-28 14:17:49 +080012#include <wait_bit.h>
Hans-Christian Egtvedt9b4381b2008-05-16 11:10:32 +020013
14#include <asm/io.h>
15
16#include <asm/arch/clk.h>
Reinhard Meyer7f619cb2010-11-03 16:32:56 +010017#include <asm/arch/hardware.h>
Wenyou Yangda8ee982016-10-28 14:17:49 +080018#ifdef CONFIG_DM_SPI
19#include <asm/arch/at91_spi.h>
20#endif
21#ifdef CONFIG_DM_GPIO
22#include <asm/gpio.h>
23#endif
Hans-Christian Egtvedt9b4381b2008-05-16 11:10:32 +020024
Tom Rini2981c4a2018-04-07 09:15:06 -040025#include "atmel_spi.h"
Jagan Tekic5364d72018-03-14 18:46:43 +053026
Tom Rinib02a3cc2018-04-07 09:15:50 -040027#ifndef CONFIG_DM_SPI
28
29static int spi_has_wdrbt(struct atmel_spi_slave *slave)
30{
31 unsigned int ver;
32
33 ver = spi_readl(slave, VERSION);
34
35 return (ATMEL_SPI_VERSION_REV(ver) >= 0x210);
36}
37
38void spi_init()
39{
40
41}
42
43struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
44 unsigned int max_hz, unsigned int mode)
45{
46 struct atmel_spi_slave *as;
47 unsigned int scbr;
48 u32 csrx;
49 void *regs;
50
51 if (!spi_cs_is_valid(bus, cs))
52 return NULL;
53
54 switch (bus) {
55 case 0:
56 regs = (void *)ATMEL_BASE_SPI0;
57 break;
58#ifdef ATMEL_BASE_SPI1
59 case 1:
60 regs = (void *)ATMEL_BASE_SPI1;
61 break;
62#endif
63#ifdef ATMEL_BASE_SPI2
64 case 2:
65 regs = (void *)ATMEL_BASE_SPI2;
66 break;
67#endif
68#ifdef ATMEL_BASE_SPI3
69 case 3:
70 regs = (void *)ATMEL_BASE_SPI3;
71 break;
72#endif
73 default:
74 return NULL;
75 }
76
77
78 scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz;
79 if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
80 /* Too low max SCK rate */
81 return NULL;
82 if (scbr < 1)
83 scbr = 1;
84
85 csrx = ATMEL_SPI_CSRx_SCBR(scbr);
86 csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
87 if (!(mode & SPI_CPHA))
88 csrx |= ATMEL_SPI_CSRx_NCPHA;
89 if (mode & SPI_CPOL)
90 csrx |= ATMEL_SPI_CSRx_CPOL;
91
92 as = spi_alloc_slave(struct atmel_spi_slave, bus, cs);
93 if (!as)
94 return NULL;
95
96 as->regs = regs;
97 as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS
98 | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf);
99 if (spi_has_wdrbt(as))
100 as->mr |= ATMEL_SPI_MR_WDRBT;
101
102 spi_writel(as, CSR(cs), csrx);
103
104 return &as->slave;
105}
106
107void spi_free_slave(struct spi_slave *slave)
108{
109 struct atmel_spi_slave *as = to_atmel_spi(slave);
110
111 free(as);
112}
113
114int spi_claim_bus(struct spi_slave *slave)
115{
116 struct atmel_spi_slave *as = to_atmel_spi(slave);
117
118 /* Enable the SPI hardware */
119 spi_writel(as, CR, ATMEL_SPI_CR_SPIEN);
120
121 /*
122 * Select the slave. This should set SCK to the correct
123 * initial state, etc.
124 */
125 spi_writel(as, MR, as->mr);
126
127 return 0;
128}
129
130void spi_release_bus(struct spi_slave *slave)
131{
132 struct atmel_spi_slave *as = to_atmel_spi(slave);
133
134 /* Disable the SPI hardware */
135 spi_writel(as, CR, ATMEL_SPI_CR_SPIDIS);
136}
137
138int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
139 const void *dout, void *din, unsigned long flags)
140{
141 struct atmel_spi_slave *as = to_atmel_spi(slave);
142 unsigned int len_tx;
143 unsigned int len_rx;
144 unsigned int len;
145 u32 status;
146 const u8 *txp = dout;
147 u8 *rxp = din;
148 u8 value;
149
150 if (bitlen == 0)
151 /* Finish any previously submitted transfers */
152 goto out;
153
154 /*
155 * TODO: The controller can do non-multiple-of-8 bit
156 * transfers, but this driver currently doesn't support it.
157 *
158 * It's also not clear how such transfers are supposed to be
159 * represented as a stream of bytes...this is a limitation of
160 * the current SPI interface.
161 */
162 if (bitlen % 8) {
163 /* Errors always terminate an ongoing transfer */
164 flags |= SPI_XFER_END;
165 goto out;
166 }
167
168 len = bitlen / 8;
169
170 /*
171 * The controller can do automatic CS control, but it is
172 * somewhat quirky, and it doesn't really buy us much anyway
173 * in the context of U-Boot.
174 */
175 if (flags & SPI_XFER_BEGIN) {
176 spi_cs_activate(slave);
177 /*
178 * sometimes the RDR is not empty when we get here,
179 * in theory that should not happen, but it DOES happen.
180 * Read it here to be on the safe side.
181 * That also clears the OVRES flag. Required if the
182 * following loop exits due to OVRES!
183 */
184 spi_readl(as, RDR);
185 }
186
187 for (len_tx = 0, len_rx = 0; len_rx < len; ) {
188 status = spi_readl(as, SR);
189
190 if (status & ATMEL_SPI_SR_OVRES)
191 return -1;
192
193 if (len_tx < len && (status & ATMEL_SPI_SR_TDRE)) {
194 if (txp)
195 value = *txp++;
196 else
197 value = 0;
198 spi_writel(as, TDR, value);
199 len_tx++;
200 }
201 if (status & ATMEL_SPI_SR_RDRF) {
202 value = spi_readl(as, RDR);
203 if (rxp)
204 *rxp++ = value;
205 len_rx++;
206 }
207 }
208
209out:
210 if (flags & SPI_XFER_END) {
211 /*
212 * Wait until the transfer is completely done before
213 * we deactivate CS.
214 */
215 do {
216 status = spi_readl(as, SR);
217 } while (!(status & ATMEL_SPI_SR_TXEMPTY));
218
219 spi_cs_deactivate(slave);
220 }
221
222 return 0;
223}
224
225#else
226
Tom Rini2981c4a2018-04-07 09:15:06 -0400227#define MAX_CS_COUNT 4
Wenyou Yangda8ee982016-10-28 14:17:49 +0800228
229struct atmel_spi_platdata {
230 struct at91_spi *regs;
231};
232
233struct atmel_spi_priv {
234 unsigned int freq; /* Default frequency */
235 unsigned int mode;
236 ulong bus_clk_rate;
Jagan Teki54036532018-03-14 18:46:31 +0530237#ifdef CONFIG_DM_GPIO
Wenyou Yangda8ee982016-10-28 14:17:49 +0800238 struct gpio_desc cs_gpios[MAX_CS_COUNT];
Jagan Teki54036532018-03-14 18:46:31 +0530239#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800240};
241
242static int atmel_spi_claim_bus(struct udevice *dev)
243{
244 struct udevice *bus = dev_get_parent(dev);
245 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
246 struct atmel_spi_priv *priv = dev_get_priv(bus);
247 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
248 struct at91_spi *reg_base = bus_plat->regs;
249 u32 cs = slave_plat->cs;
250 u32 freq = priv->freq;
251 u32 scbr, csrx, mode;
252
253 scbr = (priv->bus_clk_rate + freq - 1) / freq;
Tom Rini2981c4a2018-04-07 09:15:06 -0400254 if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
Wenyou Yangda8ee982016-10-28 14:17:49 +0800255 return -EINVAL;
256
257 if (scbr < 1)
258 scbr = 1;
259
Tom Rini2981c4a2018-04-07 09:15:06 -0400260 csrx = ATMEL_SPI_CSRx_SCBR(scbr);
261 csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800262
263 if (!(priv->mode & SPI_CPHA))
Tom Rini2981c4a2018-04-07 09:15:06 -0400264 csrx |= ATMEL_SPI_CSRx_NCPHA;
Wenyou Yangda8ee982016-10-28 14:17:49 +0800265 if (priv->mode & SPI_CPOL)
Tom Rini2981c4a2018-04-07 09:15:06 -0400266 csrx |= ATMEL_SPI_CSRx_CPOL;
Wenyou Yangda8ee982016-10-28 14:17:49 +0800267
268 writel(csrx, &reg_base->csr[cs]);
269
270 mode = ATMEL_SPI_MR_MSTR |
271 ATMEL_SPI_MR_MODFDIS |
272 ATMEL_SPI_MR_WDRBT |
273 ATMEL_SPI_MR_PCS(~(1 << cs));
274
275 writel(mode, &reg_base->mr);
276
277 writel(ATMEL_SPI_CR_SPIEN, &reg_base->cr);
278
279 return 0;
280}
281
282static int atmel_spi_release_bus(struct udevice *dev)
283{
284 struct udevice *bus = dev_get_parent(dev);
285 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
286
287 writel(ATMEL_SPI_CR_SPIDIS, &bus_plat->regs->cr);
288
289 return 0;
290}
291
292static void atmel_spi_cs_activate(struct udevice *dev)
293{
Jagan Teki54036532018-03-14 18:46:31 +0530294#ifdef CONFIG_DM_GPIO
Wenyou Yangda8ee982016-10-28 14:17:49 +0800295 struct udevice *bus = dev_get_parent(dev);
296 struct atmel_spi_priv *priv = dev_get_priv(bus);
297 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
298 u32 cs = slave_plat->cs;
299
Wenyou Yang530fa312017-04-07 15:14:46 +0800300 if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
301 return;
302
Wenyou Yangda8ee982016-10-28 14:17:49 +0800303 dm_gpio_set_value(&priv->cs_gpios[cs], 0);
Jagan Teki54036532018-03-14 18:46:31 +0530304#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800305}
306
307static void atmel_spi_cs_deactivate(struct udevice *dev)
308{
Jagan Teki54036532018-03-14 18:46:31 +0530309#ifdef CONFIG_DM_GPIO
Wenyou Yangda8ee982016-10-28 14:17:49 +0800310 struct udevice *bus = dev_get_parent(dev);
311 struct atmel_spi_priv *priv = dev_get_priv(bus);
312 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
313 u32 cs = slave_plat->cs;
314
Wenyou Yang530fa312017-04-07 15:14:46 +0800315 if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
316 return;
317
Wenyou Yangda8ee982016-10-28 14:17:49 +0800318 dm_gpio_set_value(&priv->cs_gpios[cs], 1);
Jagan Teki54036532018-03-14 18:46:31 +0530319#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800320}
321
322static int atmel_spi_xfer(struct udevice *dev, unsigned int bitlen,
323 const void *dout, void *din, unsigned long flags)
324{
325 struct udevice *bus = dev_get_parent(dev);
326 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
327 struct at91_spi *reg_base = bus_plat->regs;
328
329 u32 len_tx, len_rx, len;
330 u32 status;
331 const u8 *txp = dout;
332 u8 *rxp = din;
333 u8 value;
334
335 if (bitlen == 0)
336 goto out;
337
338 /*
339 * The controller can do non-multiple-of-8 bit
340 * transfers, but this driver currently doesn't support it.
341 *
342 * It's also not clear how such transfers are supposed to be
343 * represented as a stream of bytes...this is a limitation of
344 * the current SPI interface.
345 */
346 if (bitlen % 8) {
347 /* Errors always terminate an ongoing transfer */
348 flags |= SPI_XFER_END;
349 goto out;
350 }
351
352 len = bitlen / 8;
353
354 /*
355 * The controller can do automatic CS control, but it is
356 * somewhat quirky, and it doesn't really buy us much anyway
357 * in the context of U-Boot.
358 */
359 if (flags & SPI_XFER_BEGIN) {
360 atmel_spi_cs_activate(dev);
361
362 /*
363 * sometimes the RDR is not empty when we get here,
364 * in theory that should not happen, but it DOES happen.
365 * Read it here to be on the safe side.
366 * That also clears the OVRES flag. Required if the
367 * following loop exits due to OVRES!
368 */
369 readl(&reg_base->rdr);
370 }
371
372 for (len_tx = 0, len_rx = 0; len_rx < len; ) {
373 status = readl(&reg_base->sr);
374
375 if (status & ATMEL_SPI_SR_OVRES)
376 return -1;
377
378 if ((len_tx < len) && (status & ATMEL_SPI_SR_TDRE)) {
379 if (txp)
380 value = *txp++;
381 else
382 value = 0;
383 writel(value, &reg_base->tdr);
384 len_tx++;
385 }
386
387 if (status & ATMEL_SPI_SR_RDRF) {
388 value = readl(&reg_base->rdr);
389 if (rxp)
390 *rxp++ = value;
391 len_rx++;
392 }
393 }
394
395out:
396 if (flags & SPI_XFER_END) {
397 /*
398 * Wait until the transfer is completely done before
399 * we deactivate CS.
400 */
Álvaro Fernández Rojas918de032018-01-23 17:14:55 +0100401 wait_for_bit_le32(&reg_base->sr,
402 ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800403
404 atmel_spi_cs_deactivate(dev);
405 }
406
Hans-Christian Egtvedt9b4381b2008-05-16 11:10:32 +0200407 return 0;
408}
Wenyou Yangda8ee982016-10-28 14:17:49 +0800409
410static int atmel_spi_set_speed(struct udevice *bus, uint speed)
411{
412 struct atmel_spi_priv *priv = dev_get_priv(bus);
413
414 priv->freq = speed;
415
416 return 0;
417}
418
419static int atmel_spi_set_mode(struct udevice *bus, uint mode)
420{
421 struct atmel_spi_priv *priv = dev_get_priv(bus);
422
423 priv->mode = mode;
424
425 return 0;
426}
427
428static const struct dm_spi_ops atmel_spi_ops = {
429 .claim_bus = atmel_spi_claim_bus,
430 .release_bus = atmel_spi_release_bus,
431 .xfer = atmel_spi_xfer,
432 .set_speed = atmel_spi_set_speed,
433 .set_mode = atmel_spi_set_mode,
434 /*
435 * cs_info is not needed, since we require all chip selects to be
436 * in the device tree explicitly
437 */
438};
439
440static int atmel_spi_enable_clk(struct udevice *bus)
441{
442 struct atmel_spi_priv *priv = dev_get_priv(bus);
443 struct clk clk;
444 ulong clk_rate;
445 int ret;
446
447 ret = clk_get_by_index(bus, 0, &clk);
448 if (ret)
449 return -EINVAL;
450
451 ret = clk_enable(&clk);
452 if (ret)
453 return ret;
454
455 clk_rate = clk_get_rate(&clk);
456 if (!clk_rate)
457 return -EINVAL;
458
459 priv->bus_clk_rate = clk_rate;
460
461 clk_free(&clk);
462
463 return 0;
464}
465
466static int atmel_spi_probe(struct udevice *bus)
467{
468 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
Jagan Teki54036532018-03-14 18:46:31 +0530469 int ret;
Wenyou Yangda8ee982016-10-28 14:17:49 +0800470
471 ret = atmel_spi_enable_clk(bus);
472 if (ret)
473 return ret;
474
Simon Glassba1dea42017-05-17 17:18:05 -0600475 bus_plat->regs = (struct at91_spi *)devfdt_get_addr(bus);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800476
Jagan Teki54036532018-03-14 18:46:31 +0530477#ifdef CONFIG_DM_GPIO
478 struct atmel_spi_priv *priv = dev_get_priv(bus);
479 int i;
480
Wenyou Yangda8ee982016-10-28 14:17:49 +0800481 ret = gpio_request_list_by_name(bus, "cs-gpios", priv->cs_gpios,
482 ARRAY_SIZE(priv->cs_gpios), 0);
483 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900484 pr_err("Can't get %s gpios! Error: %d", bus->name, ret);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800485 return ret;
486 }
487
Tom Rini2981c4a2018-04-07 09:15:06 -0400488 for(i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) {
Wenyou Yang530fa312017-04-07 15:14:46 +0800489 if (!dm_gpio_is_valid(&priv->cs_gpios[i]))
490 continue;
491
Wenyou Yangda8ee982016-10-28 14:17:49 +0800492 dm_gpio_set_dir_flags(&priv->cs_gpios[i],
493 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
494 }
Jagan Teki54036532018-03-14 18:46:31 +0530495#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800496
497 writel(ATMEL_SPI_CR_SWRST, &bus_plat->regs->cr);
498
499 return 0;
500}
501
502static const struct udevice_id atmel_spi_ids[] = {
503 { .compatible = "atmel,at91rm9200-spi" },
504 { }
505};
506
507U_BOOT_DRIVER(atmel_spi) = {
508 .name = "atmel_spi",
509 .id = UCLASS_SPI,
510 .of_match = atmel_spi_ids,
511 .ops = &atmel_spi_ops,
512 .platdata_auto_alloc_size = sizeof(struct atmel_spi_platdata),
513 .priv_auto_alloc_size = sizeof(struct atmel_spi_priv),
514 .probe = atmel_spi_probe,
515};
Tom Rinib02a3cc2018-04-07 09:15:50 -0400516#endif