2 * SPI-Engine SPI controller driver
3 * Copyright 2015 Analog Devices Inc.
4 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 * Licensed under the GPL-2.
10 #include <linux/interrupt.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/spi/spi.h>
17 #define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff)
18 #define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff)
19 #define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff)
21 #define SPI_ENGINE_REG_VERSION 0x00
23 #define SPI_ENGINE_REG_RESET 0x40
25 #define SPI_ENGINE_REG_INT_ENABLE 0x80
26 #define SPI_ENGINE_REG_INT_PENDING 0x84
27 #define SPI_ENGINE_REG_INT_SOURCE 0x88
29 #define SPI_ENGINE_REG_SYNC_ID 0xc0
31 #define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xd0
32 #define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xd4
33 #define SPI_ENGINE_REG_SDI_FIFO_LEVEL 0xd8
35 #define SPI_ENGINE_REG_CMD_FIFO 0xe0
36 #define SPI_ENGINE_REG_SDO_DATA_FIFO 0xe4
37 #define SPI_ENGINE_REG_SDI_DATA_FIFO 0xe8
38 #define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xec
40 #define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0)
41 #define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1)
42 #define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2)
43 #define SPI_ENGINE_INT_SYNC BIT(3)
45 #define SPI_ENGINE_CONFIG_CPHA BIT(0)
46 #define SPI_ENGINE_CONFIG_CPOL BIT(1)
47 #define SPI_ENGINE_CONFIG_3WIRE BIT(2)
49 #define SPI_ENGINE_INST_TRANSFER 0x0
50 #define SPI_ENGINE_INST_ASSERT 0x1
51 #define SPI_ENGINE_INST_WRITE 0x2
52 #define SPI_ENGINE_INST_MISC 0x3
54 #define SPI_ENGINE_CMD_REG_CLK_DIV 0x0
55 #define SPI_ENGINE_CMD_REG_CONFIG 0x1
57 #define SPI_ENGINE_MISC_SYNC 0x0
58 #define SPI_ENGINE_MISC_SLEEP 0x1
60 #define SPI_ENGINE_TRANSFER_WRITE 0x1
61 #define SPI_ENGINE_TRANSFER_READ 0x2
63 #define SPI_ENGINE_CMD(inst, arg1, arg2) \
64 (((inst) << 12) | ((arg1) << 8) | (arg2))
66 #define SPI_ENGINE_CMD_TRANSFER(flags, n) \
67 SPI_ENGINE_CMD(SPI_ENGINE_INST_TRANSFER, (flags), (n))
68 #define SPI_ENGINE_CMD_ASSERT(delay, cs) \
69 SPI_ENGINE_CMD(SPI_ENGINE_INST_ASSERT, (delay), (cs))
70 #define SPI_ENGINE_CMD_WRITE(reg, val) \
71 SPI_ENGINE_CMD(SPI_ENGINE_INST_WRITE, (reg), (val))
72 #define SPI_ENGINE_CMD_SLEEP(delay) \
73 SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SLEEP, (delay))
74 #define SPI_ENGINE_CMD_SYNC(id) \
75 SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SYNC, (id))
77 struct spi_engine_program
{
79 uint16_t instructions
[];
90 struct spi_message
*msg
;
91 struct spi_engine_program
*p
;
93 const uint16_t *cmd_buf
;
95 struct spi_transfer
*tx_xfer
;
96 unsigned int tx_length
;
97 const uint8_t *tx_buf
;
99 struct spi_transfer
*rx_xfer
;
100 unsigned int rx_length
;
103 unsigned int sync_id
;
104 unsigned int completed_id
;
106 unsigned int int_enable
;
109 static void spi_engine_program_add_cmd(struct spi_engine_program
*p
,
110 bool dry
, uint16_t cmd
)
113 p
->instructions
[p
->length
] = cmd
;
117 static unsigned int spi_engine_get_config(struct spi_device
*spi
)
119 unsigned int config
= 0;
121 if (spi
->mode
& SPI_CPOL
)
122 config
|= SPI_ENGINE_CONFIG_CPOL
;
123 if (spi
->mode
& SPI_CPHA
)
124 config
|= SPI_ENGINE_CONFIG_CPHA
;
125 if (spi
->mode
& SPI_3WIRE
)
126 config
|= SPI_ENGINE_CONFIG_3WIRE
;
131 static unsigned int spi_engine_get_clk_div(struct spi_engine
*spi_engine
,
132 struct spi_device
*spi
, struct spi_transfer
*xfer
)
134 unsigned int clk_div
;
136 clk_div
= DIV_ROUND_UP(clk_get_rate(spi_engine
->ref_clk
),
140 else if (clk_div
> 0)
146 static void spi_engine_gen_xfer(struct spi_engine_program
*p
, bool dry
,
147 struct spi_transfer
*xfer
)
149 unsigned int len
= xfer
->len
;
152 unsigned int n
= min(len
, 256U);
153 unsigned int flags
= 0;
156 flags
|= SPI_ENGINE_TRANSFER_WRITE
;
158 flags
|= SPI_ENGINE_TRANSFER_READ
;
160 spi_engine_program_add_cmd(p
, dry
,
161 SPI_ENGINE_CMD_TRANSFER(flags
, n
- 1));
166 static void spi_engine_gen_sleep(struct spi_engine_program
*p
, bool dry
,
167 struct spi_engine
*spi_engine
, unsigned int clk_div
, unsigned int delay
)
169 unsigned int spi_clk
= clk_get_rate(spi_engine
->ref_clk
);
175 t
= DIV_ROUND_UP(delay
* spi_clk
, (clk_div
+ 1) * 2);
177 unsigned int n
= min(t
, 256U);
179 spi_engine_program_add_cmd(p
, dry
, SPI_ENGINE_CMD_SLEEP(n
- 1));
184 static void spi_engine_gen_cs(struct spi_engine_program
*p
, bool dry
,
185 struct spi_device
*spi
, bool assert)
187 unsigned int mask
= 0xff;
190 mask
^= BIT(spi
->chip_select
);
192 spi_engine_program_add_cmd(p
, dry
, SPI_ENGINE_CMD_ASSERT(1, mask
));
195 static int spi_engine_compile_message(struct spi_engine
*spi_engine
,
196 struct spi_message
*msg
, bool dry
, struct spi_engine_program
*p
)
198 struct spi_device
*spi
= msg
->spi
;
199 struct spi_transfer
*xfer
;
200 int clk_div
, new_clk_div
;
201 bool cs_change
= true;
205 spi_engine_program_add_cmd(p
, dry
,
206 SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CONFIG
,
207 spi_engine_get_config(spi
)));
209 list_for_each_entry(xfer
, &msg
->transfers
, transfer_list
) {
210 new_clk_div
= spi_engine_get_clk_div(spi_engine
, spi
, xfer
);
211 if (new_clk_div
!= clk_div
) {
212 clk_div
= new_clk_div
;
213 spi_engine_program_add_cmd(p
, dry
,
214 SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CLK_DIV
,
219 spi_engine_gen_cs(p
, dry
, spi
, true);
221 spi_engine_gen_xfer(p
, dry
, xfer
);
222 spi_engine_gen_sleep(p
, dry
, spi_engine
, clk_div
,
225 cs_change
= xfer
->cs_change
;
226 if (list_is_last(&xfer
->transfer_list
, &msg
->transfers
))
227 cs_change
= !cs_change
;
230 spi_engine_gen_cs(p
, dry
, spi
, false);
236 static void spi_engine_xfer_next(struct spi_engine
*spi_engine
,
237 struct spi_transfer
**_xfer
)
239 struct spi_message
*msg
= spi_engine
->msg
;
240 struct spi_transfer
*xfer
= *_xfer
;
243 xfer
= list_first_entry(&msg
->transfers
,
244 struct spi_transfer
, transfer_list
);
245 } else if (list_is_last(&xfer
->transfer_list
, &msg
->transfers
)) {
248 xfer
= list_next_entry(xfer
, transfer_list
);
254 static void spi_engine_tx_next(struct spi_engine
*spi_engine
)
256 struct spi_transfer
*xfer
= spi_engine
->tx_xfer
;
259 spi_engine_xfer_next(spi_engine
, &xfer
);
260 } while (xfer
&& !xfer
->tx_buf
);
262 spi_engine
->tx_xfer
= xfer
;
264 spi_engine
->tx_length
= xfer
->len
;
265 spi_engine
->tx_buf
= xfer
->tx_buf
;
267 spi_engine
->tx_buf
= NULL
;
271 static void spi_engine_rx_next(struct spi_engine
*spi_engine
)
273 struct spi_transfer
*xfer
= spi_engine
->rx_xfer
;
276 spi_engine_xfer_next(spi_engine
, &xfer
);
277 } while (xfer
&& !xfer
->rx_buf
);
279 spi_engine
->rx_xfer
= xfer
;
281 spi_engine
->rx_length
= xfer
->len
;
282 spi_engine
->rx_buf
= xfer
->rx_buf
;
284 spi_engine
->rx_buf
= NULL
;
288 static bool spi_engine_write_cmd_fifo(struct spi_engine
*spi_engine
)
290 void __iomem
*addr
= spi_engine
->base
+ SPI_ENGINE_REG_CMD_FIFO
;
291 unsigned int n
, m
, i
;
294 n
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_CMD_FIFO_ROOM
);
295 while (n
&& spi_engine
->cmd_length
) {
296 m
= min(n
, spi_engine
->cmd_length
);
297 buf
= spi_engine
->cmd_buf
;
298 for (i
= 0; i
< m
; i
++)
299 writel_relaxed(buf
[i
], addr
);
300 spi_engine
->cmd_buf
+= m
;
301 spi_engine
->cmd_length
-= m
;
305 return spi_engine
->cmd_length
!= 0;
308 static bool spi_engine_write_tx_fifo(struct spi_engine
*spi_engine
)
310 void __iomem
*addr
= spi_engine
->base
+ SPI_ENGINE_REG_SDO_DATA_FIFO
;
311 unsigned int n
, m
, i
;
314 n
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_SDO_FIFO_ROOM
);
315 while (n
&& spi_engine
->tx_length
) {
316 m
= min(n
, spi_engine
->tx_length
);
317 buf
= spi_engine
->tx_buf
;
318 for (i
= 0; i
< m
; i
++)
319 writel_relaxed(buf
[i
], addr
);
320 spi_engine
->tx_buf
+= m
;
321 spi_engine
->tx_length
-= m
;
323 if (spi_engine
->tx_length
== 0)
324 spi_engine_tx_next(spi_engine
);
327 return spi_engine
->tx_length
!= 0;
330 static bool spi_engine_read_rx_fifo(struct spi_engine
*spi_engine
)
332 void __iomem
*addr
= spi_engine
->base
+ SPI_ENGINE_REG_SDI_DATA_FIFO
;
333 unsigned int n
, m
, i
;
336 n
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_SDI_FIFO_LEVEL
);
337 while (n
&& spi_engine
->rx_length
) {
338 m
= min(n
, spi_engine
->rx_length
);
339 buf
= spi_engine
->rx_buf
;
340 for (i
= 0; i
< m
; i
++)
341 buf
[i
] = readl_relaxed(addr
);
342 spi_engine
->rx_buf
+= m
;
343 spi_engine
->rx_length
-= m
;
345 if (spi_engine
->rx_length
== 0)
346 spi_engine_rx_next(spi_engine
);
349 return spi_engine
->rx_length
!= 0;
352 static irqreturn_t
spi_engine_irq(int irq
, void *devid
)
354 struct spi_master
*master
= devid
;
355 struct spi_engine
*spi_engine
= spi_master_get_devdata(master
);
356 unsigned int disable_int
= 0;
357 unsigned int pending
;
359 pending
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_INT_PENDING
);
361 if (pending
& SPI_ENGINE_INT_SYNC
) {
362 writel_relaxed(SPI_ENGINE_INT_SYNC
,
363 spi_engine
->base
+ SPI_ENGINE_REG_INT_PENDING
);
364 spi_engine
->completed_id
= readl_relaxed(
365 spi_engine
->base
+ SPI_ENGINE_REG_SYNC_ID
);
368 spin_lock(&spi_engine
->lock
);
370 if (pending
& SPI_ENGINE_INT_CMD_ALMOST_EMPTY
) {
371 if (!spi_engine_write_cmd_fifo(spi_engine
))
372 disable_int
|= SPI_ENGINE_INT_CMD_ALMOST_EMPTY
;
375 if (pending
& SPI_ENGINE_INT_SDO_ALMOST_EMPTY
) {
376 if (!spi_engine_write_tx_fifo(spi_engine
))
377 disable_int
|= SPI_ENGINE_INT_SDO_ALMOST_EMPTY
;
380 if (pending
& (SPI_ENGINE_INT_SDI_ALMOST_FULL
| SPI_ENGINE_INT_SYNC
)) {
381 if (!spi_engine_read_rx_fifo(spi_engine
))
382 disable_int
|= SPI_ENGINE_INT_SDI_ALMOST_FULL
;
385 if (pending
& SPI_ENGINE_INT_SYNC
) {
386 if (spi_engine
->msg
&&
387 spi_engine
->completed_id
== spi_engine
->sync_id
) {
388 struct spi_message
*msg
= spi_engine
->msg
;
390 kfree(spi_engine
->p
);
392 msg
->actual_length
= msg
->frame_length
;
393 spi_engine
->msg
= NULL
;
394 spi_finalize_current_message(master
);
395 disable_int
|= SPI_ENGINE_INT_SYNC
;
400 spi_engine
->int_enable
&= ~disable_int
;
401 writel_relaxed(spi_engine
->int_enable
,
402 spi_engine
->base
+ SPI_ENGINE_REG_INT_ENABLE
);
405 spin_unlock(&spi_engine
->lock
);
410 static int spi_engine_transfer_one_message(struct spi_master
*master
,
411 struct spi_message
*msg
)
413 struct spi_engine_program p_dry
, *p
;
414 struct spi_engine
*spi_engine
= spi_master_get_devdata(master
);
415 unsigned int int_enable
= 0;
420 spi_engine_compile_message(spi_engine
, msg
, true, &p_dry
);
422 size
= sizeof(*p
->instructions
) * (p_dry
.length
+ 1);
423 p
= kzalloc(sizeof(*p
) + size
, GFP_KERNEL
);
426 spi_engine_compile_message(spi_engine
, msg
, false, p
);
428 spin_lock_irqsave(&spi_engine
->lock
, flags
);
429 spi_engine
->sync_id
= (spi_engine
->sync_id
+ 1) & 0xff;
430 spi_engine_program_add_cmd(p
, false,
431 SPI_ENGINE_CMD_SYNC(spi_engine
->sync_id
));
433 spi_engine
->msg
= msg
;
436 spi_engine
->cmd_buf
= p
->instructions
;
437 spi_engine
->cmd_length
= p
->length
;
438 if (spi_engine_write_cmd_fifo(spi_engine
))
439 int_enable
|= SPI_ENGINE_INT_CMD_ALMOST_EMPTY
;
441 spi_engine_tx_next(spi_engine
);
442 if (spi_engine_write_tx_fifo(spi_engine
))
443 int_enable
|= SPI_ENGINE_INT_SDO_ALMOST_EMPTY
;
445 spi_engine_rx_next(spi_engine
);
446 if (spi_engine
->rx_length
!= 0)
447 int_enable
|= SPI_ENGINE_INT_SDI_ALMOST_FULL
;
449 int_enable
|= SPI_ENGINE_INT_SYNC
;
451 writel_relaxed(int_enable
,
452 spi_engine
->base
+ SPI_ENGINE_REG_INT_ENABLE
);
453 spi_engine
->int_enable
= int_enable
;
454 spin_unlock_irqrestore(&spi_engine
->lock
, flags
);
459 static int spi_engine_probe(struct platform_device
*pdev
)
461 struct spi_engine
*spi_engine
;
462 struct spi_master
*master
;
463 unsigned int version
;
464 struct resource
*res
;
468 irq
= platform_get_irq(pdev
, 0);
472 spi_engine
= devm_kzalloc(&pdev
->dev
, sizeof(*spi_engine
), GFP_KERNEL
);
476 master
= spi_alloc_master(&pdev
->dev
, 0);
480 spi_master_set_devdata(master
, spi_engine
);
482 spin_lock_init(&spi_engine
->lock
);
484 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
485 spi_engine
->base
= devm_ioremap_resource(&pdev
->dev
, res
);
486 if (IS_ERR(spi_engine
->base
)) {
487 ret
= PTR_ERR(spi_engine
->base
);
491 version
= readl(spi_engine
->base
+ SPI_ENGINE_REG_VERSION
);
492 if (SPI_ENGINE_VERSION_MAJOR(version
) != 1) {
493 dev_err(&pdev
->dev
, "Unsupported peripheral version %u.%u.%c\n",
494 SPI_ENGINE_VERSION_MAJOR(version
),
495 SPI_ENGINE_VERSION_MINOR(version
),
496 SPI_ENGINE_VERSION_PATCH(version
));
500 spi_engine
->clk
= devm_clk_get(&pdev
->dev
, "s_axi_aclk");
501 if (IS_ERR(spi_engine
->clk
)) {
502 ret
= PTR_ERR(spi_engine
->clk
);
506 spi_engine
->ref_clk
= devm_clk_get(&pdev
->dev
, "spi_clk");
507 if (IS_ERR(spi_engine
->ref_clk
)) {
508 ret
= PTR_ERR(spi_engine
->ref_clk
);
512 ret
= clk_prepare_enable(spi_engine
->clk
);
516 ret
= clk_prepare_enable(spi_engine
->ref_clk
);
518 goto err_clk_disable
;
520 writel_relaxed(0x00, spi_engine
->base
+ SPI_ENGINE_REG_RESET
);
521 writel_relaxed(0xff, spi_engine
->base
+ SPI_ENGINE_REG_INT_PENDING
);
522 writel_relaxed(0x00, spi_engine
->base
+ SPI_ENGINE_REG_INT_ENABLE
);
524 ret
= request_irq(irq
, spi_engine_irq
, 0, pdev
->name
, master
);
526 goto err_ref_clk_disable
;
528 master
->dev
.of_node
= pdev
->dev
.of_node
;
529 master
->mode_bits
= SPI_CPOL
| SPI_CPHA
| SPI_3WIRE
;
530 master
->bits_per_word_mask
= SPI_BPW_MASK(8);
531 master
->max_speed_hz
= clk_get_rate(spi_engine
->ref_clk
) / 2;
532 master
->transfer_one_message
= spi_engine_transfer_one_message
;
533 master
->num_chipselect
= 8;
535 ret
= spi_register_master(master
);
539 platform_set_drvdata(pdev
, master
);
543 free_irq(irq
, master
);
545 clk_disable_unprepare(spi_engine
->ref_clk
);
547 clk_disable_unprepare(spi_engine
->clk
);
549 spi_master_put(master
);
553 static int spi_engine_remove(struct platform_device
*pdev
)
555 struct spi_master
*master
= platform_get_drvdata(pdev
);
556 struct spi_engine
*spi_engine
= spi_master_get_devdata(master
);
557 int irq
= platform_get_irq(pdev
, 0);
559 spi_unregister_master(master
);
561 free_irq(irq
, master
);
563 writel_relaxed(0xff, spi_engine
->base
+ SPI_ENGINE_REG_INT_PENDING
);
564 writel_relaxed(0x00, spi_engine
->base
+ SPI_ENGINE_REG_INT_ENABLE
);
565 writel_relaxed(0x01, spi_engine
->base
+ SPI_ENGINE_REG_RESET
);
567 clk_disable_unprepare(spi_engine
->ref_clk
);
568 clk_disable_unprepare(spi_engine
->clk
);
573 static const struct of_device_id spi_engine_match_table
[] = {
574 { .compatible
= "adi,axi-spi-engine-1.00.a" },
578 static struct platform_driver spi_engine_driver
= {
579 .probe
= spi_engine_probe
,
580 .remove
= spi_engine_remove
,
582 .name
= "spi-engine",
583 .of_match_table
= spi_engine_match_table
,
586 module_platform_driver(spi_engine_driver
);
588 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
589 MODULE_DESCRIPTION("Analog Devices SPI engine peripheral driver");
590 MODULE_LICENSE("GPL");