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