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