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