1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2006-2008
4  * Stefan Roese, DENX Software Engineering, sr@denx.de.
5  */
6 
7 #include <common.h>
8 #include <nand.h>
9 #include <asm/io.h>
10 #include <linux/mtd/nand_ecc.h>
11 #include <linux/mtd/rawnand.h>
12 
13 static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
14 static struct mtd_info *mtd;
15 static struct nand_chip nand_chip;
16 
17 #define ECCSTEPS	(CONFIG_SYS_NAND_PAGE_SIZE / \
18 					CONFIG_SYS_NAND_ECCSIZE)
19 #define ECCTOTAL	(ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES)
20 
21 
22 #if (CONFIG_SYS_NAND_PAGE_SIZE <= 512)
23 /*
24  * NAND command for small page NAND devices (512)
25  */
nand_command(int block,int page,uint32_t offs,u8 cmd)26 static int nand_command(int block, int page, uint32_t offs,
27 	u8 cmd)
28 {
29 	struct nand_chip *this = mtd_to_nand(mtd);
30 	int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
31 
32 	while (!this->dev_ready(mtd))
33 		;
34 
35 	/* Begin command latch cycle */
36 	this->cmd_ctrl(mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
37 	/* Set ALE and clear CLE to start address cycle */
38 	/* Column address */
39 	this->cmd_ctrl(mtd, offs, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
40 	this->cmd_ctrl(mtd, page_addr & 0xff, NAND_CTRL_ALE); /* A[16:9] */
41 	this->cmd_ctrl(mtd, (page_addr >> 8) & 0xff,
42 		       NAND_CTRL_ALE); /* A[24:17] */
43 	/* Latch in address */
44 	this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
45 
46 	/*
47 	 * Wait a while for the data to be ready
48 	 */
49 	while (!this->dev_ready(mtd))
50 		;
51 
52 	return 0;
53 }
54 #else
55 /*
56  * NAND command for large page NAND devices (2k)
57  */
nand_command(int block,int page,uint32_t offs,u8 cmd)58 static int nand_command(int block, int page, uint32_t offs,
59 	u8 cmd)
60 {
61 	struct nand_chip *this = mtd_to_nand(mtd);
62 	int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
63 	void (*hwctrl)(struct mtd_info *mtd, int cmd,
64 			unsigned int ctrl) = this->cmd_ctrl;
65 
66 	while (!this->dev_ready(mtd))
67 		;
68 
69 	/* Emulate NAND_CMD_READOOB */
70 	if (cmd == NAND_CMD_READOOB) {
71 		offs += CONFIG_SYS_NAND_PAGE_SIZE;
72 		cmd = NAND_CMD_READ0;
73 	}
74 
75 	/* Shift the offset from byte addressing to word addressing. */
76 	if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
77 		offs >>= 1;
78 
79 	/* Begin command latch cycle */
80 	hwctrl(mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
81 	/* Set ALE and clear CLE to start address cycle */
82 	/* Column address */
83 	hwctrl(mtd, offs & 0xff,
84 		    NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */
85 	hwctrl(mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */
86 	/* Row address */
87 	hwctrl(mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */
88 	hwctrl(mtd, ((page_addr >> 8) & 0xff),
89 		    NAND_CTRL_ALE); /* A[27:20] */
90 #ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
91 	/* One more address cycle for devices > 128MiB */
92 	hwctrl(mtd, (page_addr >> 16) & 0x0f,
93 		       NAND_CTRL_ALE); /* A[31:28] */
94 #endif
95 	/* Latch in address */
96 	hwctrl(mtd, NAND_CMD_READSTART,
97 		    NAND_CTRL_CLE | NAND_CTRL_CHANGE);
98 	hwctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
99 
100 	/*
101 	 * Wait a while for the data to be ready
102 	 */
103 	while (!this->dev_ready(mtd))
104 		;
105 
106 	return 0;
107 }
108 #endif
109 
nand_is_bad_block(int block)110 static int nand_is_bad_block(int block)
111 {
112 	struct nand_chip *this = mtd_to_nand(mtd);
113 	u_char bb_data[2];
114 
115 	nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS,
116 		NAND_CMD_READOOB);
117 
118 	/*
119 	 * Read one byte (or two if it's a 16 bit chip).
120 	 */
121 	if (this->options & NAND_BUSWIDTH_16) {
122 		this->read_buf(mtd, bb_data, 2);
123 		if (bb_data[0] != 0xff || bb_data[1] != 0xff)
124 			return 1;
125 	} else {
126 		this->read_buf(mtd, bb_data, 1);
127 		if (bb_data[0] != 0xff)
128 			return 1;
129 	}
130 
131 	return 0;
132 }
133 
134 #if defined(CONFIG_SYS_NAND_HW_ECC_OOBFIRST)
nand_read_page(int block,int page,uchar * dst)135 static int nand_read_page(int block, int page, uchar *dst)
136 {
137 	struct nand_chip *this = mtd_to_nand(mtd);
138 	u_char ecc_calc[ECCTOTAL];
139 	u_char ecc_code[ECCTOTAL];
140 	u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
141 	int i;
142 	int eccsize = CONFIG_SYS_NAND_ECCSIZE;
143 	int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
144 	int eccsteps = ECCSTEPS;
145 	uint8_t *p = dst;
146 
147 	nand_command(block, page, 0, NAND_CMD_READOOB);
148 	this->read_buf(mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
149 	nand_command(block, page, 0, NAND_CMD_READ0);
150 
151 	/* Pick the ECC bytes out of the oob data */
152 	for (i = 0; i < ECCTOTAL; i++)
153 		ecc_code[i] = oob_data[nand_ecc_pos[i]];
154 
155 
156 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
157 		this->ecc.hwctl(mtd, NAND_ECC_READ);
158 		this->read_buf(mtd, p, eccsize);
159 		this->ecc.calculate(mtd, p, &ecc_calc[i]);
160 		this->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
161 	}
162 
163 	return 0;
164 }
165 #else
nand_read_page(int block,int page,void * dst)166 static int nand_read_page(int block, int page, void *dst)
167 {
168 	struct nand_chip *this = mtd_to_nand(mtd);
169 	u_char ecc_calc[ECCTOTAL];
170 	u_char ecc_code[ECCTOTAL];
171 	u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
172 	int i;
173 	int eccsize = CONFIG_SYS_NAND_ECCSIZE;
174 	int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
175 	int eccsteps = ECCSTEPS;
176 	uint8_t *p = dst;
177 
178 	nand_command(block, page, 0, NAND_CMD_READ0);
179 
180 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
181 		if (this->ecc.mode != NAND_ECC_SOFT)
182 			this->ecc.hwctl(mtd, NAND_ECC_READ);
183 		this->read_buf(mtd, p, eccsize);
184 		this->ecc.calculate(mtd, p, &ecc_calc[i]);
185 	}
186 	this->read_buf(mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
187 
188 	/* Pick the ECC bytes out of the oob data */
189 	for (i = 0; i < ECCTOTAL; i++)
190 		ecc_code[i] = oob_data[nand_ecc_pos[i]];
191 
192 	eccsteps = ECCSTEPS;
193 	p = dst;
194 
195 	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
196 		/* No chance to do something with the possible error message
197 		 * from correct_data(). We just hope that all possible errors
198 		 * are corrected by this routine.
199 		 */
200 		this->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
201 	}
202 
203 	return 0;
204 }
205 #endif
206 
207 /* nand_init() - initialize data to make nand usable by SPL */
nand_init(void)208 void nand_init(void)
209 {
210 	/*
211 	 * Init board specific nand support
212 	 */
213 	mtd = nand_to_mtd(&nand_chip);
214 	nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
215 		(void  __iomem *)CONFIG_SYS_NAND_BASE;
216 	board_nand_init(&nand_chip);
217 
218 #ifdef CONFIG_SPL_NAND_SOFTECC
219 	if (nand_chip.ecc.mode == NAND_ECC_SOFT) {
220 		nand_chip.ecc.calculate = nand_calculate_ecc;
221 		nand_chip.ecc.correct = nand_correct_data;
222 	}
223 #endif
224 
225 	if (nand_chip.select_chip)
226 		nand_chip.select_chip(mtd, 0);
227 }
228 
229 /* Unselect after operation */
nand_deselect(void)230 void nand_deselect(void)
231 {
232 	if (nand_chip.select_chip)
233 		nand_chip.select_chip(mtd, -1);
234 }
235 
236 #include "nand_spl_loaders.c"
237