blob: 41f84fdc0f68ef1d83c75093af7d914ee403824a [file] [log] [blame]
wdenkdc7c9a12003-03-26 06:55:25 +00001/*
2 * Driver for NAND support, Rick Bronson
3 * borrowed heavily from:
4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 *
7 */
8
9#include <common.h>
wdenkdc7c9a12003-03-26 06:55:25 +000010#include <command.h>
11#include <malloc.h>
12#include <asm/io.h>
13
14#ifdef CONFIG_SHOW_BOOT_PROGRESS
15# include <status_led.h>
16# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
17#else
18# define SHOW_BOOT_PROGRESS(arg)
19#endif
20
21#if (CONFIG_COMMANDS & CFG_CMD_NAND)
22
wdenkdc7c9a12003-03-26 06:55:25 +000023#include <linux/mtd/nand.h>
24#include <linux/mtd/nand_ids.h>
wdenk7a8e9bed2003-05-31 18:35:21 +000025#include <jffs2/jffs2.h>
wdenkdc7c9a12003-03-26 06:55:25 +000026
27/*
28 * Definition of the out of band configuration structure
29 */
30struct nand_oob_config {
31 int ecc_pos[6]; /* position of ECC bytes inside oob */
32 int badblock_pos; /* position of bad block flag inside oob -1 = inactive */
33 int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */
34} oob_config = { {0}, 0, 0};
35
wdenk7a8e9bed2003-05-31 18:35:21 +000036#undef NAND_DEBUG
wdenkdc7c9a12003-03-26 06:55:25 +000037#undef PSYCHO_DEBUG
wdenk7a8e9bed2003-05-31 18:35:21 +000038
39/* ****************** WARNING *********************
40 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
41 * erase (or at least attempt to erase) blocks that are marked
42 * bad. This can be very handy if you are _sure_ that the block
43 * is OK, say because you marked a good block bad to test bad
44 * block handling and you are done testing, or if you have
45 * accidentally marked blocks bad.
46 *
47 * Erasing factory marked bad blocks is a _bad_ idea. If the
48 * erase succeeds there is no reliable way to find them again,
49 * and attempting to program or erase bad blocks can affect
50 * the data in _other_ (good) blocks.
51 */
52#define ALLOW_ERASE_BAD_DEBUG 0
wdenkdc7c9a12003-03-26 06:55:25 +000053
54#define CONFIG_MTD_NAND_ECC /* enable ECC */
55/* #define CONFIG_MTD_NAND_ECC_JFFS2 */
56
wdenk7a8e9bed2003-05-31 18:35:21 +000057/* bits for nand_rw() `cmd'; or together as needed */
58#define NANDRW_READ 0x01
59#define NANDRW_WRITE 0x00
60#define NANDRW_JFFS2 0x02
61
wdenkdc7c9a12003-03-26 06:55:25 +000062/*
63 * Function Prototypes
64 */
65static void nand_print(struct nand_chip *nand);
66static int nand_rw (struct nand_chip* nand, int cmd,
67 size_t start, size_t len,
68 size_t * retlen, u_char * buf);
wdenk7a8e9bed2003-05-31 18:35:21 +000069static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);
wdenkdc7c9a12003-03-26 06:55:25 +000070static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
71 size_t * retlen, u_char *buf, u_char *ecc_code);
72static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
73 size_t * retlen, const u_char * buf, u_char * ecc_code);
wdenk7a8e9bed2003-05-31 18:35:21 +000074static void nand_print_bad(struct nand_chip *nand);
75static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
76 size_t * retlen, u_char * buf);
77static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
78 size_t * retlen, const u_char * buf);
wdenkdc7c9a12003-03-26 06:55:25 +000079#ifdef CONFIG_MTD_NAND_ECC
80static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
81static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
82#endif
83
wdenk7a8e9bed2003-05-31 18:35:21 +000084struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
wdenkdc7c9a12003-03-26 06:55:25 +000085
86/* Current NAND Device */
87static int curr_device = -1;
88
89/* ------------------------------------------------------------------------- */
90
91int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
92{
93 int rcode = 0;
94
95 switch (argc) {
96 case 0:
97 case 1:
98 printf ("Usage:\n%s\n", cmdtp->usage);
99 return 1;
100 case 2:
wdenk8bde7f72003-06-27 21:31:46 +0000101 if (strcmp(argv[1],"info") == 0) {
wdenkdc7c9a12003-03-26 06:55:25 +0000102 int i;
103
104 putc ('\n');
105
106 for (i=0; i<CFG_MAX_NAND_DEVICE; ++i) {
107 if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)
108 continue; /* list only known devices */
109 printf ("Device %d: ", i);
110 nand_print(&nand_dev_desc[i]);
111 }
112 return 0;
113
114 } else if (strcmp(argv[1],"device") == 0) {
115 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
116 puts ("\nno devices available\n");
117 return 1;
118 }
119 printf ("\nDevice %d: ", curr_device);
120 nand_print(&nand_dev_desc[curr_device]);
121 return 0;
wdenk7a8e9bed2003-05-31 18:35:21 +0000122
123 } else if (strcmp(argv[1],"bad") == 0) {
124 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
125 puts ("\nno devices available\n");
126 return 1;
127 }
128 printf ("\nDevice %d bad blocks:\n", curr_device);
129 nand_print_bad(&nand_dev_desc[curr_device]);
130 return 0;
131
wdenkdc7c9a12003-03-26 06:55:25 +0000132 }
133 printf ("Usage:\n%s\n", cmdtp->usage);
134 return 1;
135 case 3:
136 if (strcmp(argv[1],"device") == 0) {
137 int dev = (int)simple_strtoul(argv[2], NULL, 10);
138
139 printf ("\nDevice %d: ", dev);
140 if (dev >= CFG_MAX_NAND_DEVICE) {
141 puts ("unknown device\n");
142 return 1;
143 }
144 nand_print(&nand_dev_desc[dev]);
145 /*nand_print (dev);*/
146
147 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {
148 return 1;
149 }
150
151 curr_device = dev;
152
153 puts ("... is now current device\n");
154
155 return 0;
156 }
wdenk7a8e9bed2003-05-31 18:35:21 +0000157 else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) {
158 struct nand_chip* nand = &nand_dev_desc[curr_device];
159 ulong off = 0;
160 ulong size = nand->totlen;
161 int ret;
162
163 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
164 curr_device, off, size);
165
166 ret = nand_erase (nand, off, size, 1);
167
168 printf("%s\n", ret ? "ERROR" : "OK");
169
170 return ret;
171 }
wdenkdc7c9a12003-03-26 06:55:25 +0000172
173 printf ("Usage:\n%s\n", cmdtp->usage);
174 return 1;
175 default:
176 /* at least 4 args */
177
wdenk7a8e9bed2003-05-31 18:35:21 +0000178 if (strncmp(argv[1], "read", 4) == 0 ||
179 strncmp(argv[1], "write", 5) == 0) {
wdenkdc7c9a12003-03-26 06:55:25 +0000180 ulong addr = simple_strtoul(argv[2], NULL, 16);
181 ulong off = simple_strtoul(argv[3], NULL, 16);
182 ulong size = simple_strtoul(argv[4], NULL, 16);
wdenk7a8e9bed2003-05-31 18:35:21 +0000183 int cmd = (strncmp(argv[1], "read", 4) == 0) ?
184 NANDRW_READ : NANDRW_WRITE;
wdenkdc7c9a12003-03-26 06:55:25 +0000185 int ret, total;
wdenk7a8e9bed2003-05-31 18:35:21 +0000186 char* cmdtail = strchr(argv[1], '.');
187
188 if (cmdtail && !strncmp(cmdtail, ".oob", 2)) {
189 /* read out-of-band data */
190 if (cmd & NANDRW_READ) {
191 ret = nand_read_oob(nand_dev_desc + curr_device,
192 off, size, &total,
193 (u_char*)addr);
194 }
195 else {
196 ret = nand_write_oob(nand_dev_desc + curr_device,
197 off, size, &total,
198 (u_char*)addr);
199 }
200 return ret;
201 }
202 else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
203 cmd |= NANDRW_JFFS2; /* skip bad blocks */
204#ifdef SXNI855T
205 /* need ".e" same as ".j" for compatibility with older units */
206 else if (cmdtail && !strcmp(cmdtail, ".e"))
207 cmd |= NANDRW_JFFS2; /* skip bad blocks */
208#endif
209 else if (cmdtail) {
210 printf ("Usage:\n%s\n", cmdtp->usage);
211 return 1;
212 }
wdenkdc7c9a12003-03-26 06:55:25 +0000213
214 printf ("\nNAND %s: device %d offset %ld, size %ld ... ",
wdenk7a8e9bed2003-05-31 18:35:21 +0000215 (cmd & NANDRW_READ) ? "read" : "write",
216 curr_device, off, size);
wdenkdc7c9a12003-03-26 06:55:25 +0000217
218 ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size,
219 &total, (u_char*)addr);
220
wdenk7a8e9bed2003-05-31 18:35:21 +0000221 printf ("%d bytes %s: %s\n", total,
222 (cmd & NANDRW_READ) ? "read" : "write",
wdenkdc7c9a12003-03-26 06:55:25 +0000223 ret ? "ERROR" : "OK");
224
225 return ret;
wdenk7a8e9bed2003-05-31 18:35:21 +0000226 } else if (strcmp(argv[1],"erase") == 0 &&
227 (argc == 4 || strcmp("clean", argv[2]) == 0)) {
228 int clean = argc == 5;
229 ulong off = simple_strtoul(argv[2 + clean], NULL, 16);
230 ulong size = simple_strtoul(argv[3 + clean], NULL, 16);
wdenkdc7c9a12003-03-26 06:55:25 +0000231 int ret;
232
233 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
234 curr_device, off, size);
235
wdenk7a8e9bed2003-05-31 18:35:21 +0000236 ret = nand_erase (nand_dev_desc + curr_device, off, size, clean);
wdenkdc7c9a12003-03-26 06:55:25 +0000237
238 printf("%s\n", ret ? "ERROR" : "OK");
239
240 return ret;
241 } else {
242 printf ("Usage:\n%s\n", cmdtp->usage);
243 rcode = 1;
244 }
245
246 return rcode;
247 }
248}
249
250int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
251{
252 char *boot_device = NULL;
253 char *ep;
254 int dev;
255 ulong cnt;
256 ulong addr;
257 ulong offset = 0;
258 image_header_t *hdr;
259 int rcode = 0;
260 switch (argc) {
261 case 1:
262 addr = CFG_LOAD_ADDR;
263 boot_device = getenv ("bootdevice");
264 break;
265 case 2:
266 addr = simple_strtoul(argv[1], NULL, 16);
267 boot_device = getenv ("bootdevice");
268 break;
269 case 3:
270 addr = simple_strtoul(argv[1], NULL, 16);
271 boot_device = argv[2];
272 break;
273 case 4:
274 addr = simple_strtoul(argv[1], NULL, 16);
275 boot_device = argv[2];
276 offset = simple_strtoul(argv[3], NULL, 16);
277 break;
278 default:
279 printf ("Usage:\n%s\n", cmdtp->usage);
280 SHOW_BOOT_PROGRESS (-1);
281 return 1;
282 }
283
284 if (!boot_device) {
285 puts ("\n** No boot device **\n");
286 SHOW_BOOT_PROGRESS (-1);
287 return 1;
288 }
289
290 dev = simple_strtoul(boot_device, &ep, 16);
291
292 if ((dev >= CFG_MAX_NAND_DEVICE) ||
293 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {
294 printf ("\n** Device %d not available\n", dev);
295 SHOW_BOOT_PROGRESS (-1);
296 return 1;
297 }
298
wdenk7a8e9bed2003-05-31 18:35:21 +0000299 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
wdenkdc7c9a12003-03-26 06:55:25 +0000300 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
301 offset);
302
wdenk7a8e9bed2003-05-31 18:35:21 +0000303 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset,
wdenkdc7c9a12003-03-26 06:55:25 +0000304 SECTORSIZE, NULL, (u_char *)addr)) {
305 printf ("** Read error on %d\n", dev);
306 SHOW_BOOT_PROGRESS (-1);
307 return 1;
308 }
309
310 hdr = (image_header_t *)addr;
311
312 if (ntohl(hdr->ih_magic) == IH_MAGIC) {
313
314 print_image_hdr (hdr);
315
316 cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
317 cnt -= SECTORSIZE;
318 } else {
319 printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
320 SHOW_BOOT_PROGRESS (-1);
321 return 1;
322 }
323
wdenk7a8e9bed2003-05-31 18:35:21 +0000324 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt,
wdenkdc7c9a12003-03-26 06:55:25 +0000325 NULL, (u_char *)(addr+SECTORSIZE))) {
326 printf ("** Read error on %d\n", dev);
327 SHOW_BOOT_PROGRESS (-1);
328 return 1;
329 }
330
331 /* Loading ok, update default load address */
332
333 load_addr = addr;
334
335 /* Check if we should attempt an auto-start */
336 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
337 char *local_args[2];
338 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
339
340 local_args[0] = argv[0];
341 local_args[1] = NULL;
342
wdenk7a8e9bed2003-05-31 18:35:21 +0000343 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);
wdenkdc7c9a12003-03-26 06:55:25 +0000344
345 do_bootm (cmdtp, 0, 1, local_args);
346 rcode = 1;
347 }
348 return rcode;
349}
350
wdenk7a8e9bed2003-05-31 18:35:21 +0000351/* returns 0 if block containing pos is OK:
352 * valid erase block and
353 * not marked bad, or no bad mark position is specified
354 * returns 1 if marked bad or otherwise invalid
355 */
356int check_block(struct nand_chip* nand, unsigned long pos)
357{
358 int retlen;
359 uint8_t oob_data;
360 int page0 = pos & (-nand->erasesize);
361 int page1 = page0 + nand->oobblock;
362 int badpos = oob_config.badblock_pos;
363
364 if (pos >= nand->totlen)
365 return 1;
366
367 if (badpos < 0)
368 return 0; /* no way to check, assume OK */
369
370 /* Note - bad block marker can be on first or second page */
371 if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data) ||
372 oob_data != 0xff ||
373 nand_read_oob(nand, page1 + badpos, 1, &retlen, &oob_data) ||
374 oob_data != 0xff)
375 return 1;
376
377 return 0;
378}
wdenk8bde7f72003-06-27 21:31:46 +0000379
wdenk7a8e9bed2003-05-31 18:35:21 +0000380/* print bad blocks in NAND flash */
381static void nand_print_bad(struct nand_chip* nand)
382{
383 unsigned long pos;
384
385 for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
386 if (check_block(nand, pos))
387 printf(" 0x%8.8lx\n", pos);
388 }
389 puts("\n");
390}
391
392/* cmd: 0: NANDRW_WRITE write, fail on bad block
393 * 1: NANDRW_READ read, fail on bad block
394 * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
395 * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
396 */
wdenkdc7c9a12003-03-26 06:55:25 +0000397static int nand_rw (struct nand_chip* nand, int cmd,
398 size_t start, size_t len,
399 size_t * retlen, u_char * buf)
400{
401 int noecc, ret = 0, n, total = 0;
402 char eccbuf[6];
wdenk7a8e9bed2003-05-31 18:35:21 +0000403 /* eblk (once set) is the start of the erase block containing the
404 * data being processed.
405 */
406 unsigned long eblk = ~0; /* force mismatch on first pass */
407 unsigned long erasesize = nand->erasesize;
wdenkdc7c9a12003-03-26 06:55:25 +0000408
wdenk7a8e9bed2003-05-31 18:35:21 +0000409 while (len) {
410 if ((start & (-erasesize)) != eblk) {
411 /* have crossed into new erase block, deal with
412 * it if it is sure marked bad.
413 */
414 eblk = start & (-erasesize); /* start of block */
415 if (check_block(nand, eblk)) {
416 if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
417 while (len > 0 &&
418 start - eblk < erasesize) {
419 *(buf++) = 0xff;
420 ++start;
421 ++total;
422 --len;
423 }
424 continue;
425 }
426 else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
427 /* skip bad block */
428 start += erasesize;
429 continue;
430 }
431 else {
432 ret = 1;
433 break;
434 }
435 }
436 }
wdenkdc7c9a12003-03-26 06:55:25 +0000437 /* The ECC will not be calculated correctly if
438 less than 512 is written or read */
439 noecc = (start != (start | 0x1ff) + 1) || (len < 0x200);
wdenk7a8e9bed2003-05-31 18:35:21 +0000440 if (cmd & NANDRW_READ)
441 ret = nand_read_ecc(nand, start,
442 min(len, eblk + erasesize - start),
wdenkdc7c9a12003-03-26 06:55:25 +0000443 &n, (u_char*)buf,
444 noecc ? NULL : eccbuf);
445 else
wdenk7a8e9bed2003-05-31 18:35:21 +0000446 ret = nand_write_ecc(nand, start,
447 min(len, eblk + erasesize - start),
wdenkdc7c9a12003-03-26 06:55:25 +0000448 &n, (u_char*)buf,
449 noecc ? NULL : eccbuf);
450
451 if (ret)
452 break;
453
454 start += n;
455 buf += n;
456 total += n;
457 len -= n;
458 }
459 if (retlen)
460 *retlen = total;
461
462 return ret;
463}
464
465static void nand_print(struct nand_chip *nand)
wdenk0db5bca2003-03-31 17:27:09 +0000466{
wdenk7a8e9bed2003-05-31 18:35:21 +0000467 if (nand->numchips > 1) {
468 printf("%s at 0x%lx,\n"
469 "\t %d chips %s, size %d MB, \n"
470 "\t total size %ld MB, sector size %ld kB\n",
471 nand->name, nand->IO_ADDR, nand->numchips,
472 nand->chips_name, 1 << (nand->chipshift - 20),
473 nand->totlen >> 20, nand->erasesize >> 10);
474 }
475 else {
wdenk8bde7f72003-06-27 21:31:46 +0000476 printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
wdenk7a8e9bed2003-05-31 18:35:21 +0000477 print_size(nand->totlen, ", ");
478 print_size(nand->erasesize, " sector)\n");
wdenkdc7c9a12003-03-26 06:55:25 +0000479 }
480}
481
482/* ------------------------------------------------------------------------- */
483
484/* This function is needed to avoid calls of the __ashrdi3 function. */
wdenk0db5bca2003-03-31 17:27:09 +0000485#if 0
wdenkdc7c9a12003-03-26 06:55:25 +0000486static int shr(int val, int shift)
wdenk0db5bca2003-03-31 17:27:09 +0000487{
wdenkdc7c9a12003-03-26 06:55:25 +0000488 return val >> shift;
489}
wdenk0db5bca2003-03-31 17:27:09 +0000490#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000491static int NanD_WaitReady(struct nand_chip *nand)
492{
493 /* This is inline, to optimise the common case, where it's ready instantly */
494 int ret = 0;
wdenk0db5bca2003-03-31 17:27:09 +0000495 NAND_WAIT_READY(nand);
wdenkdc7c9a12003-03-26 06:55:25 +0000496
497 return ret;
498}
499
500/* NanD_Command: Send a flash command to the flash chip */
501
502static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
503{
504 unsigned long nandptr = nand->IO_ADDR;
505
506 /* Assert the CLE (Command Latch Enable) line to the flash chip */
507 NAND_CTL_SETCLE(nandptr);
508
509 /* Send the command */
510 WRITE_NAND_COMMAND(command, nandptr);
511
512 /* Lower the CLE line */
513 NAND_CTL_CLRCLE(nandptr);
514
515 return NanD_WaitReady(nand);
516}
517
518/* NanD_Address: Set the current address for the flash chip */
519
520static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
wdenk0db5bca2003-03-31 17:27:09 +0000521{
522 unsigned long nandptr;
523 int i;
wdenkdc7c9a12003-03-26 06:55:25 +0000524
wdenk0db5bca2003-03-31 17:27:09 +0000525 nandptr = nand->IO_ADDR;
wdenkdc7c9a12003-03-26 06:55:25 +0000526
527 /* Assert the ALE (Address Latch Enable) line to the flash chip */
wdenk0db5bca2003-03-31 17:27:09 +0000528 NAND_CTL_SETALE(nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000529
wdenk0db5bca2003-03-31 17:27:09 +0000530 /* Send the address */
531 /* Devices with 256-byte page are addressed as:
532 * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
533 * there is no device on the market with page256
534 * and more than 24 bits.
535 * Devices with 512-byte page are addressed as:
536 * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
537 * 25-31 is sent only if the chip support it.
538 * bit 8 changes the read command to be sent
539 * (NAND_CMD_READ0 or NAND_CMD_READ1).
wdenkdc7c9a12003-03-26 06:55:25 +0000540 */
541
wdenk0db5bca2003-03-31 17:27:09 +0000542 if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
543 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000544
wdenk0db5bca2003-03-31 17:27:09 +0000545 ofs = ofs >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000546
wdenk0db5bca2003-03-31 17:27:09 +0000547 if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
548 for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8)
549 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000550
wdenk0db5bca2003-03-31 17:27:09 +0000551 /* Lower the ALE line */
552 NAND_CTL_CLRALE(nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000553
wdenk0db5bca2003-03-31 17:27:09 +0000554 /* Wait for the chip to respond */
555 return NanD_WaitReady(nand);
556}
wdenkdc7c9a12003-03-26 06:55:25 +0000557
558/* NanD_SelectChip: Select a given flash chip within the current floor */
559
560static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
561{
562 /* Wait for it to be ready */
563 return NanD_WaitReady(nand);
564}
565
566/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
567
568static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
569{
570 int mfr, id, i;
571
wdenk0db5bca2003-03-31 17:27:09 +0000572 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +0000573 /* Reset the chip */
574 if (NanD_Command(nand, NAND_CMD_RESET)) {
575#ifdef NAND_DEBUG
576 printf("NanD_Command (reset) for %d,%d returned true\n",
577 floor, chip);
578#endif
wdenk0db5bca2003-03-31 17:27:09 +0000579 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000580 return 0;
581 }
582
583 /* Read the NAND chip ID: 1. Send ReadID command */
584 if (NanD_Command(nand, NAND_CMD_READID)) {
585#ifdef NAND_DEBUG
586 printf("NanD_Command (ReadID) for %d,%d returned true\n",
587 floor, chip);
588#endif
wdenk0db5bca2003-03-31 17:27:09 +0000589 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000590 return 0;
591 }
592
593 /* Read the NAND chip ID: 2. Send address byte zero */
594 NanD_Address(nand, ADDR_COLUMN, 0);
595
596 /* Read the manufacturer and device id codes from the device */
597
598 mfr = READ_NAND(nand->IO_ADDR);
599
600 id = READ_NAND(nand->IO_ADDR);
601
wdenk8bde7f72003-06-27 21:31:46 +0000602 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000603 /* No response - return failure */
wdenk0db5bca2003-03-31 17:27:09 +0000604 if (mfr == 0xff || mfr == 0) {
605 printf("NanD_Command (ReadID) got %d %d\n", mfr, id);
606 return 0;
607 }
wdenkdc7c9a12003-03-26 06:55:25 +0000608
609 /* Check it's the same as the first chip we identified.
610 * M-Systems say that any given nand_chip device should only
611 * contain _one_ type of flash part, although that's not a
612 * hardware restriction. */
613 if (nand->mfr) {
614 if (nand->mfr == mfr && nand->id == id)
615 return 1; /* This is another the same the first */
616 else
617 printf("Flash chip at floor %d, chip %d is different:\n",
618 floor, chip);
619 }
620
621 /* Print and store the manufacturer and ID codes. */
622 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
623 if (mfr == nand_flash_ids[i].manufacture_id &&
624 id == nand_flash_ids[i].model_id) {
625#ifdef NAND_DEBUG
626 printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
627 "Chip ID: 0x%2.2X (%s)\n", mfr, id,
628 nand_flash_ids[i].name);
629#endif
630 if (!nand->mfr) {
631 nand->mfr = mfr;
632 nand->id = id;
633 nand->chipshift =
634 nand_flash_ids[i].chipshift;
635 nand->page256 = nand_flash_ids[i].page256;
wdenk7a8e9bed2003-05-31 18:35:21 +0000636 nand->eccsize = 256;
wdenkdc7c9a12003-03-26 06:55:25 +0000637 if (nand->page256) {
638 nand->oobblock = 256;
639 nand->oobsize = 8;
640 nand->page_shift = 8;
641 } else {
642 nand->oobblock = 512;
643 nand->oobsize = 16;
644 nand->page_shift = 9;
645 }
646 nand->pageadrlen =
647 nand_flash_ids[i].pageadrlen;
648 nand->erasesize =
649 nand_flash_ids[i].erasesize;
650 nand->chips_name =
651 nand_flash_ids[i].name;
652 return 1;
653 }
654 return 0;
655 }
656 }
657
658
659#ifdef NAND_DEBUG
660 /* We haven't fully identified the chip. Print as much as we know. */
661 printf("Unknown flash chip found: %2.2X %2.2X\n",
662 id, mfr);
663#endif
664
665 return 0;
666}
667
668/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
669
670static void NanD_ScanChips(struct nand_chip *nand)
671{
672 int floor, chip;
673 int numchips[NAND_MAX_FLOORS];
674 int maxchips = NAND_MAX_CHIPS;
675 int ret = 1;
676
677 nand->numchips = 0;
678 nand->mfr = 0;
679 nand->id = 0;
680
681
682 /* For each floor, find the number of valid chips it contains */
683 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
684 ret = 1;
685 numchips[floor] = 0;
686 for (chip = 0; chip < maxchips && ret != 0; chip++) {
687
688 ret = NanD_IdentChip(nand, floor, chip);
689 if (ret) {
690 numchips[floor]++;
691 nand->numchips++;
692 }
693 }
694 }
695
696 /* If there are none at all that we recognise, bail */
697 if (!nand->numchips) {
698 puts ("No flash chips recognised.\n");
699 return;
700 }
701
702 /* Allocate an array to hold the information for each chip */
703 nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
704 if (!nand->chips) {
705 puts ("No memory for allocating chip info structures\n");
706 return;
707 }
708
709 ret = 0;
710
711 /* Fill out the chip array with {floor, chipno} for each
712 * detected chip in the device. */
713 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
714 for (chip = 0; chip < numchips[floor]; chip++) {
715 nand->chips[ret].floor = floor;
716 nand->chips[ret].chip = chip;
717 nand->chips[ret].curadr = 0;
718 nand->chips[ret].curmode = 0x50;
719 ret++;
720 }
721 }
722
723 /* Calculate and print the total size of the device */
724 nand->totlen = nand->numchips * (1 << nand->chipshift);
725
726#ifdef NAND_DEBUG
727 printf("%d flash chips found. Total nand_chip size: %ld MB\n",
728 nand->numchips, nand->totlen >> 20);
729#endif
730}
wdenk0db5bca2003-03-31 17:27:09 +0000731
wdenkdc7c9a12003-03-26 06:55:25 +0000732/* we need to be fast here, 1 us per read translates to 1 second per meg */
wdenk7a8e9bed2003-05-31 18:35:21 +0000733static void NanD_ReadBuf(struct nand_chip *nand, u_char *data_buf, int cntr)
wdenk0db5bca2003-03-31 17:27:09 +0000734{
wdenk7a8e9bed2003-05-31 18:35:21 +0000735 unsigned long nandptr = nand->IO_ADDR;
wdenk0db5bca2003-03-31 17:27:09 +0000736
wdenk7a8e9bed2003-05-31 18:35:21 +0000737 while (cntr >= 16) {
wdenk0db5bca2003-03-31 17:27:09 +0000738 *data_buf++ = READ_NAND(nandptr);
739 *data_buf++ = READ_NAND(nandptr);
740 *data_buf++ = READ_NAND(nandptr);
741 *data_buf++ = READ_NAND(nandptr);
742 *data_buf++ = READ_NAND(nandptr);
743 *data_buf++ = READ_NAND(nandptr);
744 *data_buf++ = READ_NAND(nandptr);
745 *data_buf++ = READ_NAND(nandptr);
746 *data_buf++ = READ_NAND(nandptr);
747 *data_buf++ = READ_NAND(nandptr);
748 *data_buf++ = READ_NAND(nandptr);
749 *data_buf++ = READ_NAND(nandptr);
750 *data_buf++ = READ_NAND(nandptr);
751 *data_buf++ = READ_NAND(nandptr);
752 *data_buf++ = READ_NAND(nandptr);
753 *data_buf++ = READ_NAND(nandptr);
754 cntr -= 16;
755 }
756
757 while (cntr > 0) {
758 *data_buf++ = READ_NAND(nandptr);
759 cntr--;
760 }
761}
wdenkdc7c9a12003-03-26 06:55:25 +0000762
wdenkdc7c9a12003-03-26 06:55:25 +0000763/*
764 * NAND read with ECC
765 */
766static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
767 size_t * retlen, u_char *buf, u_char *ecc_code)
768{
769 int col, page;
770 int ecc_status = 0;
771#ifdef CONFIG_MTD_NAND_ECC
772 int j;
773 int ecc_failed = 0;
774 u_char *data_poi;
775 u_char ecc_calc[6];
776#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000777
778 /* Do not allow reads past end of device */
779 if ((start + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +0000780 printf ("%s: Attempt read beyond end of device %x %x %x\n", __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000781 *retlen = 0;
782 return -1;
783 }
784
785 /* First we calculate the starting page */
wdenk0db5bca2003-03-31 17:27:09 +0000786 /*page = shr(start, nand->page_shift);*/
787 page = start >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000788
789 /* Get raw starting column */
790 col = start & (nand->oobblock - 1);
791
792 /* Initialize return value */
793 *retlen = 0;
794
795 /* Select the NAND device */
796 NAND_ENABLE_CE(nand); /* set pin low */
797
798 /* Loop until all data read */
799 while (*retlen < len) {
800
801
802#ifdef CONFIG_MTD_NAND_ECC
803
804 /* Do we have this page in cache ? */
805 if (nand->cache_page == page)
806 goto readdata;
807 /* Send the read command */
808 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000809 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000810 /* Read in a page + oob data */
wdenk7a8e9bed2003-05-31 18:35:21 +0000811 NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
wdenkdc7c9a12003-03-26 06:55:25 +0000812
813 /* copy data into cache, for read out of cache and if ecc fails */
814 if (nand->data_cache)
815 memcpy (nand->data_cache, nand->data_buf, nand->oobblock + nand->oobsize);
816
817 /* Pick the ECC bytes out of the oob data */
818 for (j = 0; j < 6; j++)
819 ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
820
821 /* Calculate the ECC and verify it */
822 /* If block was not written with ECC, skip ECC */
823 if (oob_config.eccvalid_pos != -1 &&
824 (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
825
826 nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
827 switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
828 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000829 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000830 ecc_failed++;
831 break;
832 case 1:
833 case 2: /* transfer ECC corrected data to cache */
wdenk7a8e9bed2003-05-31 18:35:21 +0000834 if (nand->data_cache)
835 memcpy (nand->data_cache, nand->data_buf, 256);
wdenkdc7c9a12003-03-26 06:55:25 +0000836 break;
837 }
838 }
839
840 if (oob_config.eccvalid_pos != -1 &&
841 nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
842
843 nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
844 switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
845 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000846 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000847 ecc_failed++;
848 break;
849 case 1:
850 case 2: /* transfer ECC corrected data to cache */
851 if (nand->data_cache)
852 memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
853 break;
854 }
855 }
856readdata:
857 /* Read the data from ECC data buffer into return buffer */
858 data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
859 data_poi += col;
860 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000861 memcpy (buf + *retlen, data_poi, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000862 *retlen = len;
863 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000864 memcpy (buf + *retlen, data_poi, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000865 *retlen += nand->oobblock - col;
866 }
867 /* Set cache page address, invalidate, if ecc_failed */
868 nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
869
870 ecc_status += ecc_failed;
871 ecc_failed = 0;
872
873#else
874 /* Send the read command */
875 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000876 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000877 /* Read the data directly into the return buffer */
878 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000879 NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000880 *retlen = len;
881 /* We're done */
882 continue;
883 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000884 NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000885 *retlen += nand->oobblock - col;
886 }
887#endif
888 /* For subsequent reads align to page boundary. */
889 col = 0;
890 /* Increment page address */
891 page++;
892 }
893
894 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +0000895 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000896
897 /*
898 * Return success, if no ECC failures, else -EIO
899 * fs driver will take care of that, because
900 * retlen == desired len and result == -EIO
901 */
902 return ecc_status ? -1 : 0;
903}
904
wdenkdc7c9a12003-03-26 06:55:25 +0000905/*
906 * Nand_page_program function is used for write and writev !
907 */
908static int nand_write_page (struct nand_chip *nand,
909 int page, int col, int last, u_char * ecc_code)
910{
911
912 int i;
913#ifdef CONFIG_MTD_NAND_ECC
914 unsigned long nandptr = nand->IO_ADDR;
915#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
916 int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
917#endif
918#endif
919 /* pad oob area */
920 for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
921 nand->data_buf[i] = 0xff;
922
923#ifdef CONFIG_MTD_NAND_ECC
924 /* Zero out the ECC array */
925 for (i = 0; i < 6; i++)
926 ecc_code[i] = 0x00;
927
928 /* Read back previous written data, if col > 0 */
929 if (col) {
930 NanD_Command(nand, NAND_CMD_READ0);
wdenk0db5bca2003-03-31 17:27:09 +0000931 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000932 for (i = 0; i < col; i++)
933 nand->data_buf[i] = READ_NAND (nandptr);
934 }
935
936 /* Calculate and write the ECC if we have enough data */
937 if ((col < nand->eccsize) && (last >= nand->eccsize)) {
938 nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
939 for (i = 0; i < 3; i++)
940 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
941 if (oob_config.eccvalid_pos != -1)
942 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] = 0xf0;
943 }
944
945 /* Calculate and write the second ECC if we have enough data */
946 if ((nand->oobblock == 512) && (last == nand->oobblock)) {
947 nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
948 for (i = 3; i < 6; i++)
949 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
950 if (oob_config.eccvalid_pos != -1)
951 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] &= 0x0f;
952 }
953#endif
954 /* Prepad for partial page programming !!! */
955 for (i = 0; i < col; i++)
956 nand->data_buf[i] = 0xff;
957
958 /* Postpad for partial page programming !!! oob is already padded */
959 for (i = last; i < nand->oobblock; i++)
960 nand->data_buf[i] = 0xff;
961
962 /* Send command to begin auto page programming */
wdenk7a8e9bed2003-05-31 18:35:21 +0000963 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +0000964 NanD_Command(nand, NAND_CMD_SEQIN);
965 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
966
967 /* Write out complete page of data */
968 for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
wdenk0db5bca2003-03-31 17:27:09 +0000969 WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
wdenkdc7c9a12003-03-26 06:55:25 +0000970
971 /* Send command to actually program the data */
wdenk0db5bca2003-03-31 17:27:09 +0000972 NanD_Command(nand, NAND_CMD_PAGEPROG);
973 NanD_Command(nand, NAND_CMD_STATUS);
wdenkdc7c9a12003-03-26 06:55:25 +0000974
975 /* See if device thinks it succeeded */
976 if (READ_NAND(nand->IO_ADDR) & 0x01) {
wdenk0db5bca2003-03-31 17:27:09 +0000977 printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000978 return -1;
979 }
980#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
981 /*
982 * The NAND device assumes that it is always writing to
983 * a cleanly erased page. Hence, it performs its internal
984 * write verification only on bits that transitioned from
985 * 1 to 0. The device does NOT verify the whole page on a
986 * byte by byte basis. It is possible that the page was
987 * not completely erased or the page is becoming unusable
988 * due to wear. The read with ECC would catch the error
989 * later when the ECC page check fails, but we would rather
990 * catch it early in the page write stage. Better to write
991 * no data than invalid data.
992 */
993
994 /* Send command to read back the page */
995 if (col < nand->eccsize)
wdenk0db5bca2003-03-31 17:27:09 +0000996 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +0000997 else
wdenk0db5bca2003-03-31 17:27:09 +0000998 NanD_Command(nand, NAND_CMD_READ1);
999 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +00001000
1001 /* Loop through and verify the data */
1002 for (i = col; i < last; i++) {
1003 if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
wdenk0db5bca2003-03-31 17:27:09 +00001004 printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001005 return -1;
1006 }
1007 }
1008
1009#ifdef CONFIG_MTD_NAND_ECC
1010 /*
1011 * We also want to check that the ECC bytes wrote
1012 * correctly for the same reasons stated above.
1013 */
1014 NanD_Command(nand, NAND_CMD_READOOB);
1015 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1016 for (i = 0; i < nand->oobsize; i++)
1017 nand->data_buf[i] = readb (nand->IO_ADDR);
1018 for (i = 0; i < ecc_bytes; i++) {
1019 if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
wdenk0db5bca2003-03-31 17:27:09 +00001020 printf ("%s: Failed ECC write "
1021 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
wdenkdc7c9a12003-03-26 06:55:25 +00001022 return -1;
1023 }
1024 }
1025#endif
1026#endif
1027 return 0;
1028}
wdenk0db5bca2003-03-31 17:27:09 +00001029
wdenkdc7c9a12003-03-26 06:55:25 +00001030static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
1031 size_t * retlen, const u_char * buf, u_char * ecc_code)
1032{
1033 int i, page, col, cnt, ret = 0;
1034
1035 /* Do not allow write past end of device */
1036 if ((to + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +00001037 printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001038 return -1;
1039 }
1040
1041 /* Shift to get page */
1042 page = ((int) to) >> nand->page_shift;
1043
1044 /* Get the starting column */
1045 col = to & (nand->oobblock - 1);
1046
1047 /* Initialize return length value */
1048 *retlen = 0;
1049
1050 /* Select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +00001051 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001052
1053 /* Check the WP bit */
wdenk0db5bca2003-03-31 17:27:09 +00001054 NanD_Command(nand, NAND_CMD_STATUS);
wdenkdc7c9a12003-03-26 06:55:25 +00001055 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
wdenk0db5bca2003-03-31 17:27:09 +00001056 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001057 ret = -1;
1058 goto out;
1059 }
1060
1061 /* Loop until all data is written */
1062 while (*retlen < len) {
1063 /* Invalidate cache, if we write to this page */
1064 if (nand->cache_page == page)
1065 nand->cache_page = -1;
1066
1067 /* Write data into buffer */
1068 if ((col + len) >= nand->oobblock)
1069 for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++)
1070 nand->data_buf[i] = buf[(*retlen + cnt)];
1071 else
1072 for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++)
1073 nand->data_buf[i] = buf[(*retlen + cnt)];
1074 /* We use the same function for write and writev !) */
1075 ret = nand_write_page (nand, page, col, i, ecc_code);
1076 if (ret)
1077 goto out;
1078
1079 /* Next data start at page boundary */
1080 col = 0;
1081
1082 /* Update written bytes count */
1083 *retlen += cnt;
1084
1085 /* Increment page address */
1086 page++;
1087 }
1088
1089 /* Return happy */
1090 *retlen = len;
1091
1092out:
1093 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +00001094 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001095
1096 return ret;
1097}
1098
wdenk7a8e9bed2003-05-31 18:35:21 +00001099/* read from the 16 bytes of oob data that correspond to a 512 byte
1100 * page or 2 256-byte pages.
wdenkdc7c9a12003-03-26 06:55:25 +00001101 */
wdenkdc7c9a12003-03-26 06:55:25 +00001102static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
wdenk7a8e9bed2003-05-31 18:35:21 +00001103 size_t * retlen, u_char * buf)
wdenkdc7c9a12003-03-26 06:55:25 +00001104{
wdenk7a8e9bed2003-05-31 18:35:21 +00001105 int len256 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001106 struct Nand *mychip;
wdenk0db5bca2003-03-31 17:27:09 +00001107 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001108
wdenk7a8e9bed2003-05-31 18:35:21 +00001109 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001110
1111 /* update address for 2M x 8bit devices. OOB starts on the second */
1112 /* page to maintain compatibility with nand_read_ecc. */
1113 if (nand->page256) {
1114 if (!(ofs & 0x8))
1115 ofs += 0x100;
1116 else
1117 ofs -= 0x8;
1118 }
1119
wdenk7a8e9bed2003-05-31 18:35:21 +00001120 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001121 NanD_Command(nand, NAND_CMD_READOOB);
1122 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1123
1124 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1125 /* Note: datasheet says it should automaticaly wrap to the */
1126 /* next OOB block, but it didn't work here. mf. */
1127 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1128 len256 = (ofs | 0x7) + 1 - ofs;
1129 NanD_ReadBuf(nand, buf, len256);
1130
1131 NanD_Command(nand, NAND_CMD_READOOB);
1132 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1133 }
1134
1135 NanD_ReadBuf(nand, &buf[len256], len - len256);
1136
1137 *retlen = len;
1138 /* Reading the full OOB data drops us off of the end of the page,
wdenk8bde7f72003-06-27 21:31:46 +00001139 * causing the flash device to go into busy mode, so we need
1140 * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
wdenkdc7c9a12003-03-26 06:55:25 +00001141
1142 ret = NanD_WaitReady(nand);
wdenk8bde7f72003-06-27 21:31:46 +00001143 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001144
1145 return ret;
1146
1147}
wdenk7a8e9bed2003-05-31 18:35:21 +00001148
1149/* write to the 16 bytes of oob data that correspond to a 512 byte
1150 * page or 2 256-byte pages.
1151 */
wdenkdc7c9a12003-03-26 06:55:25 +00001152static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
1153 size_t * retlen, const u_char * buf)
1154{
1155 int len256 = 0;
wdenk7a8e9bed2003-05-31 18:35:21 +00001156 int i;
wdenkdc7c9a12003-03-26 06:55:25 +00001157 unsigned long nandptr = nand->IO_ADDR;
1158
1159#ifdef PSYCHO_DEBUG
1160 printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1161 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1162 buf[8], buf[9], buf[14],buf[15]);
1163#endif
1164
wdenk7a8e9bed2003-05-31 18:35:21 +00001165 NAND_ENABLE_CE(nand); /* set pin low to enable chip */
1166
wdenkdc7c9a12003-03-26 06:55:25 +00001167 /* Reset the chip */
1168 NanD_Command(nand, NAND_CMD_RESET);
1169
1170 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1171 NanD_Command(nand, NAND_CMD_READOOB);
1172 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1173
1174 /* update address for 2M x 8bit devices. OOB starts on the second */
1175 /* page to maintain compatibility with nand_read_ecc. */
1176 if (nand->page256) {
1177 if (!(ofs & 0x8))
1178 ofs += 0x100;
1179 else
1180 ofs -= 0x8;
1181 }
1182
1183 /* issue the Serial Data In command to initial the Page Program process */
1184 NanD_Command(nand, NAND_CMD_SEQIN);
1185 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1186
1187 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1188 /* Note: datasheet says it should automaticaly wrap to the */
1189 /* next OOB block, but it didn't work here. mf. */
1190 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1191 len256 = (ofs | 0x7) + 1 - ofs;
wdenk7a8e9bed2003-05-31 18:35:21 +00001192 for (i = 0; i < len256; i++)
1193 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001194
1195 NanD_Command(nand, NAND_CMD_PAGEPROG);
1196 NanD_Command(nand, NAND_CMD_STATUS);
1197 /* NanD_WaitReady() is implicit in NanD_Command */
1198
1199 if (READ_NAND(nandptr) & 1) {
1200 puts ("Error programming oob data\n");
1201 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001202 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001203 *retlen = 0;
1204 return -1;
1205 }
1206 NanD_Command(nand, NAND_CMD_SEQIN);
1207 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1208 }
1209
wdenk7a8e9bed2003-05-31 18:35:21 +00001210 for (i = len256; i < len; i++)
1211 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001212
1213 NanD_Command(nand, NAND_CMD_PAGEPROG);
1214 NanD_Command(nand, NAND_CMD_STATUS);
1215 /* NanD_WaitReady() is implicit in NanD_Command */
1216
1217 if (READ_NAND(nandptr) & 1) {
1218 puts ("Error programming oob data\n");
1219 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001220 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001221 *retlen = 0;
1222 return -1;
1223 }
1224
wdenk7a8e9bed2003-05-31 18:35:21 +00001225 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001226 *retlen = len;
1227 return 0;
1228
1229}
wdenkdc7c9a12003-03-26 06:55:25 +00001230
wdenk7a8e9bed2003-05-31 18:35:21 +00001231static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
wdenkdc7c9a12003-03-26 06:55:25 +00001232{
wdenk7a8e9bed2003-05-31 18:35:21 +00001233 /* This is defined as a structure so it will work on any system
1234 * using native endian jffs2 (the default).
1235 */
1236 static struct jffs2_unknown_node clean_marker = {
1237 JFFS2_MAGIC_BITMASK,
1238 JFFS2_NODETYPE_CLEANMARKER,
1239 8 /* 8 bytes in this node */
1240 };
wdenkdc7c9a12003-03-26 06:55:25 +00001241 unsigned long nandptr;
1242 struct Nand *mychip;
wdenk85ec0bc2003-03-31 16:34:49 +00001243 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001244
1245 if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
1246 printf ("Offset and size must be sector aligned, erasesize = %d\n",
wdenk8bde7f72003-06-27 21:31:46 +00001247 (int) nand->erasesize);
wdenkdc7c9a12003-03-26 06:55:25 +00001248 return -1;
1249 }
1250
1251 nandptr = nand->IO_ADDR;
1252
wdenk85ec0bc2003-03-31 16:34:49 +00001253 /* Select the NAND device */
1254 NAND_ENABLE_CE(nand); /* set pin low */
1255
1256 /* Check the WP bit */
1257 NanD_Command(nand, NAND_CMD_STATUS);
1258 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1259 printf ("nand_write_ecc: Device is write protected!!!\n");
1260 ret = -1;
1261 goto out;
1262 }
1263
wdenk0db5bca2003-03-31 17:27:09 +00001264 /* Check the WP bit */
1265 NanD_Command(nand, NAND_CMD_STATUS);
1266 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1267 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
1268 ret = -1;
1269 goto out;
1270 }
1271
wdenkdc7c9a12003-03-26 06:55:25 +00001272 /* FIXME: Do nand in the background. Use timers or schedule_task() */
1273 while(len) {
wdenk0db5bca2003-03-31 17:27:09 +00001274 /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
1275 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001276
wdenk7a8e9bed2003-05-31 18:35:21 +00001277 /* always check for bad block first, genuine bad blocks
1278 * should _never_ be erased.
1279 */
1280 if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
1281 /* Select the NAND device */
1282 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001283
wdenk7a8e9bed2003-05-31 18:35:21 +00001284 NanD_Command(nand, NAND_CMD_ERASE1);
1285 NanD_Address(nand, ADDR_PAGE, ofs);
1286 NanD_Command(nand, NAND_CMD_ERASE2);
wdenkdc7c9a12003-03-26 06:55:25 +00001287
wdenk7a8e9bed2003-05-31 18:35:21 +00001288 NanD_Command(nand, NAND_CMD_STATUS);
1289
1290 if (READ_NAND(nandptr) & 1) {
1291 printf ("%s: Error erasing at 0x%lx\n",
1292 __FUNCTION__, (long)ofs);
1293 /* There was an error */
1294 ret = -1;
1295 goto out;
1296 }
1297 if (clean) {
1298 int n; /* return value not used */
1299 int p, l;
1300
1301 /* clean marker position and size depend
1302 * on the page size, since 256 byte pages
1303 * only have 8 bytes of oob data
1304 */
1305 if (nand->page256) {
1306 p = NAND_JFFS2_OOB8_FSDAPOS;
1307 l = NAND_JFFS2_OOB8_FSDALEN;
1308 }
1309 else {
1310 p = NAND_JFFS2_OOB16_FSDAPOS;
1311 l = NAND_JFFS2_OOB16_FSDALEN;
1312 }
1313
1314 ret = nand_write_oob(nand, ofs + p, l, &n,
1315 (u_char *)&clean_marker);
1316 /* quit here if write failed */
1317 if (ret)
1318 goto out;
1319 }
wdenkdc7c9a12003-03-26 06:55:25 +00001320 }
1321 ofs += nand->erasesize;
1322 len -= nand->erasesize;
1323 }
1324
wdenk85ec0bc2003-03-31 16:34:49 +00001325out:
1326 /* De-select the NAND device */
1327 NAND_DISABLE_CE(nand); /* set pin high */
1328
1329 return ret;
wdenkdc7c9a12003-03-26 06:55:25 +00001330}
1331
1332static inline int nandcheck(unsigned long potential, unsigned long physadr)
1333{
wdenkdc7c9a12003-03-26 06:55:25 +00001334 return 0;
1335}
1336
1337void nand_probe(unsigned long physadr)
1338{
1339 struct nand_chip *nand = NULL;
1340 int i = 0, ChipID = 1;
1341
1342#ifdef CONFIG_MTD_NAND_ECC_JFFS2
1343 oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
1344 oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
1345 oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
1346 oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
1347 oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
1348 oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001349 oob_config.eccvalid_pos = 4;
1350#else
1351 oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
1352 oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
1353 oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
1354 oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
1355 oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
1356 oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001357 oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
1358#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001359 oob_config.badblock_pos = 5;
wdenkdc7c9a12003-03-26 06:55:25 +00001360
1361 for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
1362 if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
1363 nand = nand_dev_desc + i;
1364 break;
1365 }
1366 }
1367
wdenk7a8e9bed2003-05-31 18:35:21 +00001368 memset((char *)nand, 0, sizeof(struct nand_chip));
1369
1370 nand->IO_ADDR = physadr;
1371 nand->cache_page = -1; /* init the cache page */
1372 NanD_ScanChips(nand);
1373
1374 if (nand->totlen == 0) {
1375 /* no chips found, clean up and quit */
1376 memset((char *)nand, 0, sizeof(struct nand_chip));
1377 nand->ChipID = NAND_ChipID_UNKNOWN;
1378 return;
1379 }
1380
1381 nand->ChipID = ChipID;
wdenk0db5bca2003-03-31 17:27:09 +00001382 if (curr_device == -1)
1383 curr_device = i;
wdenkdc7c9a12003-03-26 06:55:25 +00001384
wdenk0db5bca2003-03-31 17:27:09 +00001385 nand->data_buf = malloc (nand->oobblock + nand->oobsize);
1386 if (!nand->data_buf) {
1387 puts ("Cannot allocate memory for data structures.\n");
1388 return;
1389 }
wdenkdc7c9a12003-03-26 06:55:25 +00001390}
1391
1392#ifdef CONFIG_MTD_NAND_ECC
1393/*
1394 * Pre-calculated 256-way 1 byte column parity
1395 */
1396static const u_char nand_ecc_precalc_table[] = {
1397 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
1398 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1399 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1400 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1401 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1402 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1403 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1404 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1405 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1406 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1407 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1408 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1409 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1410 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1411 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1412 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
1413};
1414
1415
1416/*
1417 * Creates non-inverted ECC code from line parity
1418 */
1419static void nand_trans_result(u_char reg2, u_char reg3,
1420 u_char *ecc_code)
1421{
1422 u_char a, b, i, tmp1, tmp2;
1423
1424 /* Initialize variables */
1425 a = b = 0x80;
1426 tmp1 = tmp2 = 0;
1427
1428 /* Calculate first ECC byte */
1429 for (i = 0; i < 4; i++) {
1430 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
1431 tmp1 |= b;
1432 b >>= 1;
1433 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
1434 tmp1 |= b;
1435 b >>= 1;
1436 a >>= 1;
1437 }
1438
1439 /* Calculate second ECC byte */
1440 b = 0x80;
1441 for (i = 0; i < 4; i++) {
1442 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
1443 tmp2 |= b;
1444 b >>= 1;
1445 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
1446 tmp2 |= b;
1447 b >>= 1;
1448 a >>= 1;
1449 }
1450
1451 /* Store two of the ECC bytes */
1452 ecc_code[0] = tmp1;
1453 ecc_code[1] = tmp2;
1454}
1455
1456/*
1457 * Calculate 3 byte ECC code for 256 byte block
1458 */
1459static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
1460{
wdenk7a8e9bed2003-05-31 18:35:21 +00001461 u_char idx, reg1, reg3;
wdenkdc7c9a12003-03-26 06:55:25 +00001462 int j;
1463
1464 /* Initialize variables */
wdenk7a8e9bed2003-05-31 18:35:21 +00001465 reg1 = reg3 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001466 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
1467
1468 /* Build up column parity */
1469 for(j = 0; j < 256; j++) {
1470
1471 /* Get CP0 - CP5 from table */
1472 idx = nand_ecc_precalc_table[dat[j]];
wdenk7a8e9bed2003-05-31 18:35:21 +00001473 reg1 ^= idx;
wdenkdc7c9a12003-03-26 06:55:25 +00001474
1475 /* All bit XOR = 1 ? */
1476 if (idx & 0x40) {
1477 reg3 ^= (u_char) j;
wdenkdc7c9a12003-03-26 06:55:25 +00001478 }
1479 }
1480
1481 /* Create non-inverted ECC code from line parity */
wdenk7a8e9bed2003-05-31 18:35:21 +00001482 nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
wdenkdc7c9a12003-03-26 06:55:25 +00001483
1484 /* Calculate final ECC code */
1485 ecc_code[0] = ~ecc_code[0];
1486 ecc_code[1] = ~ecc_code[1];
1487 ecc_code[2] = ((~reg1) << 2) | 0x03;
1488}
1489
1490/*
1491 * Detect and correct a 1 bit error for 256 byte block
1492 */
1493static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
1494{
1495 u_char a, b, c, d1, d2, d3, add, bit, i;
1496
1497 /* Do error detection */
1498 d1 = calc_ecc[0] ^ read_ecc[0];
1499 d2 = calc_ecc[1] ^ read_ecc[1];
1500 d3 = calc_ecc[2] ^ read_ecc[2];
1501
1502 if ((d1 | d2 | d3) == 0) {
1503 /* No errors */
1504 return 0;
1505 }
1506 else {
1507 a = (d1 ^ (d1 >> 1)) & 0x55;
1508 b = (d2 ^ (d2 >> 1)) & 0x55;
1509 c = (d3 ^ (d3 >> 1)) & 0x54;
1510
1511 /* Found and will correct single bit error in the data */
1512 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
1513 c = 0x80;
1514 add = 0;
1515 a = 0x80;
1516 for (i=0; i<4; i++) {
1517 if (d1 & c)
1518 add |= a;
1519 c >>= 2;
1520 a >>= 1;
1521 }
1522 c = 0x80;
1523 for (i=0; i<4; i++) {
1524 if (d2 & c)
1525 add |= a;
1526 c >>= 2;
1527 a >>= 1;
1528 }
1529 bit = 0;
1530 b = 0x04;
1531 c = 0x80;
1532 for (i=0; i<3; i++) {
1533 if (d3 & c)
1534 bit |= b;
1535 c >>= 2;
1536 b >>= 1;
1537 }
1538 b = 0x01;
1539 a = dat[add];
1540 a ^= (b << bit);
1541 dat[add] = a;
1542 return 1;
1543 }
1544 else {
1545 i = 0;
1546 while (d1) {
1547 if (d1 & 0x01)
1548 ++i;
1549 d1 >>= 1;
1550 }
1551 while (d2) {
1552 if (d2 & 0x01)
1553 ++i;
1554 d2 >>= 1;
1555 }
1556 while (d3) {
1557 if (d3 & 0x01)
1558 ++i;
1559 d3 >>= 1;
1560 }
1561 if (i == 1) {
1562 /* ECC Code Error Correction */
1563 read_ecc[0] = calc_ecc[0];
1564 read_ecc[1] = calc_ecc[1];
1565 read_ecc[2] = calc_ecc[2];
1566 return 2;
1567 }
1568 else {
1569 /* Uncorrectable Error */
1570 return -1;
1571 }
1572 }
1573 }
1574
1575 /* Should never happen */
1576 return -1;
1577}
1578#endif
1579#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */