aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Perier <romain.perier@free-electrons.com>2016-12-08 09:58:44 -0500
committerMark Brown <broonie@kernel.org>2016-12-08 11:05:34 -0500
commit5762ab71eb24a8393a167361510d7ca5e18c99f9 (patch)
tree3632a6465da524ccb201bdd22b9e2d4097cfba4e
parent4049537742b3ed39fac4da10d31f3171a2ee9a3e (diff)
spi: Add support for Armada 3700 SPI Controller
Marvell Armada 3700 SoC comprises an SPI Controller. This Controller supports up to 4 SPI slave devices, with dedicated chip selects,supports SPI mode 0/1/2 and 3, CPIO or Fifo mode with DMA transfers and different SPI transfer mode (Single, Dual or Quad). This commit adds basic driver support for FIFO mode. In this mode, dedicated registers are used to store the instruction, the address, the read mode and the data. Write and Read FIFO are used to store the outcoming or incoming data. The data FIFOs are accessible via DMA or by the CPU. Only the CPU is supported for now. Signed-off-by: Romain Perier <romain.perier@free-electrons.com> Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/spi-armada-3700.c923
3 files changed, 931 insertions, 0 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b7995474148c..1faad2ce4b4b 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -67,6 +67,13 @@ config SPI_ATH79
67 This enables support for the SPI controller present on the 67 This enables support for the SPI controller present on the
68 Atheros AR71XX/AR724X/AR913X SoCs. 68 Atheros AR71XX/AR724X/AR913X SoCs.
69 69
70config SPI_ARMADA_3700
71 tristate "Marvell Armada 3700 SPI Controller"
72 depends on (ARCH_MVEBU && OF) || COMPILE_TEST
73 help
74 This enables support for the SPI controller present on the
75 Marvell Armada 3700 SoCs.
76
70config SPI_ATMEL 77config SPI_ATMEL
71 tristate "Atmel SPI Controller" 78 tristate "Atmel SPI Controller"
72 depends on HAS_DMA 79 depends on HAS_DMA
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index aa939d955521..140ca45aa9d2 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o
12 12
13# SPI master controller drivers (bus) 13# SPI master controller drivers (bus)
14obj-$(CONFIG_SPI_ALTERA) += spi-altera.o 14obj-$(CONFIG_SPI_ALTERA) += spi-altera.o
15obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o
15obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o 16obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
16obj-$(CONFIG_SPI_ATH79) += spi-ath79.o 17obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
17obj-$(CONFIG_SPI_AU1550) += spi-au1550.o 18obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
diff --git a/drivers/spi/spi-armada-3700.c b/drivers/spi/spi-armada-3700.c
new file mode 100644
index 000000000000..e89da0af45d2
--- /dev/null
+++ b/drivers/spi/spi-armada-3700.c
@@ -0,0 +1,923 @@
1/*
2 * Marvell Armada-3700 SPI controller driver
3 *
4 * Copyright (C) 2016 Marvell Ltd.
5 *
6 * Author: Wilson Ding <dingwei@marvell.com>
7 * Author: Romain Perier <romain.perier@free-electrons.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/clk.h>
15#include <linux/completion.h>
16#include <linux/delay.h>
17#include <linux/err.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/of_irq.h>
24#include <linux/of_device.h>
25#include <linux/pinctrl/consumer.h>
26#include <linux/spi/spi.h>
27
28#define DRIVER_NAME "armada_3700_spi"
29
30#define A3700_SPI_TIMEOUT 10
31
32/* SPI Register Offest */
33#define A3700_SPI_IF_CTRL_REG 0x00
34#define A3700_SPI_IF_CFG_REG 0x04
35#define A3700_SPI_DATA_OUT_REG 0x08
36#define A3700_SPI_DATA_IN_REG 0x0C
37#define A3700_SPI_IF_INST_REG 0x10
38#define A3700_SPI_IF_ADDR_REG 0x14
39#define A3700_SPI_IF_RMODE_REG 0x18
40#define A3700_SPI_IF_HDR_CNT_REG 0x1C
41#define A3700_SPI_IF_DIN_CNT_REG 0x20
42#define A3700_SPI_IF_TIME_REG 0x24
43#define A3700_SPI_INT_STAT_REG 0x28
44#define A3700_SPI_INT_MASK_REG 0x2C
45
46/* A3700_SPI_IF_CTRL_REG */
47#define A3700_SPI_EN BIT(16)
48#define A3700_SPI_ADDR_NOT_CONFIG BIT(12)
49#define A3700_SPI_WFIFO_OVERFLOW BIT(11)
50#define A3700_SPI_WFIFO_UNDERFLOW BIT(10)
51#define A3700_SPI_RFIFO_OVERFLOW BIT(9)
52#define A3700_SPI_RFIFO_UNDERFLOW BIT(8)
53#define A3700_SPI_WFIFO_FULL BIT(7)
54#define A3700_SPI_WFIFO_EMPTY BIT(6)
55#define A3700_SPI_RFIFO_FULL BIT(5)
56#define A3700_SPI_RFIFO_EMPTY BIT(4)
57#define A3700_SPI_WFIFO_RDY BIT(3)
58#define A3700_SPI_RFIFO_RDY BIT(2)
59#define A3700_SPI_XFER_RDY BIT(1)
60#define A3700_SPI_XFER_DONE BIT(0)
61
62/* A3700_SPI_IF_CFG_REG */
63#define A3700_SPI_WFIFO_THRS BIT(28)
64#define A3700_SPI_RFIFO_THRS BIT(24)
65#define A3700_SPI_AUTO_CS BIT(20)
66#define A3700_SPI_DMA_RD_EN BIT(18)
67#define A3700_SPI_FIFO_MODE BIT(17)
68#define A3700_SPI_SRST BIT(16)
69#define A3700_SPI_XFER_START BIT(15)
70#define A3700_SPI_XFER_STOP BIT(14)
71#define A3700_SPI_INST_PIN BIT(13)
72#define A3700_SPI_ADDR_PIN BIT(12)
73#define A3700_SPI_DATA_PIN1 BIT(11)
74#define A3700_SPI_DATA_PIN0 BIT(10)
75#define A3700_SPI_FIFO_FLUSH BIT(9)
76#define A3700_SPI_RW_EN BIT(8)
77#define A3700_SPI_CLK_POL BIT(7)
78#define A3700_SPI_CLK_PHA BIT(6)
79#define A3700_SPI_BYTE_LEN BIT(5)
80#define A3700_SPI_CLK_PRESCALE BIT(0)
81#define A3700_SPI_CLK_PRESCALE_MASK (0x1f)
82
83#define A3700_SPI_WFIFO_THRS_BIT 28
84#define A3700_SPI_RFIFO_THRS_BIT 24
85#define A3700_SPI_FIFO_THRS_MASK 0x7
86
87#define A3700_SPI_DATA_PIN_MASK 0x3
88
89/* A3700_SPI_IF_HDR_CNT_REG */
90#define A3700_SPI_DUMMY_CNT_BIT 12
91#define A3700_SPI_DUMMY_CNT_MASK 0x7
92#define A3700_SPI_RMODE_CNT_BIT 8
93#define A3700_SPI_RMODE_CNT_MASK 0x3
94#define A3700_SPI_ADDR_CNT_BIT 4
95#define A3700_SPI_ADDR_CNT_MASK 0x7
96#define A3700_SPI_INSTR_CNT_BIT 0
97#define A3700_SPI_INSTR_CNT_MASK 0x3
98
99/* A3700_SPI_IF_TIME_REG */
100#define A3700_SPI_CLK_CAPT_EDGE BIT(7)
101
102/* Flags and macros for struct a3700_spi */
103#define A3700_INSTR_CNT 1
104#define A3700_ADDR_CNT 3
105#define A3700_DUMMY_CNT 1
106
107struct a3700_spi {
108 struct spi_master *master;
109 void __iomem *base;
110 struct clk *clk;
111 unsigned int irq;
112 unsigned int flags;
113 bool xmit_data;
114 const u8 *tx_buf;
115 u8 *rx_buf;
116 size_t buf_len;
117 u8 byte_len;
118 u32 wait_mask;
119 struct completion done;
120 u32 addr_cnt;
121 u32 instr_cnt;
122 size_t hdr_cnt;
123};
124
125static u32 spireg_read(struct a3700_spi *a3700_spi, u32 offset)
126{
127 return readl(a3700_spi->base + offset);
128}
129
130static void spireg_write(struct a3700_spi *a3700_spi, u32 offset, u32 data)
131{
132 writel(data, a3700_spi->base + offset);
133}
134
135static void a3700_spi_auto_cs_unset(struct a3700_spi *a3700_spi)
136{
137 u32 val;
138
139 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
140 val &= ~A3700_SPI_AUTO_CS;
141 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
142}
143
144static void a3700_spi_activate_cs(struct a3700_spi *a3700_spi, unsigned int cs)
145{
146 u32 val;
147
148 val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
149 val |= (A3700_SPI_EN << cs);
150 spireg_write(a3700_spi, A3700_SPI_IF_CTRL_REG, val);
151}
152
153static void a3700_spi_deactivate_cs(struct a3700_spi *a3700_spi,
154 unsigned int cs)
155{
156 u32 val;
157
158 val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
159 val &= ~(A3700_SPI_EN << cs);
160 spireg_write(a3700_spi, A3700_SPI_IF_CTRL_REG, val);
161}
162
163static int a3700_spi_pin_mode_set(struct a3700_spi *a3700_spi,
164 unsigned int pin_mode)
165{
166 u32 val;
167
168 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
169 val &= ~(A3700_SPI_INST_PIN | A3700_SPI_ADDR_PIN);
170 val &= ~(A3700_SPI_DATA_PIN0 | A3700_SPI_DATA_PIN1);
171
172 switch (pin_mode) {
173 case 1:
174 break;
175 case 2:
176 val |= A3700_SPI_DATA_PIN0;
177 break;
178 case 4:
179 val |= A3700_SPI_DATA_PIN1;
180 break;
181 default:
182 dev_err(&a3700_spi->master->dev, "wrong pin mode %u", pin_mode);
183 return -EINVAL;
184 }
185
186 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
187
188 return 0;
189}
190
191static void a3700_spi_fifo_mode_set(struct a3700_spi *a3700_spi)
192{
193 u32 val;
194
195 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
196 val |= A3700_SPI_FIFO_MODE;
197 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
198}
199
200static void a3700_spi_mode_set(struct a3700_spi *a3700_spi,
201 unsigned int mode_bits)
202{
203 u32 val;
204
205 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
206
207 if (mode_bits & SPI_CPOL)
208 val |= A3700_SPI_CLK_POL;
209 else
210 val &= ~A3700_SPI_CLK_POL;
211
212 if (mode_bits & SPI_CPHA)
213 val |= A3700_SPI_CLK_PHA;
214 else
215 val &= ~A3700_SPI_CLK_PHA;
216
217 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
218}
219
220static void a3700_spi_clock_set(struct a3700_spi *a3700_spi,
221 unsigned int speed_hz, u16 mode)
222{
223 u32 val;
224 u32 prescale;
225
226 prescale = DIV_ROUND_UP(clk_get_rate(a3700_spi->clk), speed_hz);
227
228 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
229 val = val & ~A3700_SPI_CLK_PRESCALE_MASK;
230
231 val = val | (prescale & A3700_SPI_CLK_PRESCALE_MASK);
232 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
233
234 if (prescale <= 2) {
235 val = spireg_read(a3700_spi, A3700_SPI_IF_TIME_REG);
236 val |= A3700_SPI_CLK_CAPT_EDGE;
237 spireg_write(a3700_spi, A3700_SPI_IF_TIME_REG, val);
238 }
239
240 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
241 val &= ~(A3700_SPI_CLK_POL | A3700_SPI_CLK_PHA);
242
243 if (mode & SPI_CPOL)
244 val |= A3700_SPI_CLK_POL;
245
246 if (mode & SPI_CPHA)
247 val |= A3700_SPI_CLK_PHA;
248
249 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
250}
251
252static void a3700_spi_bytelen_set(struct a3700_spi *a3700_spi, unsigned int len)
253{
254 u32 val;
255
256 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
257 if (len == 4)
258 val |= A3700_SPI_BYTE_LEN;
259 else
260 val &= ~A3700_SPI_BYTE_LEN;
261 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
262
263 a3700_spi->byte_len = len;
264}
265
266static int a3700_spi_fifo_flush(struct a3700_spi *a3700_spi)
267{
268 int timeout = A3700_SPI_TIMEOUT;
269 u32 val;
270
271 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
272 val |= A3700_SPI_FIFO_FLUSH;
273 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
274
275 while (--timeout) {
276 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
277 if (!(val & A3700_SPI_FIFO_FLUSH))
278 return 0;
279 udelay(1);
280 }
281
282 return -ETIMEDOUT;
283}
284
285static int a3700_spi_init(struct a3700_spi *a3700_spi)
286{
287 struct spi_master *master = a3700_spi->master;
288 u32 val;
289 int i, ret = 0;
290
291 /* Reset SPI unit */
292 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
293 val |= A3700_SPI_SRST;
294 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
295
296 udelay(A3700_SPI_TIMEOUT);
297
298 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
299 val &= ~A3700_SPI_SRST;
300 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
301
302 /* Disable AUTO_CS and deactivate all chip-selects */
303 a3700_spi_auto_cs_unset(a3700_spi);
304 for (i = 0; i < master->num_chipselect; i++)
305 a3700_spi_deactivate_cs(a3700_spi, i);
306
307 /* Enable FIFO mode */
308 a3700_spi_fifo_mode_set(a3700_spi);
309
310 /* Set SPI mode */
311 a3700_spi_mode_set(a3700_spi, master->mode_bits);
312
313 /* Reset counters */
314 spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, 0);
315 spireg_write(a3700_spi, A3700_SPI_IF_DIN_CNT_REG, 0);
316
317 /* Mask the interrupts and clear cause bits */
318 spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0);
319 spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, ~0U);
320
321 return ret;
322}
323
324static irqreturn_t a3700_spi_interrupt(int irq, void *dev_id)
325{
326 struct spi_master *master = dev_id;
327 struct a3700_spi *a3700_spi;
328 u32 cause;
329
330 a3700_spi = spi_master_get_devdata(master);
331
332 /* Get interrupt causes */
333 cause = spireg_read(a3700_spi, A3700_SPI_INT_STAT_REG);
334
335 if (!cause || !(a3700_spi->wait_mask & cause))
336 return IRQ_NONE;
337
338 /* mask and acknowledge the SPI interrupts */
339 spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0);
340 spireg_write(a3700_spi, A3700_SPI_INT_STAT_REG, cause);
341
342 /* Wake up the transfer */
343 if (a3700_spi->wait_mask & cause)
344 complete(&a3700_spi->done);
345
346 return IRQ_HANDLED;
347}
348
349static bool a3700_spi_wait_completion(struct spi_device *spi)
350{
351 struct a3700_spi *a3700_spi;
352 unsigned int timeout;
353 unsigned int ctrl_reg;
354 unsigned long timeout_jiffies;
355
356 a3700_spi = spi_master_get_devdata(spi->master);
357
358 /* SPI interrupt is edge-triggered, which means an interrupt will
359 * be generated only when detecting a specific status bit changed
360 * from '0' to '1'. So when we start waiting for a interrupt, we
361 * need to check status bit in control reg first, if it is already 1,
362 * then we do not need to wait for interrupt
363 */
364 ctrl_reg = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
365 if (a3700_spi->wait_mask & ctrl_reg)
366 return true;
367
368 reinit_completion(&a3700_spi->done);
369
370 spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG,
371 a3700_spi->wait_mask);
372
373 timeout_jiffies = msecs_to_jiffies(A3700_SPI_TIMEOUT);
374 timeout = wait_for_completion_timeout(&a3700_spi->done,
375 timeout_jiffies);
376
377 a3700_spi->wait_mask = 0;
378
379 if (timeout)
380 return true;
381
382 /* there might be the case that right after we checked the
383 * status bits in this routine and before start to wait for
384 * interrupt by wait_for_completion_timeout, the interrupt
385 * happens, to avoid missing it we need to double check
386 * status bits in control reg, if it is already 1, then
387 * consider that we have the interrupt successfully and
388 * return true.
389 */
390 ctrl_reg = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
391 if (a3700_spi->wait_mask & ctrl_reg)
392 return true;
393
394 spireg_write(a3700_spi, A3700_SPI_INT_MASK_REG, 0);
395
396 return true;
397}
398
399static bool a3700_spi_transfer_wait(struct spi_device *spi,
400 unsigned int bit_mask)
401{
402 struct a3700_spi *a3700_spi;
403
404 a3700_spi = spi_master_get_devdata(spi->master);
405 a3700_spi->wait_mask = bit_mask;
406
407 return a3700_spi_wait_completion(spi);
408}
409
410static void a3700_spi_fifo_thres_set(struct a3700_spi *a3700_spi,
411 unsigned int bytes)
412{
413 u32 val;
414
415 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
416 val &= ~(A3700_SPI_FIFO_THRS_MASK << A3700_SPI_RFIFO_THRS_BIT);
417 val |= (bytes - 1) << A3700_SPI_RFIFO_THRS_BIT;
418 val &= ~(A3700_SPI_FIFO_THRS_MASK << A3700_SPI_WFIFO_THRS_BIT);
419 val |= (7 - bytes) << A3700_SPI_WFIFO_THRS_BIT;
420 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
421}
422
423static void a3700_spi_transfer_setup(struct spi_device *spi,
424 struct spi_transfer *xfer)
425{
426 struct a3700_spi *a3700_spi;
427 unsigned int byte_len;
428
429 a3700_spi = spi_master_get_devdata(spi->master);
430
431 a3700_spi_clock_set(a3700_spi, xfer->speed_hz, spi->mode);
432
433 byte_len = xfer->bits_per_word >> 3;
434
435 a3700_spi_fifo_thres_set(a3700_spi, byte_len);
436}
437
438static void a3700_spi_set_cs(struct spi_device *spi, bool enable)
439{
440 struct a3700_spi *a3700_spi = spi_master_get_devdata(spi->master);
441
442 if (!enable)
443 a3700_spi_activate_cs(a3700_spi, spi->chip_select);
444 else
445 a3700_spi_deactivate_cs(a3700_spi, spi->chip_select);
446}
447
448static void a3700_spi_header_set(struct a3700_spi *a3700_spi)
449{
450 u32 instr_cnt = 0, addr_cnt = 0, dummy_cnt = 0;
451 u32 val = 0;
452
453 /* Clear the header registers */
454 spireg_write(a3700_spi, A3700_SPI_IF_INST_REG, 0);
455 spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, 0);
456 spireg_write(a3700_spi, A3700_SPI_IF_RMODE_REG, 0);
457
458 /* Set header counters */
459 if (a3700_spi->tx_buf) {
460 if (a3700_spi->buf_len <= a3700_spi->instr_cnt) {
461 instr_cnt = a3700_spi->buf_len;
462 } else if (a3700_spi->buf_len <= (a3700_spi->instr_cnt +
463 a3700_spi->addr_cnt)) {
464 instr_cnt = a3700_spi->instr_cnt;
465 addr_cnt = a3700_spi->buf_len - instr_cnt;
466 } else if (a3700_spi->buf_len <= a3700_spi->hdr_cnt) {
467 instr_cnt = a3700_spi->instr_cnt;
468 addr_cnt = a3700_spi->addr_cnt;
469 /* Need to handle the normal write case with 1 byte
470 * data
471 */
472 if (!a3700_spi->tx_buf[instr_cnt + addr_cnt])
473 dummy_cnt = a3700_spi->buf_len - instr_cnt -
474 addr_cnt;
475 }
476 val |= ((instr_cnt & A3700_SPI_INSTR_CNT_MASK)
477 << A3700_SPI_INSTR_CNT_BIT);
478 val |= ((addr_cnt & A3700_SPI_ADDR_CNT_MASK)
479 << A3700_SPI_ADDR_CNT_BIT);
480 val |= ((dummy_cnt & A3700_SPI_DUMMY_CNT_MASK)
481 << A3700_SPI_DUMMY_CNT_BIT);
482 }
483 spireg_write(a3700_spi, A3700_SPI_IF_HDR_CNT_REG, val);
484
485 /* Update the buffer length to be transferred */
486 a3700_spi->buf_len -= (instr_cnt + addr_cnt + dummy_cnt);
487
488 /* Set Instruction */
489 val = 0;
490 while (instr_cnt--) {
491 val = (val << 8) | a3700_spi->tx_buf[0];
492 a3700_spi->tx_buf++;
493 }
494 spireg_write(a3700_spi, A3700_SPI_IF_INST_REG, val);
495
496 /* Set Address */
497 val = 0;
498 while (addr_cnt--) {
499 val = (val << 8) | a3700_spi->tx_buf[0];
500 a3700_spi->tx_buf++;
501 }
502 spireg_write(a3700_spi, A3700_SPI_IF_ADDR_REG, val);
503}
504
505static int a3700_is_wfifo_full(struct a3700_spi *a3700_spi)
506{
507 u32 val;
508
509 val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
510 return (val & A3700_SPI_WFIFO_FULL);
511}
512
513static int a3700_spi_fifo_write(struct a3700_spi *a3700_spi)
514{
515 u32 val;
516 int i = 0;
517
518 while (!a3700_is_wfifo_full(a3700_spi) && a3700_spi->buf_len) {
519 val = 0;
520 if (a3700_spi->buf_len >= 4) {
521 val = cpu_to_le32(*(u32 *)a3700_spi->tx_buf);
522 spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG, val);
523
524 a3700_spi->buf_len -= 4;
525 a3700_spi->tx_buf += 4;
526 } else {
527 /*
528 * If the remained buffer length is less than 4-bytes,
529 * we should pad the write buffer with all ones. So that
530 * it avoids overwrite the unexpected bytes following
531 * the last one.
532 */
533 val = GENMASK(31, 0);
534 while (a3700_spi->buf_len) {
535 val &= ~(0xff << (8 * i));
536 val |= *a3700_spi->tx_buf++ << (8 * i);
537 i++;
538 a3700_spi->buf_len--;
539
540 spireg_write(a3700_spi, A3700_SPI_DATA_OUT_REG,
541 val);
542 }
543 break;
544 }
545 }
546
547 return 0;
548}
549
550static int a3700_is_rfifo_empty(struct a3700_spi *a3700_spi)
551{
552 u32 val = spireg_read(a3700_spi, A3700_SPI_IF_CTRL_REG);
553
554 return (val & A3700_SPI_RFIFO_EMPTY);
555}
556
557static int a3700_spi_fifo_read(struct a3700_spi *a3700_spi)
558{
559 u32 val;
560
561 while (!a3700_is_rfifo_empty(a3700_spi) && a3700_spi->buf_len) {
562 val = spireg_read(a3700_spi, A3700_SPI_DATA_IN_REG);
563 if (a3700_spi->buf_len >= 4) {
564 u32 data = le32_to_cpu(val);
565 memcpy(a3700_spi->rx_buf, &data, 4);
566
567 a3700_spi->buf_len -= 4;
568 a3700_spi->rx_buf += 4;
569 } else {
570 /*
571 * When remain bytes is not larger than 4, we should
572 * avoid memory overwriting and just write the left rx
573 * buffer bytes.
574 */
575 while (a3700_spi->buf_len) {
576 *a3700_spi->rx_buf = val & 0xff;
577 val >>= 8;
578
579 a3700_spi->buf_len--;
580 a3700_spi->rx_buf++;
581 }
582 }
583 }
584
585 return 0;
586}
587
588static void a3700_spi_transfer_abort_fifo(struct a3700_spi *a3700_spi)
589{
590 int timeout = A3700_SPI_TIMEOUT;
591 u32 val;
592
593 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
594 val |= A3700_SPI_XFER_STOP;
595 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
596
597 while (--timeout) {
598 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
599 if (!(val & A3700_SPI_XFER_START))
600 break;
601 udelay(1);
602 }
603
604 a3700_spi_fifo_flush(a3700_spi);
605
606 val &= ~A3700_SPI_XFER_STOP;
607 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
608}
609
610static int a3700_spi_prepare_message(struct spi_master *master,
611 struct spi_message *message)
612{
613 struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
614 struct spi_device *spi = message->spi;
615 int ret;
616
617 ret = clk_enable(a3700_spi->clk);
618 if (ret) {
619 dev_err(&spi->dev, "failed to enable clk with error %d\n", ret);
620 return ret;
621 }
622
623 /* Flush the FIFOs */
624 ret = a3700_spi_fifo_flush(a3700_spi);
625 if (ret)
626 return ret;
627
628 a3700_spi_bytelen_set(a3700_spi, 4);
629
630 return 0;
631}
632
633static int a3700_spi_transfer_one(struct spi_master *master,
634 struct spi_device *spi,
635 struct spi_transfer *xfer)
636{
637 struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
638 int ret = 0, timeout = A3700_SPI_TIMEOUT;
639 unsigned int nbits = 0;
640 u32 val;
641
642 a3700_spi_transfer_setup(spi, xfer);
643
644 a3700_spi->tx_buf = xfer->tx_buf;
645 a3700_spi->rx_buf = xfer->rx_buf;
646 a3700_spi->buf_len = xfer->len;
647
648 /* SPI transfer headers */
649 a3700_spi_header_set(a3700_spi);
650
651 if (xfer->tx_buf)
652 nbits = xfer->tx_nbits;
653 else if (xfer->rx_buf)
654 nbits = xfer->rx_nbits;
655
656 a3700_spi_pin_mode_set(a3700_spi, nbits);
657
658 if (xfer->rx_buf) {
659 /* Set read data length */
660 spireg_write(a3700_spi, A3700_SPI_IF_DIN_CNT_REG,
661 a3700_spi->buf_len);
662 /* Start READ transfer */
663 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
664 val &= ~A3700_SPI_RW_EN;
665 val |= A3700_SPI_XFER_START;
666 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
667 } else if (xfer->tx_buf) {
668 /* Start Write transfer */
669 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
670 val |= (A3700_SPI_XFER_START | A3700_SPI_RW_EN);
671 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
672
673 /*
674 * If there are data to be written to the SPI device, xmit_data
675 * flag is set true; otherwise the instruction in SPI_INSTR does
676 * not require data to be written to the SPI device, then
677 * xmit_data flag is set false.
678 */
679 a3700_spi->xmit_data = (a3700_spi->buf_len != 0);
680 }
681
682 while (a3700_spi->buf_len) {
683 if (a3700_spi->tx_buf) {
684 /* Wait wfifo ready */
685 if (!a3700_spi_transfer_wait(spi,
686 A3700_SPI_WFIFO_RDY)) {
687 dev_err(&spi->dev,
688 "wait wfifo ready timed out\n");
689 ret = -ETIMEDOUT;
690 goto error;
691 }
692 /* Fill up the wfifo */
693 ret = a3700_spi_fifo_write(a3700_spi);
694 if (ret)
695 goto error;
696 } else if (a3700_spi->rx_buf) {
697 /* Wait rfifo ready */
698 if (!a3700_spi_transfer_wait(spi,
699 A3700_SPI_RFIFO_RDY)) {
700 dev_err(&spi->dev,
701 "wait rfifo ready timed out\n");
702 ret = -ETIMEDOUT;
703 goto error;
704 }
705 /* Drain out the rfifo */
706 ret = a3700_spi_fifo_read(a3700_spi);
707 if (ret)
708 goto error;
709 }
710 }
711
712 /*
713 * Stop a write transfer in fifo mode:
714 * - wait all the bytes in wfifo to be shifted out
715 * - set XFER_STOP bit
716 * - wait XFER_START bit clear
717 * - clear XFER_STOP bit
718 * Stop a read transfer in fifo mode:
719 * - the hardware is to reset the XFER_START bit
720 * after the number of bytes indicated in DIN_CNT
721 * register
722 * - just wait XFER_START bit clear
723 */
724 if (a3700_spi->tx_buf) {
725 if (a3700_spi->xmit_data) {
726 /*
727 * If there are data written to the SPI device, wait
728 * until SPI_WFIFO_EMPTY is 1 to wait for all data to
729 * transfer out of write FIFO.
730 */
731 if (!a3700_spi_transfer_wait(spi,
732 A3700_SPI_WFIFO_EMPTY)) {
733 dev_err(&spi->dev, "wait wfifo empty timed out\n");
734 return -ETIMEDOUT;
735 }
736 } else {
737 /*
738 * If the instruction in SPI_INSTR does not require data
739 * to be written to the SPI device, wait until SPI_RDY
740 * is 1 for the SPI interface to be in idle.
741 */
742 if (!a3700_spi_transfer_wait(spi, A3700_SPI_XFER_RDY)) {
743 dev_err(&spi->dev, "wait xfer ready timed out\n");
744 return -ETIMEDOUT;
745 }
746 }
747
748 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
749 val |= A3700_SPI_XFER_STOP;
750 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
751 }
752
753 while (--timeout) {
754 val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG);
755 if (!(val & A3700_SPI_XFER_START))
756 break;
757 udelay(1);
758 }
759
760 if (timeout == 0) {
761 dev_err(&spi->dev, "wait transfer start clear timed out\n");
762 ret = -ETIMEDOUT;
763 goto error;
764 }
765
766 val &= ~A3700_SPI_XFER_STOP;
767 spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val);
768 goto out;
769
770error:
771 a3700_spi_transfer_abort_fifo(a3700_spi);
772out:
773 spi_finalize_current_transfer(master);
774
775 return ret;
776}
777
778static int a3700_spi_unprepare_message(struct spi_master *master,
779 struct spi_message *message)
780{
781 struct a3700_spi *a3700_spi = spi_master_get_devdata(master);
782
783 clk_disable(a3700_spi->clk);
784
785 return 0;
786}
787
788static const struct of_device_id a3700_spi_dt_ids[] = {
789 { .compatible = "marvell,armada-3700-spi", .data = NULL },
790 {},
791};
792
793MODULE_DEVICE_TABLE(of, a3700_spi_dt_ids);
794
795static int a3700_spi_probe(struct platform_device *pdev)
796{
797 struct device *dev = &pdev->dev;
798 struct device_node *of_node = dev->of_node;
799 struct resource *res;
800 struct spi_master *master;
801 struct a3700_spi *spi;
802 u32 num_cs = 0;
803 int ret = 0;
804
805 master = spi_alloc_master(dev, sizeof(*spi));
806 if (!master) {
807 dev_err(dev, "master allocation failed\n");
808 ret = -ENOMEM;
809 goto out;
810 }
811
812 if (of_property_read_u32(of_node, "num-cs", &num_cs)) {
813 dev_err(dev, "could not find num-cs\n");
814 ret = -ENXIO;
815 goto error;
816 }
817
818 master->bus_num = pdev->id;
819 master->dev.of_node = of_node;
820 master->mode_bits = SPI_MODE_3;
821 master->num_chipselect = num_cs;
822 master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(32);
823 master->prepare_message = a3700_spi_prepare_message;
824 master->transfer_one = a3700_spi_transfer_one;
825 master->unprepare_message = a3700_spi_unprepare_message;
826 master->set_cs = a3700_spi_set_cs;
827 master->flags = SPI_MASTER_HALF_DUPLEX;
828 master->mode_bits |= (SPI_RX_DUAL | SPI_RX_DUAL |
829 SPI_RX_QUAD | SPI_TX_QUAD);
830
831 platform_set_drvdata(pdev, master);
832
833 spi = spi_master_get_devdata(master);
834 memset(spi, 0, sizeof(struct a3700_spi));
835
836 spi->master = master;
837 spi->instr_cnt = A3700_INSTR_CNT;
838 spi->addr_cnt = A3700_ADDR_CNT;
839 spi->hdr_cnt = A3700_INSTR_CNT + A3700_ADDR_CNT +
840 A3700_DUMMY_CNT;
841
842 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
843 spi->base = devm_ioremap_resource(dev, res);
844 if (IS_ERR(spi->base)) {
845 ret = PTR_ERR(spi->base);
846 goto error;
847 }
848
849 spi->irq = platform_get_irq(pdev, 0);
850 if (spi->irq < 0) {
851 dev_err(dev, "could not get irq: %d\n", spi->irq);
852 ret = -ENXIO;
853 goto error;
854 }
855
856 init_completion(&spi->done);
857
858 spi->clk = devm_clk_get(dev, NULL);
859 if (IS_ERR(spi->clk)) {
860 dev_err(dev, "could not find clk: %ld\n", PTR_ERR(spi->clk));
861 goto error;
862 }
863
864 ret = clk_prepare(spi->clk);
865 if (ret) {
866 dev_err(dev, "could not prepare clk: %d\n", ret);
867 goto error;
868 }
869
870 ret = a3700_spi_init(spi);
871 if (ret)
872 goto error_clk;
873
874 ret = devm_request_irq(dev, spi->irq, a3700_spi_interrupt, 0,
875 dev_name(dev), master);
876 if (ret) {
877 dev_err(dev, "could not request IRQ: %d\n", ret);
878 goto error_clk;
879 }
880
881 ret = devm_spi_register_master(dev, master);
882 if (ret) {
883 dev_err(dev, "Failed to register master\n");
884 goto error_clk;
885 }
886
887 return 0;
888
889error_clk:
890 clk_disable_unprepare(spi->clk);
891error:
892 spi_master_put(master);
893out:
894 return ret;
895}
896
897static int a3700_spi_remove(struct platform_device *pdev)
898{
899 struct spi_master *master = platform_get_drvdata(pdev);
900 struct a3700_spi *spi = spi_master_get_devdata(master);
901
902 clk_unprepare(spi->clk);
903 spi_master_put(master);
904
905 return 0;
906}
907
908static struct platform_driver a3700_spi_driver = {
909 .driver = {
910 .name = DRIVER_NAME,
911 .owner = THIS_MODULE,
912 .of_match_table = of_match_ptr(a3700_spi_dt_ids),
913 },
914 .probe = a3700_spi_probe,
915 .remove = a3700_spi_remove,
916};
917
918module_platform_driver(a3700_spi_driver);
919
920MODULE_DESCRIPTION("Armada-3700 SPI driver");
921MODULE_AUTHOR("Wilson Ding <dingwei@marvell.com>");
922MODULE_LICENSE("GPL");
923MODULE_ALIAS("platform:" DRIVER_NAME);