1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <nand.h>
13#include <asm/io.h>
14#include <linux/bitops.h>
15#include <linux/err.h>
16#include <linux/mtd/nand_ecc.h>
17#include <linux/mtd/fsmc_nand.h>
18#include <asm/arch/hardware.h>
19
20static u32 fsmc_version;
21static struct fsmc_regs *const fsmc_regs_p = (struct fsmc_regs *)
22 CONFIG_SYS_FSMC_BASE;
23
24
25
26
27
28
29
30static struct nand_ecclayout fsmc_ecc4_lp_layout = {
31 .eccbytes = 104,
32 .eccpos = { 2, 3, 4, 5, 6, 7, 8,
33 9, 10, 11, 12, 13, 14,
34 18, 19, 20, 21, 22, 23, 24,
35 25, 26, 27, 28, 29, 30,
36 34, 35, 36, 37, 38, 39, 40,
37 41, 42, 43, 44, 45, 46,
38 50, 51, 52, 53, 54, 55, 56,
39 57, 58, 59, 60, 61, 62,
40 66, 67, 68, 69, 70, 71, 72,
41 73, 74, 75, 76, 77, 78,
42 82, 83, 84, 85, 86, 87, 88,
43 89, 90, 91, 92, 93, 94,
44 98, 99, 100, 101, 102, 103, 104,
45 105, 106, 107, 108, 109, 110,
46 114, 115, 116, 117, 118, 119, 120,
47 121, 122, 123, 124, 125, 126
48 },
49 .oobfree = {
50 {.offset = 15, .length = 3},
51 {.offset = 31, .length = 3},
52 {.offset = 47, .length = 3},
53 {.offset = 63, .length = 3},
54 {.offset = 79, .length = 3},
55 {.offset = 95, .length = 3},
56 {.offset = 111, .length = 3},
57 {.offset = 127, .length = 1}
58 }
59};
60
61
62
63
64
65
66static struct nand_ecclayout fsmc_ecc4_224_layout = {
67 .eccbytes = 104,
68 .eccpos = { 2, 3, 4, 5, 6, 7, 8,
69 9, 10, 11, 12, 13, 14,
70 18, 19, 20, 21, 22, 23, 24,
71 25, 26, 27, 28, 29, 30,
72 34, 35, 36, 37, 38, 39, 40,
73 41, 42, 43, 44, 45, 46,
74 50, 51, 52, 53, 54, 55, 56,
75 57, 58, 59, 60, 61, 62,
76 66, 67, 68, 69, 70, 71, 72,
77 73, 74, 75, 76, 77, 78,
78 82, 83, 84, 85, 86, 87, 88,
79 89, 90, 91, 92, 93, 94,
80 98, 99, 100, 101, 102, 103, 104,
81 105, 106, 107, 108, 109, 110,
82 114, 115, 116, 117, 118, 119, 120,
83 121, 122, 123, 124, 125, 126
84 },
85 .oobfree = {
86 {.offset = 15, .length = 3},
87 {.offset = 31, .length = 3},
88 {.offset = 47, .length = 3},
89 {.offset = 63, .length = 3},
90 {.offset = 79, .length = 3},
91 {.offset = 95, .length = 3},
92 {.offset = 111, .length = 3},
93 {.offset = 127, .length = 97}
94 }
95};
96
97
98
99
100
101
102
103
104
105
106static struct fsmc_eccplace fsmc_eccpl_lp = {
107 .eccplace = {
108 {.offset = 2, .length = 13},
109 {.offset = 18, .length = 13},
110 {.offset = 34, .length = 13},
111 {.offset = 50, .length = 13},
112 {.offset = 66, .length = 13},
113 {.offset = 82, .length = 13},
114 {.offset = 98, .length = 13},
115 {.offset = 114, .length = 13}
116 }
117};
118
119static struct nand_ecclayout fsmc_ecc4_sp_layout = {
120 .eccbytes = 13,
121 .eccpos = { 0, 1, 2, 3, 6, 7, 8,
122 9, 10, 11, 12, 13, 14
123 },
124 .oobfree = {
125 {.offset = 15, .length = 1},
126 }
127};
128
129static struct fsmc_eccplace fsmc_eccpl_sp = {
130 .eccplace = {
131 {.offset = 0, .length = 4},
132 {.offset = 6, .length = 9}
133 }
134};
135
136static struct nand_ecclayout fsmc_ecc1_layout = {
137 .eccbytes = 24,
138 .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
139 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
140 .oobfree = {
141 {.offset = 8, .length = 8},
142 {.offset = 24, .length = 8},
143 {.offset = 40, .length = 8},
144 {.offset = 56, .length = 8},
145 {.offset = 72, .length = 8},
146 {.offset = 88, .length = 8},
147 {.offset = 104, .length = 8},
148 {.offset = 120, .length = 8}
149 }
150};
151
152
153static int count_written_bits(uint8_t *buff, int size, int max_bits)
154{
155 int k, written_bits = 0;
156
157 for (k = 0; k < size; k++) {
158 written_bits += hweight8(~buff[k]);
159 if (written_bits > max_bits)
160 break;
161 }
162
163 return written_bits;
164}
165
166static void fsmc_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl)
167{
168 struct nand_chip *this = mtd_to_nand(mtd);
169 ulong IO_ADDR_W;
170
171 if (ctrl & NAND_CTRL_CHANGE) {
172 IO_ADDR_W = (ulong)this->IO_ADDR_W;
173
174 IO_ADDR_W &= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE);
175 if (ctrl & NAND_CLE)
176 IO_ADDR_W |= CONFIG_SYS_NAND_CLE;
177 if (ctrl & NAND_ALE)
178 IO_ADDR_W |= CONFIG_SYS_NAND_ALE;
179
180 if (ctrl & NAND_NCE) {
181 writel(readl(&fsmc_regs_p->pc) |
182 FSMC_ENABLE, &fsmc_regs_p->pc);
183 } else {
184 writel(readl(&fsmc_regs_p->pc) &
185 ~FSMC_ENABLE, &fsmc_regs_p->pc);
186 }
187 this->IO_ADDR_W = (void *)IO_ADDR_W;
188 }
189
190 if (cmd != NAND_CMD_NONE)
191 writeb(cmd, this->IO_ADDR_W);
192}
193
194static int fsmc_bch8_correct_data(struct mtd_info *mtd, u_char *dat,
195 u_char *read_ecc, u_char *calc_ecc)
196{
197
198 u32 err_idx[8];
199 u32 num_err, i;
200 u32 ecc1, ecc2, ecc3, ecc4;
201
202 num_err = (readl(&fsmc_regs_p->sts) >> 10) & 0xF;
203
204 if (likely(num_err == 0))
205 return 0;
206
207 if (unlikely(num_err > 8)) {
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 int bits_ecc = count_written_bits(read_ecc, 13, 8);
223 int bits_data = count_written_bits(dat, 512, 8);
224
225 if ((bits_ecc + bits_data) <= 8) {
226 if (bits_data)
227 memset(dat, 0xff, 512);
228 return bits_data + bits_ecc;
229 }
230
231 return -EBADMSG;
232 }
233
234 ecc1 = readl(&fsmc_regs_p->ecc1);
235 ecc2 = readl(&fsmc_regs_p->ecc2);
236 ecc3 = readl(&fsmc_regs_p->ecc3);
237 ecc4 = readl(&fsmc_regs_p->sts);
238
239 err_idx[0] = (ecc1 >> 0) & 0x1FFF;
240 err_idx[1] = (ecc1 >> 13) & 0x1FFF;
241 err_idx[2] = (((ecc2 >> 0) & 0x7F) << 6) | ((ecc1 >> 26) & 0x3F);
242 err_idx[3] = (ecc2 >> 7) & 0x1FFF;
243 err_idx[4] = (((ecc3 >> 0) & 0x1) << 12) | ((ecc2 >> 20) & 0xFFF);
244 err_idx[5] = (ecc3 >> 1) & 0x1FFF;
245 err_idx[6] = (ecc3 >> 14) & 0x1FFF;
246 err_idx[7] = (((ecc4 >> 16) & 0xFF) << 5) | ((ecc3 >> 27) & 0x1F);
247
248 i = 0;
249 while (i < num_err) {
250 err_idx[i] ^= 3;
251
252 if (err_idx[i] < 512 * 8)
253 __change_bit(err_idx[i], dat);
254
255 i++;
256 }
257
258 return num_err;
259}
260
261static int fsmc_read_hwecc(struct mtd_info *mtd,
262 const u_char *data, u_char *ecc)
263{
264 u_int ecc_tmp;
265 int timeout = CONFIG_SYS_HZ;
266 ulong start;
267
268 switch (fsmc_version) {
269 case FSMC_VER8:
270 start = get_timer(0);
271 while (get_timer(start) < timeout) {
272
273
274
275
276 if (readl(&fsmc_regs_p->sts) & FSMC_CODE_RDY)
277 break;
278 }
279
280 ecc_tmp = readl(&fsmc_regs_p->ecc1);
281 ecc[0] = (u_char) (ecc_tmp >> 0);
282 ecc[1] = (u_char) (ecc_tmp >> 8);
283 ecc[2] = (u_char) (ecc_tmp >> 16);
284 ecc[3] = (u_char) (ecc_tmp >> 24);
285
286 ecc_tmp = readl(&fsmc_regs_p->ecc2);
287 ecc[4] = (u_char) (ecc_tmp >> 0);
288 ecc[5] = (u_char) (ecc_tmp >> 8);
289 ecc[6] = (u_char) (ecc_tmp >> 16);
290 ecc[7] = (u_char) (ecc_tmp >> 24);
291
292 ecc_tmp = readl(&fsmc_regs_p->ecc3);
293 ecc[8] = (u_char) (ecc_tmp >> 0);
294 ecc[9] = (u_char) (ecc_tmp >> 8);
295 ecc[10] = (u_char) (ecc_tmp >> 16);
296 ecc[11] = (u_char) (ecc_tmp >> 24);
297
298 ecc_tmp = readl(&fsmc_regs_p->sts);
299 ecc[12] = (u_char) (ecc_tmp >> 16);
300 break;
301
302 default:
303 ecc_tmp = readl(&fsmc_regs_p->ecc1);
304 ecc[0] = (u_char) (ecc_tmp >> 0);
305 ecc[1] = (u_char) (ecc_tmp >> 8);
306 ecc[2] = (u_char) (ecc_tmp >> 16);
307 break;
308 }
309
310 return 0;
311}
312
313void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
314{
315 writel(readl(&fsmc_regs_p->pc) & ~FSMC_ECCPLEN_256,
316 &fsmc_regs_p->pc);
317 writel(readl(&fsmc_regs_p->pc) & ~FSMC_ECCEN,
318 &fsmc_regs_p->pc);
319 writel(readl(&fsmc_regs_p->pc) | FSMC_ECCEN,
320 &fsmc_regs_p->pc);
321}
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
338 uint8_t *buf, int oob_required, int page)
339{
340 struct fsmc_eccplace *fsmc_eccpl;
341 int i, j, s, stat, eccsize = chip->ecc.size;
342 int eccbytes = chip->ecc.bytes;
343 int eccsteps = chip->ecc.steps;
344 uint8_t *p = buf;
345 uint8_t *ecc_calc = chip->buffers->ecccalc;
346 uint8_t *ecc_code = chip->buffers->ecccode;
347 int off, len, group = 0;
348 uint8_t oob[13] __attribute__ ((aligned (2)));
349
350
351 if (mtd->writesize == 512)
352 fsmc_eccpl = &fsmc_eccpl_sp;
353 else
354 fsmc_eccpl = &fsmc_eccpl_lp;
355
356 for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
357
358 chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
359 chip->ecc.hwctl(mtd, NAND_ECC_READ);
360 chip->read_buf(mtd, p, eccsize);
361
362 for (j = 0; j < eccbytes;) {
363 off = fsmc_eccpl->eccplace[group].offset;
364 len = fsmc_eccpl->eccplace[group].length;
365 group++;
366
367
368
369
370
371
372 if (chip->options & NAND_BUSWIDTH_16)
373 len = roundup(len, 2);
374 chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page);
375 chip->read_buf(mtd, oob + j, len);
376 j += len;
377 }
378
379 memcpy(&ecc_code[i], oob, 13);
380 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
381
382 stat = chip->ecc.correct(mtd, p, &ecc_code[i],
383 &ecc_calc[i]);
384 if (stat < 0)
385 mtd->ecc_stats.failed++;
386 else
387 mtd->ecc_stats.corrected += stat;
388 }
389
390 return 0;
391}
392
393#ifndef CONFIG_SPL_BUILD
394
395
396
397
398
399
400int fsmc_nand_switch_ecc(uint32_t eccstrength)
401{
402 struct nand_chip *nand;
403 struct mtd_info *mtd;
404 int err;
405
406
407
408
409
410
411
412 mtd = get_nand_dev_by_index(nand_curr_device);
413 nand = mtd_to_nand(mtd);
414
415
416 if (eccstrength == 1) {
417 nand->ecc.mode = NAND_ECC_HW;
418 nand->ecc.bytes = 3;
419 nand->ecc.strength = 1;
420 nand->ecc.layout = &fsmc_ecc1_layout;
421 nand->ecc.calculate = fsmc_read_hwecc;
422 nand->ecc.correct = nand_correct_data;
423 } else if (eccstrength == 4) {
424
425
426
427
428 nand->ecc.mode = NAND_ECC_SOFT_BCH;
429 nand->ecc.strength = 4;
430 nand->ecc.layout = NULL;
431 } else {
432 printf("Error: ECC strength %d not supported!\n", eccstrength);
433 }
434
435
436 err = nand_scan_tail(mtd);
437
438 return err;
439}
440#endif
441
442int fsmc_nand_init(struct nand_chip *nand)
443{
444 static int chip_nr;
445 struct mtd_info *mtd;
446 u32 peripid2 = readl(&fsmc_regs_p->peripid2);
447
448 fsmc_version = (peripid2 >> FSMC_REVISION_SHFT) &
449 FSMC_REVISION_MSK;
450
451 writel(readl(&fsmc_regs_p->ctrl) | FSMC_WP, &fsmc_regs_p->ctrl);
452
453#if defined(CONFIG_SYS_FSMC_NAND_16BIT)
454 writel(FSMC_DEVWID_16 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
455 &fsmc_regs_p->pc);
456#elif defined(CONFIG_SYS_FSMC_NAND_8BIT)
457 writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
458 &fsmc_regs_p->pc);
459#else
460#error Please define CONFIG_SYS_FSMC_NAND_16BIT or CONFIG_SYS_FSMC_NAND_8BIT
461#endif
462 writel(readl(&fsmc_regs_p->pc) | FSMC_TCLR_1 | FSMC_TAR_1,
463 &fsmc_regs_p->pc);
464 writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
465 &fsmc_regs_p->comm);
466 writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
467 &fsmc_regs_p->attrib);
468
469 nand->options = 0;
470#if defined(CONFIG_SYS_FSMC_NAND_16BIT)
471 nand->options |= NAND_BUSWIDTH_16;
472#endif
473 nand->ecc.mode = NAND_ECC_HW;
474 nand->ecc.size = 512;
475 nand->ecc.calculate = fsmc_read_hwecc;
476 nand->ecc.hwctl = fsmc_enable_hwecc;
477 nand->cmd_ctrl = fsmc_nand_hwcontrol;
478 nand->IO_ADDR_R = nand->IO_ADDR_W =
479 (void __iomem *)CONFIG_SYS_NAND_BASE;
480 nand->badblockbits = 7;
481
482 mtd = nand_to_mtd(nand);
483
484 switch (fsmc_version) {
485 case FSMC_VER8:
486 nand->ecc.bytes = 13;
487 nand->ecc.strength = 8;
488 nand->ecc.correct = fsmc_bch8_correct_data;
489 nand->ecc.read_page = fsmc_read_page_hwecc;
490 if (mtd->writesize == 512)
491 nand->ecc.layout = &fsmc_ecc4_sp_layout;
492 else {
493 if (mtd->oobsize == 224)
494 nand->ecc.layout = &fsmc_ecc4_224_layout;
495 else
496 nand->ecc.layout = &fsmc_ecc4_lp_layout;
497 }
498
499 break;
500 default:
501 nand->ecc.bytes = 3;
502 nand->ecc.strength = 1;
503 nand->ecc.layout = &fsmc_ecc1_layout;
504 nand->ecc.correct = nand_correct_data;
505 break;
506 }
507
508
509 if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL))
510 return -ENXIO;
511
512 if (nand_scan_tail(mtd))
513 return -ENXIO;
514
515 if (nand_register(chip_nr++, mtd))
516 return -ENXIO;
517
518 return 0;
519}
520