1 // SPDX-License-Identifier: GPL-2.0-only
3 * SPI-Engine SPI controller driver
4 * Copyright 2015 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
9 #include <linux/interrupt.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/spi/spi.h>
16 #define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff)
17 #define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff)
18 #define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff)
20 #define SPI_ENGINE_REG_VERSION 0x00
22 #define SPI_ENGINE_REG_RESET 0x40
24 #define SPI_ENGINE_REG_INT_ENABLE 0x80
25 #define SPI_ENGINE_REG_INT_PENDING 0x84
26 #define SPI_ENGINE_REG_INT_SOURCE 0x88
28 #define SPI_ENGINE_REG_SYNC_ID 0xc0
30 #define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xd0
31 #define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xd4
32 #define SPI_ENGINE_REG_SDI_FIFO_LEVEL 0xd8
34 #define SPI_ENGINE_REG_CMD_FIFO 0xe0
35 #define SPI_ENGINE_REG_SDO_DATA_FIFO 0xe4
36 #define SPI_ENGINE_REG_SDI_DATA_FIFO 0xe8
37 #define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xec
39 #define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0)
40 #define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1)
41 #define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2)
42 #define SPI_ENGINE_INT_SYNC BIT(3)
44 #define SPI_ENGINE_CONFIG_CPHA BIT(0)
45 #define SPI_ENGINE_CONFIG_CPOL BIT(1)
46 #define SPI_ENGINE_CONFIG_3WIRE BIT(2)
48 #define SPI_ENGINE_INST_TRANSFER 0x0
49 #define SPI_ENGINE_INST_ASSERT 0x1
50 #define SPI_ENGINE_INST_WRITE 0x2
51 #define SPI_ENGINE_INST_MISC 0x3
53 #define SPI_ENGINE_CMD_REG_CLK_DIV 0x0
54 #define SPI_ENGINE_CMD_REG_CONFIG 0x1
56 #define SPI_ENGINE_MISC_SYNC 0x0
57 #define SPI_ENGINE_MISC_SLEEP 0x1
59 #define SPI_ENGINE_TRANSFER_WRITE 0x1
60 #define SPI_ENGINE_TRANSFER_READ 0x2
62 #define SPI_ENGINE_CMD(inst, arg1, arg2) \
63 (((inst) << 12) | ((arg1) << 8) | (arg2))
65 #define SPI_ENGINE_CMD_TRANSFER(flags, n) \
66 SPI_ENGINE_CMD(SPI_ENGINE_INST_TRANSFER, (flags), (n))
67 #define SPI_ENGINE_CMD_ASSERT(delay, cs) \
68 SPI_ENGINE_CMD(SPI_ENGINE_INST_ASSERT, (delay), (cs))
69 #define SPI_ENGINE_CMD_WRITE(reg, val) \
70 SPI_ENGINE_CMD(SPI_ENGINE_INST_WRITE, (reg), (val))
71 #define SPI_ENGINE_CMD_SLEEP(delay) \
72 SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SLEEP, (delay))
73 #define SPI_ENGINE_CMD_SYNC(id) \
74 SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SYNC, (id))
76 struct spi_engine_program
{
78 uint16_t instructions
[];
89 struct spi_message
*msg
;
90 struct spi_engine_program
*p
;
92 const uint16_t *cmd_buf
;
94 struct spi_transfer
*tx_xfer
;
95 unsigned int tx_length
;
96 const uint8_t *tx_buf
;
98 struct spi_transfer
*rx_xfer
;
99 unsigned int rx_length
;
102 unsigned int sync_id
;
103 unsigned int completed_id
;
105 unsigned int int_enable
;
108 static void spi_engine_program_add_cmd(struct spi_engine_program
*p
,
109 bool dry
, uint16_t cmd
)
112 p
->instructions
[p
->length
] = cmd
;
116 static unsigned int spi_engine_get_config(struct spi_device
*spi
)
118 unsigned int config
= 0;
120 if (spi
->mode
& SPI_CPOL
)
121 config
|= SPI_ENGINE_CONFIG_CPOL
;
122 if (spi
->mode
& SPI_CPHA
)
123 config
|= SPI_ENGINE_CONFIG_CPHA
;
124 if (spi
->mode
& SPI_3WIRE
)
125 config
|= SPI_ENGINE_CONFIG_3WIRE
;
130 static unsigned int spi_engine_get_clk_div(struct spi_engine
*spi_engine
,
131 struct spi_device
*spi
, struct spi_transfer
*xfer
)
133 unsigned int clk_div
;
135 clk_div
= DIV_ROUND_UP(clk_get_rate(spi_engine
->ref_clk
),
139 else if (clk_div
> 0)
145 static void spi_engine_gen_xfer(struct spi_engine_program
*p
, bool dry
,
146 struct spi_transfer
*xfer
)
148 unsigned int len
= xfer
->len
;
151 unsigned int n
= min(len
, 256U);
152 unsigned int flags
= 0;
155 flags
|= SPI_ENGINE_TRANSFER_WRITE
;
157 flags
|= SPI_ENGINE_TRANSFER_READ
;
159 spi_engine_program_add_cmd(p
, dry
,
160 SPI_ENGINE_CMD_TRANSFER(flags
, n
- 1));
165 static void spi_engine_gen_sleep(struct spi_engine_program
*p
, bool dry
,
166 struct spi_engine
*spi_engine
, unsigned int clk_div
, unsigned int delay
)
168 unsigned int spi_clk
= clk_get_rate(spi_engine
->ref_clk
);
174 t
= DIV_ROUND_UP(delay
* spi_clk
, (clk_div
+ 1) * 2);
176 unsigned int n
= min(t
, 256U);
178 spi_engine_program_add_cmd(p
, dry
, SPI_ENGINE_CMD_SLEEP(n
- 1));
183 static void spi_engine_gen_cs(struct spi_engine_program
*p
, bool dry
,
184 struct spi_device
*spi
, bool assert)
186 unsigned int mask
= 0xff;
189 mask
^= BIT(spi
->chip_select
);
191 spi_engine_program_add_cmd(p
, dry
, SPI_ENGINE_CMD_ASSERT(1, mask
));
194 static int spi_engine_compile_message(struct spi_engine
*spi_engine
,
195 struct spi_message
*msg
, bool dry
, struct spi_engine_program
*p
)
197 struct spi_device
*spi
= msg
->spi
;
198 struct spi_transfer
*xfer
;
199 int clk_div
, new_clk_div
;
200 bool cs_change
= true;
204 spi_engine_program_add_cmd(p
, dry
,
205 SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CONFIG
,
206 spi_engine_get_config(spi
)));
208 list_for_each_entry(xfer
, &msg
->transfers
, transfer_list
) {
209 new_clk_div
= spi_engine_get_clk_div(spi_engine
, spi
, xfer
);
210 if (new_clk_div
!= clk_div
) {
211 clk_div
= new_clk_div
;
212 spi_engine_program_add_cmd(p
, dry
,
213 SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CLK_DIV
,
218 spi_engine_gen_cs(p
, dry
, spi
, true);
220 spi_engine_gen_xfer(p
, dry
, xfer
);
221 spi_engine_gen_sleep(p
, dry
, spi_engine
, clk_div
,
224 cs_change
= xfer
->cs_change
;
225 if (list_is_last(&xfer
->transfer_list
, &msg
->transfers
))
226 cs_change
= !cs_change
;
229 spi_engine_gen_cs(p
, dry
, spi
, false);
235 static void spi_engine_xfer_next(struct spi_engine
*spi_engine
,
236 struct spi_transfer
**_xfer
)
238 struct spi_message
*msg
= spi_engine
->msg
;
239 struct spi_transfer
*xfer
= *_xfer
;
242 xfer
= list_first_entry(&msg
->transfers
,
243 struct spi_transfer
, transfer_list
);
244 } else if (list_is_last(&xfer
->transfer_list
, &msg
->transfers
)) {
247 xfer
= list_next_entry(xfer
, transfer_list
);
253 static void spi_engine_tx_next(struct spi_engine
*spi_engine
)
255 struct spi_transfer
*xfer
= spi_engine
->tx_xfer
;
258 spi_engine_xfer_next(spi_engine
, &xfer
);
259 } while (xfer
&& !xfer
->tx_buf
);
261 spi_engine
->tx_xfer
= xfer
;
263 spi_engine
->tx_length
= xfer
->len
;
264 spi_engine
->tx_buf
= xfer
->tx_buf
;
266 spi_engine
->tx_buf
= NULL
;
270 static void spi_engine_rx_next(struct spi_engine
*spi_engine
)
272 struct spi_transfer
*xfer
= spi_engine
->rx_xfer
;
275 spi_engine_xfer_next(spi_engine
, &xfer
);
276 } while (xfer
&& !xfer
->rx_buf
);
278 spi_engine
->rx_xfer
= xfer
;
280 spi_engine
->rx_length
= xfer
->len
;
281 spi_engine
->rx_buf
= xfer
->rx_buf
;
283 spi_engine
->rx_buf
= NULL
;
287 static bool spi_engine_write_cmd_fifo(struct spi_engine
*spi_engine
)
289 void __iomem
*addr
= spi_engine
->base
+ SPI_ENGINE_REG_CMD_FIFO
;
290 unsigned int n
, m
, i
;
293 n
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_CMD_FIFO_ROOM
);
294 while (n
&& spi_engine
->cmd_length
) {
295 m
= min(n
, spi_engine
->cmd_length
);
296 buf
= spi_engine
->cmd_buf
;
297 for (i
= 0; i
< m
; i
++)
298 writel_relaxed(buf
[i
], addr
);
299 spi_engine
->cmd_buf
+= m
;
300 spi_engine
->cmd_length
-= m
;
304 return spi_engine
->cmd_length
!= 0;
307 static bool spi_engine_write_tx_fifo(struct spi_engine
*spi_engine
)
309 void __iomem
*addr
= spi_engine
->base
+ SPI_ENGINE_REG_SDO_DATA_FIFO
;
310 unsigned int n
, m
, i
;
313 n
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_SDO_FIFO_ROOM
);
314 while (n
&& spi_engine
->tx_length
) {
315 m
= min(n
, spi_engine
->tx_length
);
316 buf
= spi_engine
->tx_buf
;
317 for (i
= 0; i
< m
; i
++)
318 writel_relaxed(buf
[i
], addr
);
319 spi_engine
->tx_buf
+= m
;
320 spi_engine
->tx_length
-= m
;
322 if (spi_engine
->tx_length
== 0)
323 spi_engine_tx_next(spi_engine
);
326 return spi_engine
->tx_length
!= 0;
329 static bool spi_engine_read_rx_fifo(struct spi_engine
*spi_engine
)
331 void __iomem
*addr
= spi_engine
->base
+ SPI_ENGINE_REG_SDI_DATA_FIFO
;
332 unsigned int n
, m
, i
;
335 n
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_SDI_FIFO_LEVEL
);
336 while (n
&& spi_engine
->rx_length
) {
337 m
= min(n
, spi_engine
->rx_length
);
338 buf
= spi_engine
->rx_buf
;
339 for (i
= 0; i
< m
; i
++)
340 buf
[i
] = readl_relaxed(addr
);
341 spi_engine
->rx_buf
+= m
;
342 spi_engine
->rx_length
-= m
;
344 if (spi_engine
->rx_length
== 0)
345 spi_engine_rx_next(spi_engine
);
348 return spi_engine
->rx_length
!= 0;
351 static irqreturn_t
spi_engine_irq(int irq
, void *devid
)
353 struct spi_master
*master
= devid
;
354 struct spi_engine
*spi_engine
= spi_master_get_devdata(master
);
355 unsigned int disable_int
= 0;
356 unsigned int pending
;
358 pending
= readl_relaxed(spi_engine
->base
+ SPI_ENGINE_REG_INT_PENDING
);
360 if (pending
& SPI_ENGINE_INT_SYNC
) {
361 writel_relaxed(SPI_ENGINE_INT_SYNC
,
362 spi_engine
->base
+ SPI_ENGINE_REG_INT_PENDING
);
363 spi_engine
->completed_id
= readl_relaxed(
364 spi_engine
->base
+ SPI_ENGINE_REG_SYNC_ID
);
367 spin_lock(&spi_engine
->lock
);
369 if (pending
& SPI_ENGINE_INT_CMD_ALMOST_EMPTY
) {
370 if (!spi_engine_write_cmd_fifo(spi_engine
))
371 disable_int
|= SPI_ENGINE_INT_CMD_ALMOST_EMPTY
;
374 if (pending
& SPI_ENGINE_INT_SDO_ALMOST_EMPTY
) {
375 if (!spi_engine_write_tx_fifo(spi_engine
))
376 disable_int
|= SPI_ENGINE_INT_SDO_ALMOST_EMPTY
;
379 if (pending
& (SPI_ENGINE_INT_SDI_ALMOST_FULL
| SPI_ENGINE_INT_SYNC
)) {
380 if (!spi_engine_read_rx_fifo(spi_engine
))
381 disable_int
|= SPI_ENGINE_INT_SDI_ALMOST_FULL
;
384 if (pending
& SPI_ENGINE_INT_SYNC
) {
385 if (spi_engine
->msg
&&
386 spi_engine
->completed_id
== spi_engine
->sync_id
) {
387 struct spi_message
*msg
= spi_engine
->msg
;
389 kfree(spi_engine
->p
);
391 msg
->actual_length
= msg
->frame_length
;
392 spi_engine
->msg
= NULL
;
393 spi_finalize_current_message(master
);
394 disable_int
|= SPI_ENGINE_INT_SYNC
;
399 spi_engine
->int_enable
&= ~disable_int
;
400 writel_relaxed(spi_engine
->int_enable
,
401 spi_engine
->base
+ SPI_ENGINE_REG_INT_ENABLE
);
404 spin_unlock(&spi_engine
->lock
);
409 static int spi_engine_transfer_one_message(struct spi_master
*master
,
410 struct spi_message
*msg
)
412 struct spi_engine_program p_dry
, *p
;
413 struct spi_engine
*spi_engine
= spi_master_get_devdata(master
);
414 unsigned int int_enable
= 0;
419 spi_engine_compile_message(spi_engine
, msg
, true, &p_dry
);
421 size
= sizeof(*p
->instructions
) * (p_dry
.length
+ 1);
422 p
= kzalloc(sizeof(*p
) + size
, GFP_KERNEL
);
425 spi_engine_compile_message(spi_engine
, msg
, false, p
);
427 spin_lock_irqsave(&spi_engine
->lock
, flags
);
428 spi_engine
->sync_id
= (spi_engine
->sync_id
+ 1) & 0xff;
429 spi_engine_program_add_cmd(p
, false,
430 SPI_ENGINE_CMD_SYNC(spi_engine
->sync_id
));
432 spi_engine
->msg
= msg
;
435 spi_engine
->cmd_buf
= p
->instructions
;
436 spi_engine
->cmd_length
= p
->length
;
437 if (spi_engine_write_cmd_fifo(spi_engine
))
438 int_enable
|= SPI_ENGINE_INT_CMD_ALMOST_EMPTY
;
440 spi_engine_tx_next(spi_engine
);
441 if (spi_engine_write_tx_fifo(spi_engine
))
442 int_enable
|= SPI_ENGINE_INT_SDO_ALMOST_EMPTY
;
444 spi_engine_rx_next(spi_engine
);
445 if (spi_engine
->rx_length
!= 0)
446 int_enable
|= SPI_ENGINE_INT_SDI_ALMOST_FULL
;
448 int_enable
|= SPI_ENGINE_INT_SYNC
;
450 writel_relaxed(int_enable
,
451 spi_engine
->base
+ SPI_ENGINE_REG_INT_ENABLE
);
452 spi_engine
->int_enable
= int_enable
;
453 spin_unlock_irqrestore(&spi_engine
->lock
, flags
);
458 static int spi_engine_probe(struct platform_device
*pdev
)
460 struct spi_engine
*spi_engine
;
461 struct spi_master
*master
;
462 unsigned int version
;
466 irq
= platform_get_irq(pdev
, 0);
470 spi_engine
= devm_kzalloc(&pdev
->dev
, sizeof(*spi_engine
), GFP_KERNEL
);
474 master
= spi_alloc_master(&pdev
->dev
, 0);
478 spi_master_set_devdata(master
, spi_engine
);
480 spin_lock_init(&spi_engine
->lock
);
482 spi_engine
->base
= devm_platform_ioremap_resource(pdev
, 0);
483 if (IS_ERR(spi_engine
->base
)) {
484 ret
= PTR_ERR(spi_engine
->base
);
488 version
= readl(spi_engine
->base
+ SPI_ENGINE_REG_VERSION
);
489 if (SPI_ENGINE_VERSION_MAJOR(version
) != 1) {
490 dev_err(&pdev
->dev
, "Unsupported peripheral version %u.%u.%c\n",
491 SPI_ENGINE_VERSION_MAJOR(version
),
492 SPI_ENGINE_VERSION_MINOR(version
),
493 SPI_ENGINE_VERSION_PATCH(version
));
498 spi_engine
->clk
= devm_clk_get(&pdev
->dev
, "s_axi_aclk");
499 if (IS_ERR(spi_engine
->clk
)) {
500 ret
= PTR_ERR(spi_engine
->clk
);
504 spi_engine
->ref_clk
= devm_clk_get(&pdev
->dev
, "spi_clk");
505 if (IS_ERR(spi_engine
->ref_clk
)) {
506 ret
= PTR_ERR(spi_engine
->ref_clk
);
510 ret
= clk_prepare_enable(spi_engine
->clk
);
514 ret
= clk_prepare_enable(spi_engine
->ref_clk
);
516 goto err_clk_disable
;
518 writel_relaxed(0x00, spi_engine
->base
+ SPI_ENGINE_REG_RESET
);
519 writel_relaxed(0xff, spi_engine
->base
+ SPI_ENGINE_REG_INT_PENDING
);
520 writel_relaxed(0x00, spi_engine
->base
+ SPI_ENGINE_REG_INT_ENABLE
);
522 ret
= request_irq(irq
, spi_engine_irq
, 0, pdev
->name
, master
);
524 goto err_ref_clk_disable
;
526 master
->dev
.of_node
= pdev
->dev
.of_node
;
527 master
->mode_bits
= SPI_CPOL
| SPI_CPHA
| SPI_3WIRE
;
528 master
->bits_per_word_mask
= SPI_BPW_MASK(8);
529 master
->max_speed_hz
= clk_get_rate(spi_engine
->ref_clk
) / 2;
530 master
->transfer_one_message
= spi_engine_transfer_one_message
;
531 master
->num_chipselect
= 8;
533 ret
= spi_register_master(master
);
537 platform_set_drvdata(pdev
, master
);
541 free_irq(irq
, master
);
543 clk_disable_unprepare(spi_engine
->ref_clk
);
545 clk_disable_unprepare(spi_engine
->clk
);
547 spi_master_put(master
);
551 static int spi_engine_remove(struct platform_device
*pdev
)
553 struct spi_master
*master
= spi_master_get(platform_get_drvdata(pdev
));
554 struct spi_engine
*spi_engine
= spi_master_get_devdata(master
);
555 int irq
= platform_get_irq(pdev
, 0);
557 spi_unregister_master(master
);
559 free_irq(irq
, master
);
561 spi_master_put(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" },
577 MODULE_DEVICE_TABLE(of
, spi_engine_match_table
);
579 static struct platform_driver spi_engine_driver
= {
580 .probe
= spi_engine_probe
,
581 .remove
= spi_engine_remove
,
583 .name
= "spi-engine",
584 .of_match_table
= spi_engine_match_table
,
587 module_platform_driver(spi_engine_driver
);
589 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
590 MODULE_DESCRIPTION("Analog Devices SPI engine peripheral driver");
591 MODULE_LICENSE("GPL");