xref: /linux/drivers/spi/spi-axi-spi-engine.c (revision be709d48329a500621d2a05835283150ae137b45)
1 /*
2  * SPI-Engine SPI controller driver
3  * Copyright 2015 Analog Devices Inc.
4  *  Author: Lars-Peter Clausen <lars@metafoo.de>
5  *
6  * Licensed under the GPL-2.
7  */
8 
9 #include <linux/clk.h>
10 #include <linux/interrupt.h>
11 #include <linux/io.h>
12 #include <linux/of.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/spi/spi.h>
16 
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)
20 
21 #define SPI_ENGINE_REG_VERSION			0x00
22 
23 #define SPI_ENGINE_REG_RESET			0x40
24 
25 #define SPI_ENGINE_REG_INT_ENABLE		0x80
26 #define SPI_ENGINE_REG_INT_PENDING		0x84
27 #define SPI_ENGINE_REG_INT_SOURCE		0x88
28 
29 #define SPI_ENGINE_REG_SYNC_ID			0xc0
30 
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
34 
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
39 
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)
44 
45 #define SPI_ENGINE_CONFIG_CPHA			BIT(0)
46 #define SPI_ENGINE_CONFIG_CPOL			BIT(1)
47 #define SPI_ENGINE_CONFIG_3WIRE			BIT(2)
48 
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
53 
54 #define SPI_ENGINE_CMD_REG_CLK_DIV		0x0
55 #define SPI_ENGINE_CMD_REG_CONFIG		0x1
56 
57 #define SPI_ENGINE_MISC_SYNC			0x0
58 #define SPI_ENGINE_MISC_SLEEP			0x1
59 
60 #define SPI_ENGINE_TRANSFER_WRITE		0x1
61 #define SPI_ENGINE_TRANSFER_READ		0x2
62 
63 #define SPI_ENGINE_CMD(inst, arg1, arg2) \
64 	(((inst) << 12) | ((arg1) << 8) | (arg2))
65 
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))
76 
77 struct spi_engine_program {
78 	unsigned int length;
79 	uint16_t instructions[];
80 };
81 
82 struct spi_engine {
83 	struct clk *clk;
84 	struct clk *ref_clk;
85 
86 	spinlock_t lock;
87 
88 	void __iomem *base;
89 
90 	struct spi_message *msg;
91 	struct spi_engine_program *p;
92 	unsigned cmd_length;
93 	const uint16_t *cmd_buf;
94 
95 	struct spi_transfer *tx_xfer;
96 	unsigned int tx_length;
97 	const uint8_t *tx_buf;
98 
99 	struct spi_transfer *rx_xfer;
100 	unsigned int rx_length;
101 	uint8_t *rx_buf;
102 
103 	unsigned int sync_id;
104 	unsigned int completed_id;
105 
106 	unsigned int int_enable;
107 };
108 
109 static void spi_engine_program_add_cmd(struct spi_engine_program *p,
110 	bool dry, uint16_t cmd)
111 {
112 	if (!dry)
113 		p->instructions[p->length] = cmd;
114 	p->length++;
115 }
116 
117 static unsigned int spi_engine_get_config(struct spi_device *spi)
118 {
119 	unsigned int config = 0;
120 
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;
127 
128 	return config;
129 }
130 
131 static unsigned int spi_engine_get_clk_div(struct spi_engine *spi_engine,
132 	struct spi_device *spi, struct spi_transfer *xfer)
133 {
134 	unsigned int clk_div;
135 
136 	clk_div = DIV_ROUND_UP(clk_get_rate(spi_engine->ref_clk),
137 		xfer->speed_hz * 2);
138 	if (clk_div > 255)
139 		clk_div = 255;
140 	else if (clk_div > 0)
141 		clk_div -= 1;
142 
143 	return clk_div;
144 }
145 
146 static void spi_engine_gen_xfer(struct spi_engine_program *p, bool dry,
147 	struct spi_transfer *xfer)
148 {
149 	unsigned int len = xfer->len;
150 
151 	while (len) {
152 		unsigned int n = min(len, 256U);
153 		unsigned int flags = 0;
154 
155 		if (xfer->tx_buf)
156 			flags |= SPI_ENGINE_TRANSFER_WRITE;
157 		if (xfer->rx_buf)
158 			flags |= SPI_ENGINE_TRANSFER_READ;
159 
160 		spi_engine_program_add_cmd(p, dry,
161 			SPI_ENGINE_CMD_TRANSFER(flags, n - 1));
162 		len -= n;
163 	}
164 }
165 
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)
168 {
169 	unsigned int spi_clk = clk_get_rate(spi_engine->ref_clk);
170 	unsigned int t;
171 
172 	if (delay == 0)
173 		return;
174 
175 	t = DIV_ROUND_UP(delay * spi_clk, (clk_div + 1) * 2);
176 	while (t) {
177 		unsigned int n = min(t, 256U);
178 
179 		spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_SLEEP(n - 1));
180 		t -= n;
181 	}
182 }
183 
184 static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry,
185 		struct spi_device *spi, bool assert)
186 {
187 	unsigned int mask = 0xff;
188 
189 	if (assert)
190 		mask ^= BIT(spi->chip_select);
191 
192 	spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_ASSERT(1, mask));
193 }
194 
195 static int spi_engine_compile_message(struct spi_engine *spi_engine,
196 	struct spi_message *msg, bool dry, struct spi_engine_program *p)
197 {
198 	struct spi_device *spi = msg->spi;
199 	struct spi_transfer *xfer;
200 	int clk_div, new_clk_div;
201 	bool cs_change = true;
202 
203 	clk_div = -1;
204 
205 	spi_engine_program_add_cmd(p, dry,
206 		SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CONFIG,
207 			spi_engine_get_config(spi)));
208 
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,
215 					clk_div));
216 		}
217 
218 		if (cs_change)
219 			spi_engine_gen_cs(p, dry, spi, true);
220 
221 		spi_engine_gen_xfer(p, dry, xfer);
222 		spi_engine_gen_sleep(p, dry, spi_engine, clk_div,
223 			xfer->delay_usecs);
224 
225 		cs_change = xfer->cs_change;
226 		if (list_is_last(&xfer->transfer_list, &msg->transfers))
227 			cs_change = !cs_change;
228 
229 		if (cs_change)
230 			spi_engine_gen_cs(p, dry, spi, false);
231 	}
232 
233 	return 0;
234 }
235 
236 static void spi_engine_xfer_next(struct spi_engine *spi_engine,
237 	struct spi_transfer **_xfer)
238 {
239 	struct spi_message *msg = spi_engine->msg;
240 	struct spi_transfer *xfer = *_xfer;
241 
242 	if (!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)) {
246 		xfer = NULL;
247 	} else {
248 		xfer = list_next_entry(xfer, transfer_list);
249 	}
250 
251 	*_xfer = xfer;
252 }
253 
254 static void spi_engine_tx_next(struct spi_engine *spi_engine)
255 {
256 	struct spi_transfer *xfer = spi_engine->tx_xfer;
257 
258 	do {
259 		spi_engine_xfer_next(spi_engine, &xfer);
260 	} while (xfer && !xfer->tx_buf);
261 
262 	spi_engine->tx_xfer = xfer;
263 	if (xfer) {
264 		spi_engine->tx_length = xfer->len;
265 		spi_engine->tx_buf = xfer->tx_buf;
266 	} else {
267 		spi_engine->tx_buf = NULL;
268 	}
269 }
270 
271 static void spi_engine_rx_next(struct spi_engine *spi_engine)
272 {
273 	struct spi_transfer *xfer = spi_engine->rx_xfer;
274 
275 	do {
276 		spi_engine_xfer_next(spi_engine, &xfer);
277 	} while (xfer && !xfer->rx_buf);
278 
279 	spi_engine->rx_xfer = xfer;
280 	if (xfer) {
281 		spi_engine->rx_length = xfer->len;
282 		spi_engine->rx_buf = xfer->rx_buf;
283 	} else {
284 		spi_engine->rx_buf = NULL;
285 	}
286 }
287 
288 static bool spi_engine_write_cmd_fifo(struct spi_engine *spi_engine)
289 {
290 	void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_CMD_FIFO;
291 	unsigned int n, m, i;
292 	const uint16_t *buf;
293 
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;
302 		n -= m;
303 	}
304 
305 	return spi_engine->cmd_length != 0;
306 }
307 
308 static bool spi_engine_write_tx_fifo(struct spi_engine *spi_engine)
309 {
310 	void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDO_DATA_FIFO;
311 	unsigned int n, m, i;
312 	const uint8_t *buf;
313 
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;
322 		n -= m;
323 		if (spi_engine->tx_length == 0)
324 			spi_engine_tx_next(spi_engine);
325 	}
326 
327 	return spi_engine->tx_length != 0;
328 }
329 
330 static bool spi_engine_read_rx_fifo(struct spi_engine *spi_engine)
331 {
332 	void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDI_DATA_FIFO;
333 	unsigned int n, m, i;
334 	uint8_t *buf;
335 
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;
344 		n -= m;
345 		if (spi_engine->rx_length == 0)
346 			spi_engine_rx_next(spi_engine);
347 	}
348 
349 	return spi_engine->rx_length != 0;
350 }
351 
352 static irqreturn_t spi_engine_irq(int irq, void *devid)
353 {
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;
358 
359 	pending = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_INT_PENDING);
360 
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);
366 	}
367 
368 	spin_lock(&spi_engine->lock);
369 
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;
373 	}
374 
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;
378 	}
379 
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;
383 	}
384 
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;
389 
390 			kfree(spi_engine->p);
391 			msg->status = 0;
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;
396 		}
397 	}
398 
399 	if (disable_int) {
400 		spi_engine->int_enable &= ~disable_int;
401 		writel_relaxed(spi_engine->int_enable,
402 			spi_engine->base + SPI_ENGINE_REG_INT_ENABLE);
403 	}
404 
405 	spin_unlock(&spi_engine->lock);
406 
407 	return IRQ_HANDLED;
408 }
409 
410 static int spi_engine_transfer_one_message(struct spi_master *master,
411 	struct spi_message *msg)
412 {
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;
416 	unsigned long flags;
417 	size_t size;
418 
419 	p_dry.length = 0;
420 	spi_engine_compile_message(spi_engine, msg, true, &p_dry);
421 
422 	size = sizeof(*p->instructions) * (p_dry.length + 1);
423 	p = kzalloc(sizeof(*p) + size, GFP_KERNEL);
424 	if (!p)
425 		return -ENOMEM;
426 	spi_engine_compile_message(spi_engine, msg, false, p);
427 
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));
432 
433 	spi_engine->msg = msg;
434 	spi_engine->p = p;
435 
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;
440 
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;
444 
445 	spi_engine_rx_next(spi_engine);
446 	if (spi_engine->rx_length != 0)
447 		int_enable |= SPI_ENGINE_INT_SDI_ALMOST_FULL;
448 
449 	int_enable |= SPI_ENGINE_INT_SYNC;
450 
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);
455 
456 	return 0;
457 }
458 
459 static int spi_engine_probe(struct platform_device *pdev)
460 {
461 	struct spi_engine *spi_engine;
462 	struct spi_master *master;
463 	unsigned int version;
464 	struct resource *res;
465 	int irq;
466 	int ret;
467 
468 	irq = platform_get_irq(pdev, 0);
469 	if (irq <= 0)
470 		return -ENXIO;
471 
472 	spi_engine = devm_kzalloc(&pdev->dev, sizeof(*spi_engine), GFP_KERNEL);
473 	if (!spi_engine)
474 		return -ENOMEM;
475 
476 	master = spi_alloc_master(&pdev->dev, 0);
477 	if (!master)
478 		return -ENOMEM;
479 
480 	spi_master_set_devdata(master, spi_engine);
481 
482 	spin_lock_init(&spi_engine->lock);
483 
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);
488 		goto err_put_master;
489 	}
490 
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));
497 		ret = -ENODEV;
498 		goto err_put_master;
499 	}
500 
501 	spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
502 	if (IS_ERR(spi_engine->clk)) {
503 		ret = PTR_ERR(spi_engine->clk);
504 		goto err_put_master;
505 	}
506 
507 	spi_engine->ref_clk = devm_clk_get(&pdev->dev, "spi_clk");
508 	if (IS_ERR(spi_engine->ref_clk)) {
509 		ret = PTR_ERR(spi_engine->ref_clk);
510 		goto err_put_master;
511 	}
512 
513 	ret = clk_prepare_enable(spi_engine->clk);
514 	if (ret)
515 		goto err_put_master;
516 
517 	ret = clk_prepare_enable(spi_engine->ref_clk);
518 	if (ret)
519 		goto err_clk_disable;
520 
521 	writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET);
522 	writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING);
523 	writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE);
524 
525 	ret = request_irq(irq, spi_engine_irq, 0, pdev->name, master);
526 	if (ret)
527 		goto err_ref_clk_disable;
528 
529 	master->dev.of_node = pdev->dev.of_node;
530 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE;
531 	master->bits_per_word_mask = SPI_BPW_MASK(8);
532 	master->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2;
533 	master->transfer_one_message = spi_engine_transfer_one_message;
534 	master->num_chipselect = 8;
535 
536 	ret = spi_register_master(master);
537 	if (ret)
538 		goto err_free_irq;
539 
540 	platform_set_drvdata(pdev, master);
541 
542 	return 0;
543 err_free_irq:
544 	free_irq(irq, master);
545 err_ref_clk_disable:
546 	clk_disable_unprepare(spi_engine->ref_clk);
547 err_clk_disable:
548 	clk_disable_unprepare(spi_engine->clk);
549 err_put_master:
550 	spi_master_put(master);
551 	return ret;
552 }
553 
554 static int spi_engine_remove(struct platform_device *pdev)
555 {
556 	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
557 	struct spi_engine *spi_engine = spi_master_get_devdata(master);
558 	int irq = platform_get_irq(pdev, 0);
559 
560 	spi_unregister_master(master);
561 
562 	free_irq(irq, master);
563 
564 	spi_master_put(master);
565 
566 	writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING);
567 	writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE);
568 	writel_relaxed(0x01, spi_engine->base + SPI_ENGINE_REG_RESET);
569 
570 	clk_disable_unprepare(spi_engine->ref_clk);
571 	clk_disable_unprepare(spi_engine->clk);
572 
573 	return 0;
574 }
575 
576 static const struct of_device_id spi_engine_match_table[] = {
577 	{ .compatible = "adi,axi-spi-engine-1.00.a" },
578 	{ },
579 };
580 MODULE_DEVICE_TABLE(of, spi_engine_match_table);
581 
582 static struct platform_driver spi_engine_driver = {
583 	.probe = spi_engine_probe,
584 	.remove = spi_engine_remove,
585 	.driver = {
586 		.name = "spi-engine",
587 		.of_match_table = spi_engine_match_table,
588 	},
589 };
590 module_platform_driver(spi_engine_driver);
591 
592 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
593 MODULE_DESCRIPTION("Analog Devices SPI engine peripheral driver");
594 MODULE_LICENSE("GPL");
595