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