xref: /rk3399_rockchip-uboot/drivers/spi/rockchip_sfc.c (revision 5821df21ae36d9ef252d346a5abb76be773c5d69)
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 };
45 
46 static int rockchip_sfc_ofdata_to_platdata(struct udevice *bus)
47 {
48 	struct rockchip_sfc_platdata *plat = dev_get_platdata(bus);
49 	struct rockchip_sfc *sfc = dev_get_priv(bus);
50 	const void *blob = gd->fdt_blob;
51 	int node = dev_of_offset(bus);
52 	int subnode;
53 	int ret;
54 
55 	plat->base = devfdt_get_addr(bus);
56 
57 	ret = clk_get_by_index(bus, 0, &sfc->clk);
58 	if (ret < 0) {
59 		debug("Could not get clock for %s: %d\n", bus->name, ret);
60 		return ret;
61 	}
62 
63 	subnode = fdt_first_subnode(blob, node);
64 	if (subnode < 0) {
65 		debug("Error: subnode with SPI flash config missing!\n");
66 		return -ENODEV;
67 	}
68 
69 	plat->frequency = fdtdec_get_int(blob, subnode, "spi-max-frequency",
70 					 100000000);
71 
72 	return 0;
73 }
74 
75 static int rockchip_sfc_probe(struct udevice *bus)
76 {
77 	struct rockchip_sfc_platdata *plat = dev_get_platdata(bus);
78 	struct rockchip_sfc *sfc = dev_get_priv(bus);
79 	int ret;
80 
81 	sfc->regbase = (struct rockchip_sfc_reg *)plat->base;
82 
83 	sfc->max_freq = plat->frequency;
84 
85 	ret = clk_set_rate(&sfc->clk, sfc->max_freq);
86 	if (ret < 0) {
87 		debug("%s: Failed to set clock: %d\n", __func__, ret);
88 		return ret;
89 	}
90 
91 	return 0;
92 }
93 
94 static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
95 {
96 	struct rockchip_sfc_reg *regs = sfc->regbase;
97 	int tbase = get_timer(0);
98 	u32 rcvr;
99 	int ret = 0;
100 
101 	writel(SFC_RESET, &regs->rcvr);
102 	do {
103 		rcvr = readl(&regs->rcvr);
104 		if (get_timer(tbase) > 1000) {
105 			debug("sfc reset timeout\n");
106 			ret =  -ETIMEDOUT;
107 			break;
108 		}
109 		udelay(1);
110 	} while (rcvr);
111 
112 	writel(0xFFFFFFFF, &regs->iclr);
113 
114 	debug("sfc reset\n");
115 
116 	return ret;
117 }
118 
119 static u8 rockchip_sfc_get_if_type(struct rockchip_sfc *sfc)
120 {
121 	int type = IF_TYPE_STD;
122 
123 	if (sfc->cmd & SFC_WR) {
124 		if (sfc->mode & SPI_TX_QUAD)
125 			type = IF_TYPE_QUAD;
126 		else if (sfc->mode & SPI_TX_DUAL)
127 			type = IF_TYPE_DUAL;
128 		else
129 			type = IF_TYPE_STD;
130 	} else {
131 		if (sfc->mode & SPI_RX_QUAD)
132 			type = IF_TYPE_QUAD;
133 		else if (sfc->mode & SPI_RX_DUAL)
134 			type = IF_TYPE_DUAL;
135 		else
136 			type = IF_TYPE_STD;
137 	}
138 
139 	return type;
140 }
141 
142 static void rockchip_sfc_setup_xfer(struct rockchip_sfc *sfc)
143 {
144 	struct rockchip_sfc_reg *regs = sfc->regbase;
145 	u32 val = 0x02;
146 	u32 fsr = readl(&regs->fsr);
147 	u32 sr = readl(&regs->sr);
148 	u8 data_width = IF_TYPE_STD;
149 
150 	if (!(fsr & SFC_TX_EMPTY) || !(fsr & SFC_RX_EMPTY) || (sr & SFC_BUSY))
151 		rockchip_sfc_reset(sfc);
152 
153 	if (sfc->cmd & SFC_ADDR_XBITS)
154 		data_width = rockchip_sfc_get_if_type(sfc);
155 
156 	val |= (data_width << SFC_DATA_WIDTH_SHIFT);
157 
158 	writel(val, &regs->ctrl);
159 	writel(sfc->cmd, &regs->cmd);
160 	if (sfc->cmd & SFC_ADDR_XBITS)
161 		writel(sfc->addr, &regs->addr);
162 }
163 
164 static int rockchip_sfc_do_dma_xfer(struct rockchip_sfc *sfc, u32 *buffer)
165 {
166 	struct rockchip_sfc_reg *regs = sfc->regbase;
167 	int timeout = 1000;
168 	int ret = 0;
169 	int risr;
170 	unsigned long tbase;
171 
172 	rockchip_sfc_setup_xfer(sfc);
173 
174 	writel(0xFFFFFFFF, &regs->iclr);
175 	writel((u32)buffer, &regs->dmaaddr);
176 	writel(SFC_DMA_START, &regs->dmatr);
177 
178 	tbase = get_timer(0);
179 	do {
180 		udelay(1);
181 		risr = readl(&regs->risr);
182 		if (get_timer(tbase) > timeout) {
183 			debug("dma timeout\n");
184 			ret = -ETIMEDOUT;
185 			break;
186 		}
187 	} while (!(risr & TRANS_FINISH_INT));
188 
189 	writel(0xFFFFFFFF, &regs->iclr);
190 
191 	return ret;
192 }
193 
194 static int rockchip_sfc_dma_xfer(struct rockchip_sfc *sfc, u32 *buf, u32 len)
195 {
196 	u32 trb;
197 	u32 *p32_data = buf;
198 	int ret = 0;
199 
200 	while (len) {
201 		trb = min(len, (u32)SFC_MAX_TRB);
202 		sfc->cmd |= (trb << SFC_TRB_SHIFT);
203 		ret = rockchip_sfc_do_dma_xfer(sfc, p32_data);
204 		if (ret < 0)
205 			break;
206 		len -= trb;
207 		sfc->addr += trb;
208 		p32_data += (trb >> 2);
209 	}
210 
211 	return ret;
212 }
213 
214 static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr,
215 					u32 timeout)
216 {
217 	struct rockchip_sfc_reg *regs = sfc->regbase;
218 	unsigned long tbase = get_timer(0);
219 	u8 level;
220 	u32 fsr;
221 
222 	do {
223 		fsr = readl(&regs->fsr);
224 		if (wr)
225 			level = (fsr & SFC_TXLV_MASK) >> SFC_TXLV_SHIFT;
226 		else
227 			level = (fsr & SFC_RXLV_MASK) >> SFC_RXLV_SHIFT;
228 		if (get_timer(tbase) > timeout)
229 			return -ETIMEDOUT;
230 		udelay(1);
231 	} while (!level);
232 
233 	return level;
234 }
235 
236 static int rockchip_sfc_write(struct rockchip_sfc *sfc, u32 *buf, u32 len)
237 {
238 	struct rockchip_sfc_reg *regs = sfc->regbase;
239 	u32 bytes = len & 0x3;
240 	u32 words = len >> 2;
241 	u32 tx_level = 0;
242 	u32 val = 0;
243 	u8 count;
244 
245 	while (words) {
246 		tx_level = rockchip_sfc_wait_fifo_ready(sfc, 1, 1000);
247 		if (tx_level <= 0)
248 			return tx_level;
249 		count = min(words, tx_level);
250 		writesl(&regs->data, buf, count);
251 		buf += count;
252 		words -= count;
253 	}
254 
255 	/* handle the last none word aligned bytes */
256 	if (bytes) {
257 		tx_level = rockchip_sfc_wait_fifo_ready(sfc, 1, 1000);
258 		if (tx_level <= 0)
259 			return tx_level;
260 		memcpy(&val, buf, bytes);
261 		writel(val, &regs->data);
262 	}
263 
264 	return 0;
265 }
266 
267 static int rockchip_sfc_read(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 	u32 rx_level = 0;
273 	u32 count;
274 	u32 val;
275 
276 	while (words) {
277 		rx_level = rockchip_sfc_wait_fifo_ready(sfc, 0, 1000);
278 		if (rx_level <= 0)
279 			return rx_level;
280 		count = min(words, rx_level);
281 		readsl(&regs->data, buf, count);
282 		buf += count;
283 		words -= count;
284 	}
285 
286 	/* handle the last none word aligned bytes */
287 	if (bytes) {
288 		rx_level = rockchip_sfc_wait_fifo_ready(sfc, 0, 1000);
289 		if (rx_level <= 0)
290 			return rx_level;
291 		val = readl(&regs->data);
292 		memcpy(buf, &val, bytes);
293 	}
294 
295 	return 0;
296 }
297 
298 static int rockchip_sfc_pio_xfer(struct rockchip_sfc *sfc, u32 *buf, u32 len)
299 {
300 	int ret = 0;
301 	int rw = sfc->cmd & SFC_WR;
302 
303 	sfc->cmd |= (len << SFC_TRB_SHIFT);
304 	rockchip_sfc_setup_xfer(sfc);
305 
306 	if (len) {
307 		if (rw)
308 			ret = rockchip_sfc_write(sfc, buf, len);
309 		else
310 			ret = rockchip_sfc_read(sfc, buf, len);
311 	}
312 
313 	return ret;
314 }
315 
316 static int rockchip_sfc_do_xfer(struct rockchip_sfc *sfc, u32 *buf, u32 len)
317 {
318 	int ret = 0;
319 
320 	if (!(len & 0x03) && (len >= 4))
321 		ret = rockchip_sfc_dma_xfer(sfc, buf, len);
322 	else
323 		ret = rockchip_sfc_pio_xfer(sfc, buf, len);
324 
325 	return ret;
326 }
327 
328 static int rockchip_sfc_xfer(struct udevice *dev, unsigned int bitlen,
329 			     const void *dout, void *din, unsigned long flags)
330 {
331 	struct udevice *bus = dev->parent;
332 	struct rockchip_sfc *sfc = dev_get_priv(bus);
333 	int len = bitlen >> 3;
334 	u8 *pcmd = (u8 *)dout;
335 	int ret = 0;
336 
337 	if (flags & SPI_XFER_BEGIN) {
338 		sfc->cmd = pcmd[0];
339 		if (len >= 4) {
340 			sfc->cmd |= SFC_ADDR_24BITS | (((len - 4) * 8) << 8);
341 			sfc->addr = pcmd[3] | (pcmd[2] << 8) | (pcmd[1] << 16);
342 		}
343 	}
344 
345 	if (flags == (SPI_XFER_BEGIN | SPI_XFER_END))
346 		len = 0;
347 
348 	if (flags & SPI_XFER_END) {
349 		if (dout && len)
350 			sfc->cmd |= SFC_WR;
351 
352 		if (din)
353 			ret = rockchip_sfc_do_xfer(sfc, (u32 *)din, len);
354 		else if (dout)
355 			ret = rockchip_sfc_do_xfer(sfc, (u32 *)dout, len);
356 	}
357 
358 	return ret;
359 }
360 
361 static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)
362 {
363 	struct rockchip_sfc *sfc = dev_get_priv(bus);
364 
365 	if (speed > sfc->max_freq)
366 		speed = sfc->max_freq;
367 
368 	sfc->speed_hz = speed;
369 
370 	return 0;
371 }
372 
373 static int rockchip_sfc_set_mode(struct udevice *bus, uint mode)
374 {
375 	struct rockchip_sfc *sfc = dev_get_priv(bus);
376 
377 	sfc->mode = mode;
378 
379 	return 0;
380 }
381 
382 static const struct dm_spi_ops rockchip_sfc_ops = {
383 	.xfer		= rockchip_sfc_xfer,
384 	.set_speed	= rockchip_sfc_set_speed,
385 	.set_mode	= rockchip_sfc_set_mode,
386 };
387 
388 static const struct udevice_id rockchip_sfc_ids[] = {
389 	{ .compatible = "rockchip,sfc" },
390 	{ }
391 };
392 
393 U_BOOT_DRIVER(rockchip_sfc_driver) = {
394 	.name	= "rockchip_sfc",
395 	.id	= UCLASS_SPI,
396 	.of_match = rockchip_sfc_ids,
397 	.ops	= &rockchip_sfc_ops,
398 	.ofdata_to_platdata = rockchip_sfc_ofdata_to_platdata,
399 	.platdata_auto_alloc_size = sizeof(struct rockchip_sfc_platdata),
400 	.priv_auto_alloc_size = sizeof(struct rockchip_sfc),
401 	.probe	= rockchip_sfc_probe,
402 };
403