blob: bb2262cc1f111166a22c21da764b28d45f52998b [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
Wenyou Yangda8ee982016-10-28 14:17:49 +080025DECLARE_GLOBAL_DATA_PTR;
26
Jagan Tekic5364d72018-03-14 18:46:43 +053027/* Register offsets */
28#define ATMEL_SPI_CR 0x0000
29#define ATMEL_SPI_MR 0x0004
30#define ATMEL_SPI_RDR 0x0008
31#define ATMEL_SPI_TDR 0x000c
32#define ATMEL_SPI_SR 0x0010
33#define ATMEL_SPI_IER 0x0014
34#define ATMEL_SPI_IDR 0x0018
35#define ATMEL_SPI_IMR 0x001c
36#define ATMEL_SPI_CSR(x) (0x0030 + 4 * (x))
37#define ATMEL_SPI_VERSION 0x00fc
38
39/* Bits in CR */
40#define ATMEL_SPI_CR_SPIEN BIT(0)
41#define ATMEL_SPI_CR_SPIDIS BIT(1)
42#define ATMEL_SPI_CR_SWRST BIT(7)
43#define ATMEL_SPI_CR_LASTXFER BIT(24)
44
45/* Bits in MR */
46#define ATMEL_SPI_MR_MSTR BIT(0)
47#define ATMEL_SPI_MR_PS BIT(1)
48#define ATMEL_SPI_MR_PCSDEC BIT(2)
49#define ATMEL_SPI_MR_FDIV BIT(3)
50#define ATMEL_SPI_MR_MODFDIS BIT(4)
51#define ATMEL_SPI_MR_WDRBT BIT(5)
52#define ATMEL_SPI_MR_LLB BIT(7)
53#define ATMEL_SPI_MR_PCS(x) (((x) & 15) << 16)
54#define ATMEL_SPI_MR_DLYBCS(x) ((x) << 24)
55
56/* Bits in RDR */
57#define ATMEL_SPI_RDR_RD(x) (x)
58#define ATMEL_SPI_RDR_PCS(x) ((x) << 16)
59
60/* Bits in TDR */
61#define ATMEL_SPI_TDR_TD(x) (x)
62#define ATMEL_SPI_TDR_PCS(x) ((x) << 16)
63#define ATMEL_SPI_TDR_LASTXFER BIT(24)
64
65/* Bits in SR/IER/IDR/IMR */
66#define ATMEL_SPI_SR_RDRF BIT(0)
67#define ATMEL_SPI_SR_TDRE BIT(1)
68#define ATMEL_SPI_SR_MODF BIT(2)
69#define ATMEL_SPI_SR_OVRES BIT(3)
70#define ATMEL_SPI_SR_ENDRX BIT(4)
71#define ATMEL_SPI_SR_ENDTX BIT(5)
72#define ATMEL_SPI_SR_RXBUFF BIT(6)
73#define ATMEL_SPI_SR_TXBUFE BIT(7)
74#define ATMEL_SPI_SR_NSSR BIT(8)
75#define ATMEL_SPI_SR_TXEMPTY BIT(9)
76#define ATMEL_SPI_SR_SPIENS BIT(16)
77
78/* Bits in CSRx */
79#define ATMEL_SPI_CSR_CPOL BIT(0)
80#define ATMEL_SPI_CSR_NCPHA BIT(1)
81#define ATMEL_SPI_CSR_CSAAT BIT(3)
82#define ATMEL_SPI_CSR_BITS(x) ((x) << 4)
83#define ATMEL_SPI_CSR_SCBR(x) ((x) << 8)
84#define ATMEL_SPI_CSR_SCBR_MAX GENMASK(7, 0)
85#define ATMEL_SPI_CSR_DLYBS(x) ((x) << 16)
86#define ATMEL_SPI_CSR_DLYBCT(x) ((x) << 24)
87
88/* Bits in VERSION */
89#define ATMEL_SPI_VERSION_REV(x) ((x) & 0xfff)
90#define ATMEL_SPI_VERSION_MFN(x) ((x) << 16)
91
92/* Constants for CSRx:BITS */
93#define ATMEL_SPI_BITS_8 0
94#define ATMEL_SPI_BITS_9 1
95#define ATMEL_SPI_BITS_10 2
96#define ATMEL_SPI_BITS_11 3
97#define ATMEL_SPI_BITS_12 4
98#define ATMEL_SPI_BITS_13 5
99#define ATMEL_SPI_BITS_14 6
100#define ATMEL_SPI_BITS_15 7
101#define ATMEL_SPI_BITS_16 8
102
103#define MAX_CS_COUNT 4
104
105struct atmel_spi_slave {
106 void *regs;
107 u32 mr;
108};
Wenyou Yangda8ee982016-10-28 14:17:49 +0800109
110struct atmel_spi_platdata {
111 struct at91_spi *regs;
112};
113
114struct atmel_spi_priv {
115 unsigned int freq; /* Default frequency */
116 unsigned int mode;
117 ulong bus_clk_rate;
Jagan Teki54036532018-03-14 18:46:31 +0530118#ifdef CONFIG_DM_GPIO
Wenyou Yangda8ee982016-10-28 14:17:49 +0800119 struct gpio_desc cs_gpios[MAX_CS_COUNT];
Jagan Teki54036532018-03-14 18:46:31 +0530120#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800121};
122
123static int atmel_spi_claim_bus(struct udevice *dev)
124{
125 struct udevice *bus = dev_get_parent(dev);
126 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
127 struct atmel_spi_priv *priv = dev_get_priv(bus);
128 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
129 struct at91_spi *reg_base = bus_plat->regs;
130 u32 cs = slave_plat->cs;
131 u32 freq = priv->freq;
132 u32 scbr, csrx, mode;
133
134 scbr = (priv->bus_clk_rate + freq - 1) / freq;
Jagan Tekic5364d72018-03-14 18:46:43 +0530135 if (scbr > ATMEL_SPI_CSR_SCBR_MAX)
Wenyou Yangda8ee982016-10-28 14:17:49 +0800136 return -EINVAL;
137
138 if (scbr < 1)
139 scbr = 1;
140
Jagan Tekic5364d72018-03-14 18:46:43 +0530141 csrx = ATMEL_SPI_CSR_SCBR(scbr);
142 csrx |= ATMEL_SPI_CSR_BITS(ATMEL_SPI_BITS_8);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800143
144 if (!(priv->mode & SPI_CPHA))
Jagan Tekic5364d72018-03-14 18:46:43 +0530145 csrx |= ATMEL_SPI_CSR_NCPHA;
Wenyou Yangda8ee982016-10-28 14:17:49 +0800146 if (priv->mode & SPI_CPOL)
Jagan Tekic5364d72018-03-14 18:46:43 +0530147 csrx |= ATMEL_SPI_CSR_CPOL;
Wenyou Yangda8ee982016-10-28 14:17:49 +0800148
149 writel(csrx, &reg_base->csr[cs]);
150
151 mode = ATMEL_SPI_MR_MSTR |
152 ATMEL_SPI_MR_MODFDIS |
153 ATMEL_SPI_MR_WDRBT |
154 ATMEL_SPI_MR_PCS(~(1 << cs));
155
156 writel(mode, &reg_base->mr);
157
158 writel(ATMEL_SPI_CR_SPIEN, &reg_base->cr);
159
160 return 0;
161}
162
163static int atmel_spi_release_bus(struct udevice *dev)
164{
165 struct udevice *bus = dev_get_parent(dev);
166 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
167
168 writel(ATMEL_SPI_CR_SPIDIS, &bus_plat->regs->cr);
169
170 return 0;
171}
172
173static void atmel_spi_cs_activate(struct udevice *dev)
174{
Jagan Teki54036532018-03-14 18:46:31 +0530175#ifdef CONFIG_DM_GPIO
Wenyou Yangda8ee982016-10-28 14:17:49 +0800176 struct udevice *bus = dev_get_parent(dev);
177 struct atmel_spi_priv *priv = dev_get_priv(bus);
178 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
179 u32 cs = slave_plat->cs;
180
Wenyou Yang530fa312017-04-07 15:14:46 +0800181 if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
182 return;
183
Wenyou Yangda8ee982016-10-28 14:17:49 +0800184 dm_gpio_set_value(&priv->cs_gpios[cs], 0);
Jagan Teki54036532018-03-14 18:46:31 +0530185#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800186}
187
188static void atmel_spi_cs_deactivate(struct udevice *dev)
189{
Jagan Teki54036532018-03-14 18:46:31 +0530190#ifdef CONFIG_DM_GPIO
Wenyou Yangda8ee982016-10-28 14:17:49 +0800191 struct udevice *bus = dev_get_parent(dev);
192 struct atmel_spi_priv *priv = dev_get_priv(bus);
193 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
194 u32 cs = slave_plat->cs;
195
Wenyou Yang530fa312017-04-07 15:14:46 +0800196 if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
197 return;
198
Wenyou Yangda8ee982016-10-28 14:17:49 +0800199 dm_gpio_set_value(&priv->cs_gpios[cs], 1);
Jagan Teki54036532018-03-14 18:46:31 +0530200#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800201}
202
203static int atmel_spi_xfer(struct udevice *dev, unsigned int bitlen,
204 const void *dout, void *din, unsigned long flags)
205{
206 struct udevice *bus = dev_get_parent(dev);
207 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
208 struct at91_spi *reg_base = bus_plat->regs;
209
210 u32 len_tx, len_rx, len;
211 u32 status;
212 const u8 *txp = dout;
213 u8 *rxp = din;
214 u8 value;
215
216 if (bitlen == 0)
217 goto out;
218
219 /*
220 * The controller can do non-multiple-of-8 bit
221 * transfers, but this driver currently doesn't support it.
222 *
223 * It's also not clear how such transfers are supposed to be
224 * represented as a stream of bytes...this is a limitation of
225 * the current SPI interface.
226 */
227 if (bitlen % 8) {
228 /* Errors always terminate an ongoing transfer */
229 flags |= SPI_XFER_END;
230 goto out;
231 }
232
233 len = bitlen / 8;
234
235 /*
236 * The controller can do automatic CS control, but it is
237 * somewhat quirky, and it doesn't really buy us much anyway
238 * in the context of U-Boot.
239 */
240 if (flags & SPI_XFER_BEGIN) {
241 atmel_spi_cs_activate(dev);
242
243 /*
244 * sometimes the RDR is not empty when we get here,
245 * in theory that should not happen, but it DOES happen.
246 * Read it here to be on the safe side.
247 * That also clears the OVRES flag. Required if the
248 * following loop exits due to OVRES!
249 */
250 readl(&reg_base->rdr);
251 }
252
253 for (len_tx = 0, len_rx = 0; len_rx < len; ) {
254 status = readl(&reg_base->sr);
255
256 if (status & ATMEL_SPI_SR_OVRES)
257 return -1;
258
259 if ((len_tx < len) && (status & ATMEL_SPI_SR_TDRE)) {
260 if (txp)
261 value = *txp++;
262 else
263 value = 0;
264 writel(value, &reg_base->tdr);
265 len_tx++;
266 }
267
268 if (status & ATMEL_SPI_SR_RDRF) {
269 value = readl(&reg_base->rdr);
270 if (rxp)
271 *rxp++ = value;
272 len_rx++;
273 }
274 }
275
276out:
277 if (flags & SPI_XFER_END) {
278 /*
279 * Wait until the transfer is completely done before
280 * we deactivate CS.
281 */
Álvaro Fernández Rojas918de032018-01-23 17:14:55 +0100282 wait_for_bit_le32(&reg_base->sr,
283 ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800284
285 atmel_spi_cs_deactivate(dev);
286 }
287
Hans-Christian Egtvedt9b4381b2008-05-16 11:10:32 +0200288 return 0;
289}
Wenyou Yangda8ee982016-10-28 14:17:49 +0800290
291static int atmel_spi_set_speed(struct udevice *bus, uint speed)
292{
293 struct atmel_spi_priv *priv = dev_get_priv(bus);
294
295 priv->freq = speed;
296
297 return 0;
298}
299
300static int atmel_spi_set_mode(struct udevice *bus, uint mode)
301{
302 struct atmel_spi_priv *priv = dev_get_priv(bus);
303
304 priv->mode = mode;
305
306 return 0;
307}
308
309static const struct dm_spi_ops atmel_spi_ops = {
310 .claim_bus = atmel_spi_claim_bus,
311 .release_bus = atmel_spi_release_bus,
312 .xfer = atmel_spi_xfer,
313 .set_speed = atmel_spi_set_speed,
314 .set_mode = atmel_spi_set_mode,
315 /*
316 * cs_info is not needed, since we require all chip selects to be
317 * in the device tree explicitly
318 */
319};
320
321static int atmel_spi_enable_clk(struct udevice *bus)
322{
323 struct atmel_spi_priv *priv = dev_get_priv(bus);
324 struct clk clk;
325 ulong clk_rate;
326 int ret;
327
328 ret = clk_get_by_index(bus, 0, &clk);
329 if (ret)
330 return -EINVAL;
331
332 ret = clk_enable(&clk);
333 if (ret)
334 return ret;
335
336 clk_rate = clk_get_rate(&clk);
337 if (!clk_rate)
338 return -EINVAL;
339
340 priv->bus_clk_rate = clk_rate;
341
342 clk_free(&clk);
343
344 return 0;
345}
346
347static int atmel_spi_probe(struct udevice *bus)
348{
349 struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
Jagan Teki54036532018-03-14 18:46:31 +0530350 int ret;
Wenyou Yangda8ee982016-10-28 14:17:49 +0800351
352 ret = atmel_spi_enable_clk(bus);
353 if (ret)
354 return ret;
355
Simon Glassba1dea42017-05-17 17:18:05 -0600356 bus_plat->regs = (struct at91_spi *)devfdt_get_addr(bus);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800357
Jagan Teki54036532018-03-14 18:46:31 +0530358#ifdef CONFIG_DM_GPIO
359 struct atmel_spi_priv *priv = dev_get_priv(bus);
360 int i;
361
Wenyou Yangda8ee982016-10-28 14:17:49 +0800362 ret = gpio_request_list_by_name(bus, "cs-gpios", priv->cs_gpios,
363 ARRAY_SIZE(priv->cs_gpios), 0);
364 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900365 pr_err("Can't get %s gpios! Error: %d", bus->name, ret);
Wenyou Yangda8ee982016-10-28 14:17:49 +0800366 return ret;
367 }
368
Jagan Tekic5364d72018-03-14 18:46:43 +0530369 for (i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) {
Wenyou Yang530fa312017-04-07 15:14:46 +0800370 if (!dm_gpio_is_valid(&priv->cs_gpios[i]))
371 continue;
372
Wenyou Yangda8ee982016-10-28 14:17:49 +0800373 dm_gpio_set_dir_flags(&priv->cs_gpios[i],
374 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
375 }
Jagan Teki54036532018-03-14 18:46:31 +0530376#endif
Wenyou Yangda8ee982016-10-28 14:17:49 +0800377
378 writel(ATMEL_SPI_CR_SWRST, &bus_plat->regs->cr);
379
380 return 0;
381}
382
383static const struct udevice_id atmel_spi_ids[] = {
384 { .compatible = "atmel,at91rm9200-spi" },
385 { }
386};
387
388U_BOOT_DRIVER(atmel_spi) = {
389 .name = "atmel_spi",
390 .id = UCLASS_SPI,
391 .of_match = atmel_spi_ids,
392 .ops = &atmel_spi_ops,
393 .platdata_auto_alloc_size = sizeof(struct atmel_spi_platdata),
394 .priv_auto_alloc_size = sizeof(struct atmel_spi_priv),
395 .probe = atmel_spi_probe,
396};