]>
Commit | Line | Data |
---|---|---|
7f0730a0 VK |
1 | /* |
2 | * (C) Copyright 2010 | |
3 | * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com. | |
4 | * | |
5 | * (C) Copyright 2012 | |
6 | * Amit Virdi, ST Microelectronics, amit.virdi@st.com. | |
7 | * | |
8 | * See file CREDITS for list of people who contributed to this | |
9 | * project. | |
10 | * | |
11 | * This program is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU General Public License as | |
13 | * published by the Free Software Foundation; either version 2 of | |
14 | * the License, or (at your option) any later version. | |
15 | * | |
16 | * This program is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | * GNU General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License | |
22 | * along with this program; if not, write to the Free Software | |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
24 | * MA 02111-1307 USA | |
25 | */ | |
26 | ||
27 | #include <common.h> | |
28 | #include <nand.h> | |
29 | #include <asm/io.h> | |
30 | #include <linux/bitops.h> | |
31 | #include <linux/err.h> | |
32 | #include <linux/mtd/nand_ecc.h> | |
33 | #include <linux/mtd/fsmc_nand.h> | |
34 | #include <asm/arch/hardware.h> | |
35 | ||
36 | static u32 fsmc_version; | |
37 | static struct fsmc_regs *const fsmc_regs_p = (struct fsmc_regs *) | |
38 | CONFIG_SYS_FSMC_BASE; | |
39 | ||
40 | /* | |
41 | * ECC4 and ECC1 have 13 bytes and 3 bytes of ecc respectively for 512 bytes of | |
42 | * data. ECC4 can correct up to 8 bits in 512 bytes of data while ECC1 can | |
43 | * correct 1 bit in 512 bytes | |
44 | */ | |
45 | ||
46 | static struct nand_ecclayout fsmc_ecc4_lp_layout = { | |
47 | .eccbytes = 104, | |
48 | .eccpos = { 2, 3, 4, 5, 6, 7, 8, | |
49 | 9, 10, 11, 12, 13, 14, | |
50 | 18, 19, 20, 21, 22, 23, 24, | |
51 | 25, 26, 27, 28, 29, 30, | |
52 | 34, 35, 36, 37, 38, 39, 40, | |
53 | 41, 42, 43, 44, 45, 46, | |
54 | 50, 51, 52, 53, 54, 55, 56, | |
55 | 57, 58, 59, 60, 61, 62, | |
56 | 66, 67, 68, 69, 70, 71, 72, | |
57 | 73, 74, 75, 76, 77, 78, | |
58 | 82, 83, 84, 85, 86, 87, 88, | |
59 | 89, 90, 91, 92, 93, 94, | |
60 | 98, 99, 100, 101, 102, 103, 104, | |
61 | 105, 106, 107, 108, 109, 110, | |
62 | 114, 115, 116, 117, 118, 119, 120, | |
63 | 121, 122, 123, 124, 125, 126 | |
64 | }, | |
65 | .oobfree = { | |
66 | {.offset = 15, .length = 3}, | |
67 | {.offset = 31, .length = 3}, | |
68 | {.offset = 47, .length = 3}, | |
69 | {.offset = 63, .length = 3}, | |
70 | {.offset = 79, .length = 3}, | |
71 | {.offset = 95, .length = 3}, | |
72 | {.offset = 111, .length = 3}, | |
73 | {.offset = 127, .length = 1} | |
74 | } | |
75 | }; | |
76 | ||
77 | /* | |
78 | * ECC4 layout for NAND of pagesize 4096 bytes & OOBsize 224 bytes. 13*8 bytes | |
79 | * of OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block & 118 | |
80 | * bytes are free for use. | |
81 | */ | |
82 | static struct nand_ecclayout fsmc_ecc4_224_layout = { | |
83 | .eccbytes = 104, | |
84 | .eccpos = { 2, 3, 4, 5, 6, 7, 8, | |
85 | 9, 10, 11, 12, 13, 14, | |
86 | 18, 19, 20, 21, 22, 23, 24, | |
87 | 25, 26, 27, 28, 29, 30, | |
88 | 34, 35, 36, 37, 38, 39, 40, | |
89 | 41, 42, 43, 44, 45, 46, | |
90 | 50, 51, 52, 53, 54, 55, 56, | |
91 | 57, 58, 59, 60, 61, 62, | |
92 | 66, 67, 68, 69, 70, 71, 72, | |
93 | 73, 74, 75, 76, 77, 78, | |
94 | 82, 83, 84, 85, 86, 87, 88, | |
95 | 89, 90, 91, 92, 93, 94, | |
96 | 98, 99, 100, 101, 102, 103, 104, | |
97 | 105, 106, 107, 108, 109, 110, | |
98 | 114, 115, 116, 117, 118, 119, 120, | |
99 | 121, 122, 123, 124, 125, 126 | |
100 | }, | |
101 | .oobfree = { | |
102 | {.offset = 15, .length = 3}, | |
103 | {.offset = 31, .length = 3}, | |
104 | {.offset = 47, .length = 3}, | |
105 | {.offset = 63, .length = 3}, | |
106 | {.offset = 79, .length = 3}, | |
107 | {.offset = 95, .length = 3}, | |
108 | {.offset = 111, .length = 3}, | |
109 | {.offset = 127, .length = 97} | |
110 | } | |
111 | }; | |
112 | ||
113 | /* | |
114 | * ECC placement definitions in oobfree type format | |
115 | * There are 13 bytes of ecc for every 512 byte block and it has to be read | |
116 | * consecutively and immediately after the 512 byte data block for hardware to | |
117 | * generate the error bit offsets in 512 byte data | |
118 | * Managing the ecc bytes in the following way makes it easier for software to | |
119 | * read ecc bytes consecutive to data bytes. This way is similar to | |
120 | * oobfree structure maintained already in u-boot nand driver | |
121 | */ | |
122 | static struct fsmc_eccplace fsmc_eccpl_lp = { | |
123 | .eccplace = { | |
124 | {.offset = 2, .length = 13}, | |
125 | {.offset = 18, .length = 13}, | |
126 | {.offset = 34, .length = 13}, | |
127 | {.offset = 50, .length = 13}, | |
128 | {.offset = 66, .length = 13}, | |
129 | {.offset = 82, .length = 13}, | |
130 | {.offset = 98, .length = 13}, | |
131 | {.offset = 114, .length = 13} | |
132 | } | |
133 | }; | |
134 | ||
135 | static struct nand_ecclayout fsmc_ecc4_sp_layout = { | |
136 | .eccbytes = 13, | |
137 | .eccpos = { 0, 1, 2, 3, 6, 7, 8, | |
138 | 9, 10, 11, 12, 13, 14 | |
139 | }, | |
140 | .oobfree = { | |
141 | {.offset = 15, .length = 1}, | |
142 | } | |
143 | }; | |
144 | ||
145 | static struct fsmc_eccplace fsmc_eccpl_sp = { | |
146 | .eccplace = { | |
147 | {.offset = 0, .length = 4}, | |
148 | {.offset = 6, .length = 9} | |
149 | } | |
150 | }; | |
151 | ||
152 | static struct nand_ecclayout fsmc_ecc1_layout = { | |
153 | .eccbytes = 24, | |
154 | .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52, | |
155 | 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116}, | |
156 | .oobfree = { | |
157 | {.offset = 8, .length = 8}, | |
158 | {.offset = 24, .length = 8}, | |
159 | {.offset = 40, .length = 8}, | |
160 | {.offset = 56, .length = 8}, | |
161 | {.offset = 72, .length = 8}, | |
162 | {.offset = 88, .length = 8}, | |
163 | {.offset = 104, .length = 8}, | |
164 | {.offset = 120, .length = 8} | |
165 | } | |
166 | }; | |
167 | ||
168 | /* Count the number of 0's in buff upto a max of max_bits */ | |
169 | static int count_written_bits(uint8_t *buff, int size, int max_bits) | |
170 | { | |
171 | int k, written_bits = 0; | |
172 | ||
173 | for (k = 0; k < size; k++) { | |
174 | written_bits += hweight8(~buff[k]); | |
175 | if (written_bits > max_bits) | |
176 | break; | |
177 | } | |
178 | ||
179 | return written_bits; | |
180 | } | |
181 | ||
182 | static void fsmc_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl) | |
183 | { | |
184 | struct nand_chip *this = mtd->priv; | |
185 | ulong IO_ADDR_W; | |
186 | ||
187 | if (ctrl & NAND_CTRL_CHANGE) { | |
188 | IO_ADDR_W = (ulong)this->IO_ADDR_W; | |
189 | ||
190 | IO_ADDR_W &= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE); | |
191 | if (ctrl & NAND_CLE) | |
192 | IO_ADDR_W |= CONFIG_SYS_NAND_CLE; | |
193 | if (ctrl & NAND_ALE) | |
194 | IO_ADDR_W |= CONFIG_SYS_NAND_ALE; | |
195 | ||
196 | if (ctrl & NAND_NCE) { | |
197 | writel(readl(&fsmc_regs_p->pc) | | |
198 | FSMC_ENABLE, &fsmc_regs_p->pc); | |
199 | } else { | |
200 | writel(readl(&fsmc_regs_p->pc) & | |
201 | ~FSMC_ENABLE, &fsmc_regs_p->pc); | |
202 | } | |
203 | this->IO_ADDR_W = (void *)IO_ADDR_W; | |
204 | } | |
205 | ||
206 | if (cmd != NAND_CMD_NONE) | |
207 | writeb(cmd, this->IO_ADDR_W); | |
208 | } | |
209 | ||
210 | static int fsmc_bch8_correct_data(struct mtd_info *mtd, u_char *dat, | |
211 | u_char *read_ecc, u_char *calc_ecc) | |
212 | { | |
213 | /* The calculated ecc is actually the correction index in data */ | |
214 | u32 err_idx[8]; | |
215 | u32 num_err, i; | |
216 | u32 ecc1, ecc2, ecc3, ecc4; | |
217 | ||
218 | num_err = (readl(&fsmc_regs_p->sts) >> 10) & 0xF; | |
219 | ||
220 | if (likely(num_err == 0)) | |
221 | return 0; | |
222 | ||
223 | if (unlikely(num_err > 8)) { | |
224 | /* | |
225 | * This is a temporary erase check. A newly erased page read | |
226 | * would result in an ecc error because the oob data is also | |
227 | * erased to FF and the calculated ecc for an FF data is not | |
228 | * FF..FF. | |
229 | * This is a workaround to skip performing correction in case | |
230 | * data is FF..FF | |
231 | * | |
232 | * Logic: | |
233 | * For every page, each bit written as 0 is counted until these | |
234 | * number of bits are greater than 8 (the maximum correction | |
235 | * capability of FSMC for each 512 + 13 bytes) | |
236 | */ | |
237 | ||
238 | int bits_ecc = count_written_bits(read_ecc, 13, 8); | |
239 | int bits_data = count_written_bits(dat, 512, 8); | |
240 | ||
241 | if ((bits_ecc + bits_data) <= 8) { | |
242 | if (bits_data) | |
243 | memset(dat, 0xff, 512); | |
244 | return bits_data + bits_ecc; | |
245 | } | |
246 | ||
247 | return -EBADMSG; | |
248 | } | |
249 | ||
250 | ecc1 = readl(&fsmc_regs_p->ecc1); | |
251 | ecc2 = readl(&fsmc_regs_p->ecc2); | |
252 | ecc3 = readl(&fsmc_regs_p->ecc3); | |
253 | ecc4 = readl(&fsmc_regs_p->sts); | |
254 | ||
255 | err_idx[0] = (ecc1 >> 0) & 0x1FFF; | |
256 | err_idx[1] = (ecc1 >> 13) & 0x1FFF; | |
257 | err_idx[2] = (((ecc2 >> 0) & 0x7F) << 6) | ((ecc1 >> 26) & 0x3F); | |
258 | err_idx[3] = (ecc2 >> 7) & 0x1FFF; | |
259 | err_idx[4] = (((ecc3 >> 0) & 0x1) << 12) | ((ecc2 >> 20) & 0xFFF); | |
260 | err_idx[5] = (ecc3 >> 1) & 0x1FFF; | |
261 | err_idx[6] = (ecc3 >> 14) & 0x1FFF; | |
262 | err_idx[7] = (((ecc4 >> 16) & 0xFF) << 5) | ((ecc3 >> 27) & 0x1F); | |
263 | ||
264 | i = 0; | |
265 | while (i < num_err) { | |
266 | err_idx[i] ^= 3; | |
267 | ||
268 | if (err_idx[i] < 512 * 8) | |
269 | __change_bit(err_idx[i], dat); | |
270 | ||
271 | i++; | |
272 | } | |
273 | ||
274 | return num_err; | |
275 | } | |
276 | ||
277 | static int fsmc_read_hwecc(struct mtd_info *mtd, | |
278 | const u_char *data, u_char *ecc) | |
279 | { | |
280 | u_int ecc_tmp; | |
281 | int timeout = CONFIG_SYS_HZ; | |
282 | ulong start; | |
283 | ||
284 | switch (fsmc_version) { | |
285 | case FSMC_VER8: | |
286 | start = get_timer(0); | |
287 | while (get_timer(start) < timeout) { | |
288 | /* | |
289 | * Busy waiting for ecc computation | |
290 | * to finish for 512 bytes | |
291 | */ | |
292 | if (readl(&fsmc_regs_p->sts) & FSMC_CODE_RDY) | |
293 | break; | |
294 | } | |
295 | ||
296 | ecc_tmp = readl(&fsmc_regs_p->ecc1); | |
297 | ecc[0] = (u_char) (ecc_tmp >> 0); | |
298 | ecc[1] = (u_char) (ecc_tmp >> 8); | |
299 | ecc[2] = (u_char) (ecc_tmp >> 16); | |
300 | ecc[3] = (u_char) (ecc_tmp >> 24); | |
301 | ||
302 | ecc_tmp = readl(&fsmc_regs_p->ecc2); | |
303 | ecc[4] = (u_char) (ecc_tmp >> 0); | |
304 | ecc[5] = (u_char) (ecc_tmp >> 8); | |
305 | ecc[6] = (u_char) (ecc_tmp >> 16); | |
306 | ecc[7] = (u_char) (ecc_tmp >> 24); | |
307 | ||
308 | ecc_tmp = readl(&fsmc_regs_p->ecc3); | |
309 | ecc[8] = (u_char) (ecc_tmp >> 0); | |
310 | ecc[9] = (u_char) (ecc_tmp >> 8); | |
311 | ecc[10] = (u_char) (ecc_tmp >> 16); | |
312 | ecc[11] = (u_char) (ecc_tmp >> 24); | |
313 | ||
314 | ecc_tmp = readl(&fsmc_regs_p->sts); | |
315 | ecc[12] = (u_char) (ecc_tmp >> 16); | |
316 | break; | |
317 | ||
318 | default: | |
319 | ecc_tmp = readl(&fsmc_regs_p->ecc1); | |
320 | ecc[0] = (u_char) (ecc_tmp >> 0); | |
321 | ecc[1] = (u_char) (ecc_tmp >> 8); | |
322 | ecc[2] = (u_char) (ecc_tmp >> 16); | |
323 | break; | |
324 | } | |
325 | ||
326 | return 0; | |
327 | } | |
328 | ||
329 | void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) | |
330 | { | |
331 | writel(readl(&fsmc_regs_p->pc) & ~FSMC_ECCPLEN_256, | |
332 | &fsmc_regs_p->pc); | |
333 | writel(readl(&fsmc_regs_p->pc) & ~FSMC_ECCEN, | |
334 | &fsmc_regs_p->pc); | |
335 | writel(readl(&fsmc_regs_p->pc) | FSMC_ECCEN, | |
336 | &fsmc_regs_p->pc); | |
337 | } | |
338 | ||
339 | /* | |
340 | * fsmc_read_page_hwecc | |
341 | * @mtd: mtd info structure | |
342 | * @chip: nand chip info structure | |
343 | * @buf: buffer to store read data | |
dfe64e2c | 344 | * @oob_required: caller expects OOB data read to chip->oob_poi |
7f0730a0 VK |
345 | * @page: page number to read |
346 | * | |
347 | * This routine is needed for fsmc verison 8 as reading from NAND chip has to be | |
348 | * performed in a strict sequence as follows: | |
349 | * data(512 byte) -> ecc(13 byte) | |
350 | * After this read, fsmc hardware generates and reports error data bits(upto a | |
351 | * max of 8 bits) | |
352 | */ | |
353 | static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |
dfe64e2c | 354 | uint8_t *buf, int oob_required, int page) |
7f0730a0 VK |
355 | { |
356 | struct fsmc_eccplace *fsmc_eccpl; | |
357 | int i, j, s, stat, eccsize = chip->ecc.size; | |
358 | int eccbytes = chip->ecc.bytes; | |
359 | int eccsteps = chip->ecc.steps; | |
360 | uint8_t *p = buf; | |
361 | uint8_t *ecc_calc = chip->buffers->ecccalc; | |
362 | uint8_t *ecc_code = chip->buffers->ecccode; | |
363 | int off, len, group = 0; | |
364 | uint8_t oob[13] __attribute__ ((aligned (2))); | |
365 | ||
366 | /* Differentiate between small and large page ecc place definitions */ | |
367 | if (mtd->writesize == 512) | |
368 | fsmc_eccpl = &fsmc_eccpl_sp; | |
369 | else | |
370 | fsmc_eccpl = &fsmc_eccpl_lp; | |
371 | ||
372 | for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { | |
373 | ||
374 | chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page); | |
375 | chip->ecc.hwctl(mtd, NAND_ECC_READ); | |
376 | chip->read_buf(mtd, p, eccsize); | |
377 | ||
378 | for (j = 0; j < eccbytes;) { | |
379 | off = fsmc_eccpl->eccplace[group].offset; | |
380 | len = fsmc_eccpl->eccplace[group].length; | |
381 | group++; | |
382 | ||
383 | /* | |
384 | * length is intentionally kept a higher multiple of 2 | |
385 | * to read at least 13 bytes even in case of 16 bit NAND | |
386 | * devices | |
387 | */ | |
388 | if (chip->options & NAND_BUSWIDTH_16) | |
389 | len = roundup(len, 2); | |
390 | chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page); | |
391 | chip->read_buf(mtd, oob + j, len); | |
392 | j += len; | |
393 | } | |
394 | ||
395 | memcpy(&ecc_code[i], oob, 13); | |
396 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); | |
397 | ||
398 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], | |
399 | &ecc_calc[i]); | |
400 | if (stat < 0) | |
401 | mtd->ecc_stats.failed++; | |
402 | else | |
403 | mtd->ecc_stats.corrected += stat; | |
404 | } | |
405 | ||
406 | return 0; | |
407 | } | |
408 | ||
409 | int fsmc_nand_init(struct nand_chip *nand) | |
410 | { | |
411 | static int chip_nr; | |
412 | struct mtd_info *mtd; | |
413 | int i; | |
414 | u32 peripid2 = readl(&fsmc_regs_p->peripid2); | |
415 | ||
416 | fsmc_version = (peripid2 >> FSMC_REVISION_SHFT) & | |
417 | FSMC_REVISION_MSK; | |
418 | ||
419 | writel(readl(&fsmc_regs_p->ctrl) | FSMC_WP, &fsmc_regs_p->ctrl); | |
420 | ||
421 | #if defined(CONFIG_SYS_FSMC_NAND_16BIT) | |
422 | writel(FSMC_DEVWID_16 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON, | |
423 | &fsmc_regs_p->pc); | |
424 | #elif defined(CONFIG_SYS_FSMC_NAND_8BIT) | |
425 | writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON, | |
426 | &fsmc_regs_p->pc); | |
427 | #else | |
428 | #error Please define CONFIG_SYS_FSMC_NAND_16BIT or CONFIG_SYS_FSMC_NAND_8BIT | |
429 | #endif | |
430 | writel(readl(&fsmc_regs_p->pc) | FSMC_TCLR_1 | FSMC_TAR_1, | |
431 | &fsmc_regs_p->pc); | |
432 | writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, | |
433 | &fsmc_regs_p->comm); | |
434 | writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, | |
435 | &fsmc_regs_p->attrib); | |
436 | ||
437 | nand->options = 0; | |
438 | #if defined(CONFIG_SYS_FSMC_NAND_16BIT) | |
439 | nand->options |= NAND_BUSWIDTH_16; | |
440 | #endif | |
441 | nand->ecc.mode = NAND_ECC_HW; | |
442 | nand->ecc.size = 512; | |
443 | nand->ecc.calculate = fsmc_read_hwecc; | |
444 | nand->ecc.hwctl = fsmc_enable_hwecc; | |
445 | nand->cmd_ctrl = fsmc_nand_hwcontrol; | |
446 | nand->IO_ADDR_R = nand->IO_ADDR_W = | |
447 | (void __iomem *)CONFIG_SYS_NAND_BASE; | |
448 | nand->badblockbits = 7; | |
449 | ||
450 | mtd = &nand_info[chip_nr++]; | |
451 | mtd->priv = nand; | |
452 | ||
453 | switch (fsmc_version) { | |
454 | case FSMC_VER8: | |
455 | nand->ecc.bytes = 13; | |
dfe64e2c | 456 | nand->ecc.strength = 8; |
7f0730a0 VK |
457 | nand->ecc.correct = fsmc_bch8_correct_data; |
458 | nand->ecc.read_page = fsmc_read_page_hwecc; | |
459 | if (mtd->writesize == 512) | |
460 | nand->ecc.layout = &fsmc_ecc4_sp_layout; | |
461 | else { | |
462 | if (mtd->oobsize == 224) | |
463 | nand->ecc.layout = &fsmc_ecc4_224_layout; | |
464 | else | |
465 | nand->ecc.layout = &fsmc_ecc4_lp_layout; | |
466 | } | |
467 | ||
468 | break; | |
469 | default: | |
470 | nand->ecc.bytes = 3; | |
dfe64e2c | 471 | nand->ecc.strength = 1; |
7f0730a0 VK |
472 | nand->ecc.layout = &fsmc_ecc1_layout; |
473 | nand->ecc.correct = nand_correct_data; | |
474 | break; | |
475 | } | |
476 | ||
477 | /* Detect NAND chips */ | |
478 | if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL)) | |
479 | return -ENXIO; | |
480 | ||
481 | if (nand_scan_tail(mtd)) | |
482 | return -ENXIO; | |
483 | ||
484 | for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) | |
485 | if (nand_register(i)) | |
486 | return -ENXIO; | |
487 | ||
488 | return 0; | |
489 | } |