1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2014-2015, Antmicro Ltd <www.antmicro.com>
4  * Copyright (c) 2015, AW-SOM Technologies <www.aw-som.com>
5  */
6 
7 #include <asm/arch/clock.h>
8 #include <asm/io.h>
9 #include <common.h>
10 #include <config.h>
11 #include <nand.h>
12 #include <linux/bitops.h>
13 #include <linux/ctype.h>
14 #include <linux/delay.h>
15 
16 /* registers */
17 #define NFC_CTL                    0x00000000
18 #define NFC_ST                     0x00000004
19 #define NFC_INT                    0x00000008
20 #define NFC_TIMING_CTL             0x0000000C
21 #define NFC_TIMING_CFG             0x00000010
22 #define NFC_ADDR_LOW               0x00000014
23 #define NFC_ADDR_HIGH              0x00000018
24 #define NFC_SECTOR_NUM             0x0000001C
25 #define NFC_CNT                    0x00000020
26 #define NFC_CMD                    0x00000024
27 #define NFC_RCMD_SET               0x00000028
28 #define NFC_WCMD_SET               0x0000002C
29 #define NFC_IO_DATA                0x00000030
30 #define NFC_ECC_CTL                0x00000034
31 #define NFC_ECC_ST                 0x00000038
32 #define NFC_DEBUG                  0x0000003C
33 #define NFC_ECC_CNT0               0x00000040
34 #define NFC_ECC_CNT1               0x00000044
35 #define NFC_ECC_CNT2               0x00000048
36 #define NFC_ECC_CNT3               0x0000004C
37 #define NFC_USER_DATA_BASE         0x00000050
38 #define NFC_EFNAND_STATUS          0x00000090
39 #define NFC_SPARE_AREA             0x000000A0
40 #define NFC_PATTERN_ID             0x000000A4
41 #define NFC_RAM0_BASE              0x00000400
42 #define NFC_RAM1_BASE              0x00000800
43 
44 #define NFC_CTL_EN                 (1 << 0)
45 #define NFC_CTL_RESET              (1 << 1)
46 #define NFC_CTL_RAM_METHOD         (1 << 14)
47 #define NFC_CTL_PAGE_SIZE_MASK     (0xf << 8)
48 #define NFC_CTL_PAGE_SIZE(a)       ((fls(a) - 11) << 8)
49 
50 
51 #define NFC_ECC_EN                 (1 << 0)
52 #define NFC_ECC_PIPELINE           (1 << 3)
53 #define NFC_ECC_EXCEPTION          (1 << 4)
54 #define NFC_ECC_BLOCK_SIZE         (1 << 5)
55 #define NFC_ECC_RANDOM_EN          (1 << 9)
56 #define NFC_ECC_RANDOM_DIRECTION   (1 << 10)
57 
58 
59 #define NFC_ADDR_NUM_OFFSET        16
60 #define NFC_SEND_ADDR              (1 << 19)
61 #define NFC_ACCESS_DIR             (1 << 20)
62 #define NFC_DATA_TRANS             (1 << 21)
63 #define NFC_SEND_CMD1              (1 << 22)
64 #define NFC_WAIT_FLAG              (1 << 23)
65 #define NFC_SEND_CMD2              (1 << 24)
66 #define NFC_SEQ                    (1 << 25)
67 #define NFC_DATA_SWAP_METHOD       (1 << 26)
68 #define NFC_ROW_AUTO_INC           (1 << 27)
69 #define NFC_SEND_CMD3              (1 << 28)
70 #define NFC_SEND_CMD4              (1 << 29)
71 #define NFC_RAW_CMD                (0 << 30)
72 #define NFC_ECC_CMD                (1 << 30)
73 #define NFC_PAGE_CMD               (2 << 30)
74 
75 #define NFC_ST_CMD_INT_FLAG        (1 << 1)
76 #define NFC_ST_DMA_INT_FLAG        (1 << 2)
77 #define NFC_ST_CMD_FIFO_STAT       (1 << 3)
78 
79 #define NFC_READ_CMD_OFFSET         0
80 #define NFC_RANDOM_READ_CMD0_OFFSET 8
81 #define NFC_RANDOM_READ_CMD1_OFFSET 16
82 
83 #define NFC_CMD_RNDOUTSTART        0xE0
84 #define NFC_CMD_RNDOUT             0x05
85 #define NFC_CMD_READSTART          0x30
86 
87 struct nfc_config {
88 	int page_size;
89 	int ecc_strength;
90 	int ecc_size;
91 	int addr_cycles;
92 	int nseeds;
93 	bool randomize;
94 	bool valid;
95 };
96 
97 /* minimal "boot0" style NAND support for Allwinner A20 */
98 
99 /* random seed used by linux */
100 const uint16_t random_seed[128] = {
101 	0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
102 	0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
103 	0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
104 	0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
105 	0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
106 	0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
107 	0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
108 	0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
109 	0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
110 	0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
111 	0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
112 	0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
113 	0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
114 	0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
115 	0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
116 	0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
117 };
118 
119 #define DEFAULT_TIMEOUT_US	100000
120 
check_value_inner(int offset,int expected_bits,int timeout_us,int negation)121 static int check_value_inner(int offset, int expected_bits,
122 			     int timeout_us, int negation)
123 {
124 	do {
125 		int val = readl(offset) & expected_bits;
126 		if (negation ? !val : val)
127 			return 1;
128 		udelay(1);
129 	} while (--timeout_us);
130 
131 	return 0;
132 }
133 
check_value(int offset,int expected_bits,int timeout_us)134 static inline int check_value(int offset, int expected_bits,
135 			      int timeout_us)
136 {
137 	return check_value_inner(offset, expected_bits, timeout_us, 0);
138 }
139 
check_value_negated(int offset,int unexpected_bits,int timeout_us)140 static inline int check_value_negated(int offset, int unexpected_bits,
141 				      int timeout_us)
142 {
143 	return check_value_inner(offset, unexpected_bits, timeout_us, 1);
144 }
145 
nand_wait_cmd_fifo_empty(void)146 static int nand_wait_cmd_fifo_empty(void)
147 {
148 	if (!check_value_negated(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_FIFO_STAT,
149 				 DEFAULT_TIMEOUT_US)) {
150 		printf("nand: timeout waiting for empty cmd FIFO\n");
151 		return -ETIMEDOUT;
152 	}
153 
154 	return 0;
155 }
156 
nand_wait_int(void)157 static int nand_wait_int(void)
158 {
159 	if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
160 			 DEFAULT_TIMEOUT_US)) {
161 		printf("nand: timeout waiting for interruption\n");
162 		return -ETIMEDOUT;
163 	}
164 
165 	return 0;
166 }
167 
nand_exec_cmd(u32 cmd)168 static int nand_exec_cmd(u32 cmd)
169 {
170 	int ret;
171 
172 	ret = nand_wait_cmd_fifo_empty();
173 	if (ret)
174 		return ret;
175 
176 	writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
177 	writel(cmd, SUNXI_NFC_BASE + NFC_CMD);
178 
179 	return nand_wait_int();
180 }
181 
nand_init(void)182 void nand_init(void)
183 {
184 	uint32_t val;
185 
186 	board_nand_init();
187 
188 	val = readl(SUNXI_NFC_BASE + NFC_CTL);
189 	/* enable and reset CTL */
190 	writel(val | NFC_CTL_EN | NFC_CTL_RESET,
191 	       SUNXI_NFC_BASE + NFC_CTL);
192 
193 	if (!check_value_negated(SUNXI_NFC_BASE + NFC_CTL,
194 				 NFC_CTL_RESET, DEFAULT_TIMEOUT_US)) {
195 		printf("Couldn't initialize nand\n");
196 	}
197 
198 	/* reset NAND */
199 	nand_exec_cmd(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET);
200 }
201 
nand_apply_config(const struct nfc_config * conf)202 static void nand_apply_config(const struct nfc_config *conf)
203 {
204 	u32 val;
205 
206 	nand_wait_cmd_fifo_empty();
207 
208 	val = readl(SUNXI_NFC_BASE + NFC_CTL);
209 	val &= ~NFC_CTL_PAGE_SIZE_MASK;
210 	writel(val | NFC_CTL_RAM_METHOD | NFC_CTL_PAGE_SIZE(conf->page_size),
211 	       SUNXI_NFC_BASE + NFC_CTL);
212 	writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT);
213 	writel(conf->page_size, SUNXI_NFC_BASE + NFC_SPARE_AREA);
214 }
215 
nand_load_page(const struct nfc_config * conf,u32 offs)216 static int nand_load_page(const struct nfc_config *conf, u32 offs)
217 {
218 	int page = offs / conf->page_size;
219 
220 	writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
221 	       (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
222 	       (NFC_CMD_READSTART << NFC_READ_CMD_OFFSET),
223 	       SUNXI_NFC_BASE + NFC_RCMD_SET);
224 	writel(((page & 0xFFFF) << 16), SUNXI_NFC_BASE + NFC_ADDR_LOW);
225 	writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
226 
227 	return nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
228 			     NFC_SEND_ADDR | NFC_WAIT_FLAG |
229 			     ((conf->addr_cycles - 1) << NFC_ADDR_NUM_OFFSET));
230 }
231 
nand_change_column(u16 column)232 static int nand_change_column(u16 column)
233 {
234 	int ret;
235 
236 	writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
237 	       (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
238 	       (NFC_CMD_RNDOUTSTART << NFC_READ_CMD_OFFSET),
239 	       SUNXI_NFC_BASE + NFC_RCMD_SET);
240 	writel(column, SUNXI_NFC_BASE + NFC_ADDR_LOW);
241 
242 	ret = nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
243 			    (1 << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADDR |
244 			    NFC_CMD_RNDOUT);
245 	if (ret)
246 		return ret;
247 
248 	/* Ensure tCCS has passed before reading data */
249 	udelay(1);
250 
251 	return 0;
252 }
253 
254 static const int ecc_bytes[] = {32, 46, 54, 60, 74, 88, 102, 110, 116};
255 
nand_read_page(const struct nfc_config * conf,u32 offs,void * dest,int len)256 static int nand_read_page(const struct nfc_config *conf, u32 offs,
257 			  void *dest, int len)
258 {
259 	int nsectors = len / conf->ecc_size;
260 	u16 rand_seed = 0;
261 	int oob_chunk_sz = ecc_bytes[conf->ecc_strength];
262 	int page = offs / conf->page_size;
263 	u32 ecc_st;
264 	int i;
265 
266 	if (offs % conf->page_size || len % conf->ecc_size ||
267 	    len > conf->page_size || len < 0)
268 		return -EINVAL;
269 
270 	/* Choose correct seed if randomized */
271 	if (conf->randomize)
272 		rand_seed = random_seed[page % conf->nseeds];
273 
274 	/* Retrieve data from SRAM (PIO) */
275 	for (i = 0; i < nsectors; i++) {
276 		int data_off = i * conf->ecc_size;
277 		int oob_off = conf->page_size + (i * oob_chunk_sz);
278 		u8 *data = dest + data_off;
279 
280 		/* Clear ECC status and restart ECC engine */
281 		writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
282 		writel((rand_seed << 16) | (conf->ecc_strength << 12) |
283 		       (conf->randomize ? NFC_ECC_RANDOM_EN : 0) |
284 		       (conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) |
285 		       NFC_ECC_EN | NFC_ECC_EXCEPTION,
286 		       SUNXI_NFC_BASE + NFC_ECC_CTL);
287 
288 		/* Move the data in SRAM */
289 		nand_change_column(data_off);
290 		writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT);
291 		nand_exec_cmd(NFC_DATA_TRANS);
292 
293 		/*
294 		 * Let the ECC engine consume the ECC bytes and possibly correct
295 		 * the data.
296 		 */
297 		nand_change_column(oob_off);
298 		nand_exec_cmd(NFC_DATA_TRANS | NFC_ECC_CMD);
299 
300 		/* Get the ECC status */
301 		ecc_st = readl(SUNXI_NFC_BASE + NFC_ECC_ST);
302 
303 		/* ECC error detected. */
304 		if (ecc_st & 0xffff)
305 			return -EIO;
306 
307 		/*
308 		 * Return 1 if the first chunk is empty (needed for
309 		 * configuration detection).
310 		 */
311 		if (!i && (ecc_st & 0x10000))
312 			return 1;
313 
314 		/* Retrieve the data from SRAM */
315 		memcpy_fromio(data, SUNXI_NFC_BASE + NFC_RAM0_BASE,
316 			      conf->ecc_size);
317 
318 		/* Stop the ECC engine */
319 		writel(readl(SUNXI_NFC_BASE + NFC_ECC_CTL) & ~NFC_ECC_EN,
320 		       SUNXI_NFC_BASE + NFC_ECC_CTL);
321 
322 		if (data_off + conf->ecc_size >= len)
323 			break;
324 	}
325 
326 	return 0;
327 }
328 
nand_max_ecc_strength(struct nfc_config * conf)329 static int nand_max_ecc_strength(struct nfc_config *conf)
330 {
331 	int max_oobsize, max_ecc_bytes;
332 	int nsectors = conf->page_size / conf->ecc_size;
333 	int i;
334 
335 	/*
336 	 * ECC strength is limited by the size of the OOB area which is
337 	 * correlated with the page size.
338 	 */
339 	switch (conf->page_size) {
340 	case 2048:
341 		max_oobsize = 64;
342 		break;
343 	case 4096:
344 		max_oobsize = 256;
345 		break;
346 	case 8192:
347 		max_oobsize = 640;
348 		break;
349 	case 16384:
350 		max_oobsize = 1664;
351 		break;
352 	default:
353 		return -EINVAL;
354 	}
355 
356 	max_ecc_bytes = max_oobsize / nsectors;
357 
358 	for (i = 0; i < ARRAY_SIZE(ecc_bytes); i++) {
359 		if (ecc_bytes[i] > max_ecc_bytes)
360 			break;
361 	}
362 
363 	if (!i)
364 		return -EINVAL;
365 
366 	return i - 1;
367 }
368 
nand_detect_ecc_config(struct nfc_config * conf,u32 offs,void * dest)369 static int nand_detect_ecc_config(struct nfc_config *conf, u32 offs,
370 				  void *dest)
371 {
372 	/* NAND with pages > 4k will likely require 1k sector size. */
373 	int min_ecc_size = conf->page_size > 4096 ? 1024 : 512;
374 	int page = offs / conf->page_size;
375 	int ret;
376 
377 	/*
378 	 * In most cases, 1k sectors are preferred over 512b ones, start
379 	 * testing this config first.
380 	 */
381 	for (conf->ecc_size = 1024; conf->ecc_size >= min_ecc_size;
382 	     conf->ecc_size >>= 1) {
383 		int max_ecc_strength = nand_max_ecc_strength(conf);
384 
385 		nand_apply_config(conf);
386 
387 		/*
388 		 * We are starting from the maximum ECC strength because
389 		 * most of the time NAND vendors provide an OOB area that
390 		 * barely meets the ECC requirements.
391 		 */
392 		for (conf->ecc_strength = max_ecc_strength;
393 		     conf->ecc_strength >= 0;
394 		     conf->ecc_strength--) {
395 			conf->randomize = false;
396 			if (nand_change_column(0))
397 				return -EIO;
398 
399 			/*
400 			 * Only read the first sector to speedup detection.
401 			 */
402 			ret = nand_read_page(conf, offs, dest, conf->ecc_size);
403 			if (!ret) {
404 				return 0;
405 			} else if (ret > 0) {
406 				/*
407 				 * If page is empty we can't deduce anything
408 				 * about the ECC config => stop the detection.
409 				 */
410 				return -EINVAL;
411 			}
412 
413 			conf->randomize = true;
414 			conf->nseeds = ARRAY_SIZE(random_seed);
415 			do {
416 				if (nand_change_column(0))
417 					return -EIO;
418 
419 				if (!nand_read_page(conf, offs, dest,
420 						    conf->ecc_size))
421 					return 0;
422 
423 				/*
424 				 * Find the next ->nseeds value that would
425 				 * change the randomizer seed for the page
426 				 * we're trying to read.
427 				 */
428 				while (conf->nseeds >= 16) {
429 					int seed = page % conf->nseeds;
430 
431 					conf->nseeds >>= 1;
432 					if (seed != page % conf->nseeds)
433 						break;
434 				}
435 			} while (conf->nseeds >= 16);
436 		}
437 	}
438 
439 	return -EINVAL;
440 }
441 
nand_detect_config(struct nfc_config * conf,u32 offs,void * dest)442 static int nand_detect_config(struct nfc_config *conf, u32 offs, void *dest)
443 {
444 	if (conf->valid)
445 		return 0;
446 
447 	/*
448 	 * Modern NANDs are more likely than legacy ones, so we start testing
449 	 * with 5 address cycles.
450 	 */
451 	for (conf->addr_cycles = 5;
452 	     conf->addr_cycles >= 4;
453 	     conf->addr_cycles--) {
454 		int max_page_size = conf->addr_cycles == 4 ? 2048 : 16384;
455 
456 		/*
457 		 * Ignoring 1k pages cause I'm not even sure this case exist
458 		 * in the real world.
459 		 */
460 		for (conf->page_size = 2048; conf->page_size <= max_page_size;
461 		     conf->page_size <<= 1) {
462 			if (nand_load_page(conf, offs))
463 				return -1;
464 
465 			if (!nand_detect_ecc_config(conf, offs, dest)) {
466 				conf->valid = true;
467 				return 0;
468 			}
469 		}
470 	}
471 
472 	return -EINVAL;
473 }
474 
nand_read_buffer(struct nfc_config * conf,uint32_t offs,unsigned int size,void * dest)475 static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
476 			    unsigned int size, void *dest)
477 {
478 	int first_seed = 0, page, ret;
479 
480 	size = ALIGN(size, conf->page_size);
481 	page = offs / conf->page_size;
482 	if (conf->randomize)
483 		first_seed = page % conf->nseeds;
484 
485 	for (; size; size -= conf->page_size) {
486 		if (nand_load_page(conf, offs))
487 			return -1;
488 
489 		ret = nand_read_page(conf, offs, dest, conf->page_size);
490 		/*
491 		 * The ->nseeds value should be equal to the number of pages
492 		 * in an eraseblock. Since we don't know this information in
493 		 * advance we might have picked a wrong value.
494 		 */
495 		if (ret < 0 && conf->randomize) {
496 			int cur_seed = page % conf->nseeds;
497 
498 			/*
499 			 * We already tried all the seed values => we are
500 			 * facing a real corruption.
501 			 */
502 			if (cur_seed < first_seed)
503 				return -EIO;
504 
505 			/* Try to adjust ->nseeds and read the page again... */
506 			conf->nseeds = cur_seed;
507 
508 			if (nand_change_column(0))
509 				return -EIO;
510 
511 			/* ... it still fails => it's a real corruption. */
512 			if (nand_read_page(conf, offs, dest, conf->page_size))
513 				return -EIO;
514 		} else if (ret && conf->randomize) {
515 			memset(dest, 0xff, conf->page_size);
516 		}
517 
518 		page++;
519 		offs += conf->page_size;
520 		dest += conf->page_size;
521 	}
522 
523 	return 0;
524 }
525 
nand_spl_load_image(uint32_t offs,unsigned int size,void * dest)526 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
527 {
528 	static struct nfc_config conf = { };
529 	int ret;
530 
531 	ret = nand_detect_config(&conf, offs, dest);
532 	if (ret)
533 		return ret;
534 
535 	return nand_read_buffer(&conf, offs, size, dest);
536 }
537 
nand_deselect(void)538 void nand_deselect(void)
539 {
540 	struct sunxi_ccm_reg *const ccm =
541 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
542 
543 	clrbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
544 #ifdef CONFIG_MACH_SUN9I
545 	clrbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
546 #else
547 	clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
548 #endif
549 	clrbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
550 }
551