xref: /rk3399_rockchip-uboot/drivers/spi/rockchip_sfc.c (revision 5c47e3d4734d329f41880f3b6ccf76f598763980)
1 /*
2  * SFC driver for rockchip
3  *
4  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
5  * Yifeng.zhao, Software Engineering, <zhao0116@gmail.com>.
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <bouncebuf.h>
12 #include <clk.h>
13 #include <dm.h>
14 #include <dt-structs.h>
15 #include <errno.h>
16 #include <spi.h>
17 #include <linux/errno.h>
18 #include <asm/io.h>
19 #include <asm/arch/clock.h>
20 #include <asm/arch/periph.h>
21 #include <dm/pinctrl.h>
22 
23 DECLARE_GLOBAL_DATA_PTR;
24 
25 struct rockchip_sfc_reg {
26 	u32 ctrl;
27 	u32 imr;
28 	u32 iclr;
29 	u32 ftlr;
30 	u32 rcvr;
31 	u32 ax;
32 	u32 abit;
33 	u32 isr;
34 	u32 fsr;
35 	u32 sr;
36 	u32 risr;
37 	u32 reserved[21];
38 	u32 dmatr;
39 	u32 dmaaddr;
40 	u32 reserved1[30];
41 	u32 cmd;
42 	u32 addr;
43 	u32 data;
44 };
45 check_member(rockchip_sfc_reg, data, 0x108);
46 
47 /*SFC_CTRL*/
48 #define SFC_DATA_WIDTH_SHIFT	12
49 #define SFC_DATA_WIDTH_MASK	GENMASK(13, 12)
50 #define SFC_ADDR_WIDTH_SHIFT	10
51 #define SFC_ADDR_WIDTH_MASK	GENMASK(11, 10)
52 #define SFC_CMD_WIDTH_SHIFT	8
53 #define SFC_CMD_WIDTH_MASK	GENMASK(9, 8)
54 #define SFC_DATA_SHIFT_NEGETIVE	BIT(1)
55 
56 /*SFC_CMD*/
57 #define SFC_DUMMY_BITS_SHIFT	8
58 #define SFC_RW_SHIFT		12
59 #define SFC_WR			1
60 #define SFC_RD			0
61 #define SFC_ADDR_BITS_SHIFT	14
62 #define SFC_ADDR_BITS_MASK	GENMASK(15, 14)
63 #define SFC_ADDR_0BITS		0
64 #define SFC_ADDR_24BITS		1
65 #define SFC_ADDR_32BITS		2
66 #define SFC_ADDR_XBITS		3
67 #define SFC_TRB_SHIFT		(16)
68 #define SFC_TRB_MASK		GENMASK(29, 16)
69 
70 /* Dma start trigger signal. Auto cleared after write */
71 #define SFC_DMA_START		BIT(0)
72 
73 #define SFC_RESET		BIT(0)
74 
75 /*SFC_FSR*/
76 #define SFC_RXLV_SHIFT		(16)
77 #define SFC_RXLV_MASK		GENMASK(20, 16)
78 #define SFC_TXLV_SHIFT		(8)
79 #define SFC_TXLV_MASK		GENMASK(12, 8)
80 #define SFC_RX_FULL		BIT(3)	/* rx fifo full */
81 #define SFC_RX_EMPTY		BIT(2)	/* rx fifo empty */
82 #define SFC_TX_EMPTY		BIT(1)	/* tx fifo empty */
83 #define SFC_TX_FULL		BIT(0)	/* tx fifo full */
84 
85 #define SFC_BUSY		BIT(0)	/* sfc busy flag */
86 
87 /*SFC_RISR*/
88 #define DMA_FINISH_INT		BIT(7)        /* dma interrupt */
89 #define SPI_ERR_INT		BIT(6)        /* Nspi error interrupt */
90 #define AHB_ERR_INT		BIT(5)        /* Ahb bus error interrupt */
91 #define TRANS_FINISH_INT	BIT(4)        /* Transfer finish interrupt */
92 #define TX_EMPTY_INT		BIT(3)        /* Tx fifo empty interrupt */
93 #define TX_OF_INT		BIT(2)        /* Tx fifo overflow interrupt */
94 #define RX_UF_INT		BIT(1)        /* Rx fifo underflow interrupt */
95 #define RX_FULL_INT		BIT(0)        /* Rx fifo full interrupt */
96 
97 #define SFC_MAX_TRB		(512 * 31)
98 
99 enum rockchip_sfc_if_type {
100 	IF_TYPE_STD,
101 	IF_TYPE_DUAL,
102 	IF_TYPE_QUAD,
103 };
104 
105 struct rockchip_sfc_platdata {
106 	s32 frequency;
107 	fdt_addr_t base;
108 };
109 
110 struct rockchip_sfc {
111 	struct rockchip_sfc_reg *regbase;
112 	struct clk clk;
113 	unsigned int max_freq;
114 	unsigned int mode;
115 	unsigned int speed_hz;
116 	u32 cmd;
117 	u32 addr;
118 	u8 addr_bits;
119 	u8 dummy_bits;
120 	u8 rw;
121 	u32 trb;
122 };
123 
124 static int rockchip_sfc_ofdata_to_platdata(struct udevice *bus)
125 {
126 	struct rockchip_sfc_platdata *plat = dev_get_platdata(bus);
127 	struct rockchip_sfc *sfc = dev_get_priv(bus);
128 	const void *blob = gd->fdt_blob;
129 	int node = dev_of_offset(bus);
130 	int subnode;
131 	int ret;
132 
133 	plat->base = devfdt_get_addr(bus);
134 
135 	ret = clk_get_by_index(bus, 0, &sfc->clk);
136 	if (ret < 0) {
137 		debug("Could not get clock for %s: %d\n", bus->name, ret);
138 		return ret;
139 	}
140 
141 	subnode = fdt_first_subnode(blob, node);
142 	if (subnode < 0) {
143 		debug("Error: subnode with SPI flash config missing!\n");
144 		return -ENODEV;
145 	}
146 
147 	plat->frequency = fdtdec_get_int(blob, subnode, "spi-max-frequency",
148 					 100000000);
149 
150 	return 0;
151 }
152 
153 static int rockchip_sfc_probe(struct udevice *bus)
154 {
155 	struct rockchip_sfc_platdata *plat = dev_get_platdata(bus);
156 	struct rockchip_sfc *sfc = dev_get_priv(bus);
157 	int ret;
158 
159 	sfc->regbase = (struct rockchip_sfc_reg *)plat->base;
160 
161 	sfc->max_freq = plat->frequency;
162 
163 	ret = clk_set_rate(&sfc->clk, sfc->max_freq);
164 	if (ret < 0) {
165 		debug("%s: Failed to set clock: %d\n", __func__, ret);
166 		return ret;
167 	}
168 
169 	return 0;
170 }
171 
172 static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
173 {
174 	struct rockchip_sfc_reg *regs = sfc->regbase;
175 	int tbase = get_timer(0);
176 	u32 rcvr;
177 	int ret = 0;
178 
179 	writel(SFC_RESET, &regs->rcvr);
180 	do {
181 		rcvr = readl(&regs->rcvr);
182 		if (get_timer(tbase) > 1000) {
183 			debug("sfc reset timeout\n");
184 			ret =  -ETIMEDOUT;
185 			break;
186 		}
187 		udelay(1);
188 	} while (rcvr);
189 
190 	writel(0xFFFFFFFF, &regs->iclr);
191 
192 	debug("sfc reset\n");
193 
194 	return ret;
195 }
196 
197 /* The SFC_CTRL register is a global control register,
198  * when the controller is in busy state(SFC_SR),
199  * SFC_CTRL cannot be set.
200  */
201 static int rockchip_sfc_wait_idle(struct rockchip_sfc *sfc,
202                                   u32 timeout_ms)
203 {
204 	struct rockchip_sfc_reg *regs = sfc->regbase;
205 	unsigned long tbase = get_timer(0);
206 	u32 sr, fsr;
207 
208 	while (1) {
209 		sr = readl(&regs->sr);
210 		fsr = readl(&regs->fsr);
211 		if ((fsr & SFC_TX_EMPTY) && (fsr & SFC_RX_EMPTY) && !(sr & SFC_BUSY))
212 			break;
213 		if (get_timer(tbase) > timeout_ms) {
214 			printf("waite sfc idle timeout(sr:0x%08x fsr:0x%08x)\n",
215 				sr, fsr);
216 			rockchip_sfc_reset(sfc);
217 			return -ETIMEDOUT;
218 		}
219 		udelay(100);
220 	}
221 
222 	return 0;
223 }
224 
225 static u8 rockchip_sfc_get_if_type(struct rockchip_sfc *sfc)
226 {
227 	int type = IF_TYPE_STD;
228 
229 	if (sfc->rw == SFC_WR) {
230 		if (sfc->mode & SPI_TX_QUAD)
231 			type = IF_TYPE_QUAD;
232 		else if (sfc->mode & SPI_TX_DUAL)
233 			type = IF_TYPE_DUAL;
234 		else
235 			type = IF_TYPE_STD;
236 	} else {
237 		if (sfc->mode & SPI_RX_QUAD)
238 			type = IF_TYPE_QUAD;
239 		else if (sfc->mode & SPI_RX_DUAL)
240 			type = IF_TYPE_DUAL;
241 		else
242 			type = IF_TYPE_STD;
243 	}
244 
245 	return type;
246 }
247 
248 static void rockchip_sfc_setup_xfer(struct rockchip_sfc *sfc, u32 trb)
249 {
250 	struct rockchip_sfc_reg *regs = sfc->regbase;
251 	u32 val = 0x02;
252 	u8 data_width = IF_TYPE_STD;
253 
254 	if (sfc->addr_bits & SFC_ADDR_XBITS)
255 		data_width = rockchip_sfc_get_if_type(sfc);
256 
257 	val |= (data_width << SFC_DATA_WIDTH_SHIFT);
258 
259 	rockchip_sfc_wait_idle(sfc, 10);
260 
261 	writel(val, &regs->ctrl);
262 
263 	val = sfc->cmd;
264 	val |= trb << SFC_TRB_SHIFT;
265 	val |= sfc->rw << SFC_RW_SHIFT;
266 	val |= sfc->addr_bits << SFC_ADDR_BITS_SHIFT;
267 	val |= sfc->dummy_bits << SFC_DUMMY_BITS_SHIFT;
268 
269 	writel(val, &regs->cmd);
270 
271 	if (sfc->addr_bits & SFC_ADDR_XBITS)
272 		writel(sfc->addr, &regs->addr);
273 }
274 
275 static int rockchip_sfc_dma_xfer(struct rockchip_sfc *sfc, void *buffer, size_t trb)
276 {
277 	struct rockchip_sfc_reg *regs = sfc->regbase;
278 	struct bounce_buffer bb;
279 	unsigned int bb_flags;
280 	int timeout = 1000;
281 	int ret = 0;
282 	int risr;
283 	unsigned long tbase;
284 
285 	if (sfc->rw == SFC_WR)
286 		bb_flags = GEN_BB_READ;
287 	else
288 		bb_flags = GEN_BB_WRITE;
289 
290 	ret = bounce_buffer_start(&bb, buffer, trb, bb_flags);
291 	if (ret)
292 		return ret;
293 
294 	rockchip_sfc_setup_xfer(sfc, bb.len_aligned);
295 
296 	writel(0xFFFFFFFF, &regs->iclr);
297 	writel((u32)bb.bounce_buffer, &regs->dmaaddr);
298 	writel(SFC_DMA_START, &regs->dmatr);
299 
300 	tbase = get_timer(0);
301 	do {
302 		udelay(1);
303 		risr = readl(&regs->risr);
304 		if (get_timer(tbase) > timeout) {
305 			debug("dma timeout\n");
306 			ret = -ETIMEDOUT;
307 			break;
308 		}
309 	} while (!(risr & TRANS_FINISH_INT));
310 
311 	writel(0xFFFFFFFF, &regs->iclr);
312 
313 	bounce_buffer_stop(&bb);
314 
315 	return ret;
316 }
317 
318 static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int rw,
319 					u32 timeout)
320 {
321 	struct rockchip_sfc_reg *regs = sfc->regbase;
322 	unsigned long tbase = get_timer(0);
323 	u8 level;
324 	u32 fsr;
325 
326 	do {
327 		fsr = readl(&regs->fsr);
328 		if (rw == SFC_WR)
329 			level = (fsr & SFC_TXLV_MASK) >> SFC_TXLV_SHIFT;
330 		else
331 			level = (fsr & SFC_RXLV_MASK) >> SFC_RXLV_SHIFT;
332 		if (get_timer(tbase) > timeout)
333 			return -ETIMEDOUT;
334 		udelay(1);
335 	} while (!level);
336 
337 	return level;
338 }
339 
340 static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, u32 *buf, u32 len)
341 {
342 	struct rockchip_sfc_reg *regs = sfc->regbase;
343 	u32 bytes = len & 0x3;
344 	u32 words = len >> 2;
345 	int tx_level = 0;
346 	u32 val = 0;
347 	u8 count;
348 
349 	while (words) {
350 		tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_WR, 1000);
351 		if (tx_level <= 0)
352 			return tx_level;
353 		count = min(words, (u32)tx_level);
354 		writesl(&regs->data, buf, count);
355 		buf += count;
356 		words -= count;
357 	}
358 
359 	/* handle the last non 4byte aligned bytes */
360 	if (bytes) {
361 		tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_WR, 1000);
362 		if (tx_level <= 0)
363 			return tx_level;
364 		memcpy(&val, buf, bytes);
365 		writel(val, &regs->data);
366 	}
367 
368 	return 0;
369 }
370 
371 static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u32 *buf, u32 len)
372 {
373 	struct rockchip_sfc_reg *regs = sfc->regbase;
374 	u32 bytes = len & 0x3;
375 	u32 words = len >> 2;
376 	int rx_level = 0;
377 	u32 count;
378 	u32 val;
379 
380 	while (words) {
381 		rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_RD, 1000);
382 		if (rx_level <= 0)
383 			return rx_level;
384 		count = min(words, (u32)rx_level);
385 		readsl(&regs->data, buf, count);
386 		buf += count;
387 		words -= count;
388 	}
389 
390 	/* handle the last non 4 bytes aligned bytes */
391 	if (bytes) {
392 		rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_RD, 1000);
393 		if (rx_level <= 0)
394 			return rx_level;
395 		val = readl(&regs->data);
396 		memcpy(buf, &val, bytes);
397 	}
398 
399 	return 0;
400 }
401 
402 static int rockchip_sfc_pio_xfer(struct rockchip_sfc *sfc, void *buf, u32 len)
403 {
404 	int ret = 0;
405 
406 	rockchip_sfc_setup_xfer(sfc, len);
407 
408 	if (len) {
409 		if (sfc->rw == SFC_WR)
410 			ret = rockchip_sfc_write_fifo(sfc, (u32 *)buf, len);
411 		else
412 			ret = rockchip_sfc_read_fifo(sfc, (u32 *)buf, len);
413 	}
414 
415 	return ret;
416 }
417 
418 static int rockchip_sfc_read(struct rockchip_sfc *sfc, u32 offset,
419                              void *buf, size_t len)
420 {
421 	u32 dma_trans;
422 	u32 trb;
423 	u8 bytes;
424 	int ret;
425 
426 	if (len >= ARCH_DMA_MINALIGN) {
427 		bytes = len & (ARCH_DMA_MINALIGN - 1);
428 		dma_trans = len - bytes;
429 	} else {
430 		dma_trans = 0;
431 		bytes = len;
432 	}
433 
434 	while (dma_trans) {
435 		trb = min_t(size_t, dma_trans, SFC_MAX_TRB);
436 		ret = rockchip_sfc_dma_xfer(sfc, buf, trb);
437 		if (ret < 0)
438 			return ret;
439 		dma_trans -= trb;
440 		sfc->addr += trb;
441 		buf += trb;
442 	}
443 
444 	/*
445 	 * transfer the last non dma anligned byte by pio mode
446 	 */
447 	if (bytes)
448 		ret = rockchip_sfc_pio_xfer(sfc, buf, bytes);
449 
450 	return 0;
451 }
452 
453 static int rockchip_sfc_write(struct rockchip_sfc *sfc, u32 offset,
454                               void *buf, size_t len)
455 {
456 
457 	if (len > SFC_MAX_TRB) {
458 		printf("out of the max sfc trb");
459 		return -EINVAL;
460 	}
461 
462 	if (len && !(len & (ARCH_DMA_MINALIGN - 1)))
463 		return rockchip_sfc_dma_xfer(sfc, buf, len);
464 	else
465 		return rockchip_sfc_pio_xfer(sfc, buf,len);
466 
467 	return 0;
468 }
469 
470 static int rockchip_sfc_do_xfer(struct rockchip_sfc *sfc, void *buf, size_t len)
471 {
472 
473 	if (sfc->rw)
474 		return rockchip_sfc_write(sfc, sfc->addr, buf, len);
475 	else
476 		return rockchip_sfc_read(sfc, sfc->addr, buf, len);
477 }
478 
479 static int rockchip_sfc_xfer(struct udevice *dev, unsigned int bitlen,
480 			     const void *dout, void *din, unsigned long flags)
481 {
482 	struct udevice *bus = dev->parent;
483 	struct rockchip_sfc *sfc = dev_get_priv(bus);
484 	int len = bitlen >> 3;
485 	u8 *pcmd = (u8 *)dout;
486 	void *data_buf;
487 	int ret = 0;
488 
489 	if (flags & SPI_XFER_BEGIN) {
490 		sfc->cmd = pcmd[0];
491 		if (len >= 4) {
492 			sfc->addr_bits = SFC_ADDR_24BITS;
493 			sfc->dummy_bits = (len - 4) << 3;
494 			sfc->addr = pcmd[3] | (pcmd[2] << 8) | (pcmd[1] << 16);
495 		} else {
496 			sfc->addr_bits = 0;
497 			sfc->dummy_bits = 0;
498 			sfc->addr = 0;
499 		}
500 	}
501 
502 	if (flags & SPI_XFER_END) {
503 
504 		if (din) {
505 			sfc->rw = SFC_RD;
506 			data_buf = din;
507 		} else {
508 			sfc->rw = SFC_WR;
509 			data_buf = (void *)dout;
510 		}
511 
512 		if (flags == (SPI_XFER_BEGIN | SPI_XFER_END)) {
513 			len = 0;
514 			data_buf = NULL;
515 		}
516 
517 		ret = rockchip_sfc_do_xfer(sfc, data_buf, len);
518 	}
519 
520 	return ret;
521 }
522 
523 static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)
524 {
525 	struct rockchip_sfc *sfc = dev_get_priv(bus);
526 
527 	if (speed > sfc->max_freq)
528 		speed = sfc->max_freq;
529 
530 	sfc->speed_hz = speed;
531 
532 	return 0;
533 }
534 
535 static int rockchip_sfc_set_mode(struct udevice *bus, uint mode)
536 {
537 	struct rockchip_sfc *sfc = dev_get_priv(bus);
538 
539 	sfc->mode = mode;
540 
541 	return 0;
542 }
543 
544 static const struct dm_spi_ops rockchip_sfc_ops = {
545 	.xfer		= rockchip_sfc_xfer,
546 	.set_speed	= rockchip_sfc_set_speed,
547 	.set_mode	= rockchip_sfc_set_mode,
548 };
549 
550 static const struct udevice_id rockchip_sfc_ids[] = {
551 	{ .compatible = "rockchip,sfc" },
552 	{ }
553 };
554 
555 U_BOOT_DRIVER(rockchip_sfc_driver) = {
556 	.name	= "rockchip_sfc",
557 	.id	= UCLASS_SPI,
558 	.of_match = rockchip_sfc_ids,
559 	.ops	= &rockchip_sfc_ops,
560 	.ofdata_to_platdata = rockchip_sfc_ofdata_to_platdata,
561 	.platdata_auto_alloc_size = sizeof(struct rockchip_sfc_platdata),
562 	.priv_auto_alloc_size = sizeof(struct rockchip_sfc),
563 	.probe	= rockchip_sfc_probe,
564 };
565