blob: ce7b5ff02b380c2871654b92e66f9175109d765a [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>
wdenkdc7c9a12003-03-26 06:55:25 +00006 */
7
8#include <common.h>
wdenkdc7c9a12003-03-26 06:55:25 +00009#include <command.h>
10#include <malloc.h>
11#include <asm/io.h>
12
13#ifdef CONFIG_SHOW_BOOT_PROGRESS
14# include <status_led.h>
15# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
16#else
17# define SHOW_BOOT_PROGRESS(arg)
18#endif
19
20#if (CONFIG_COMMANDS & CFG_CMD_NAND)
21
wdenkdc7c9a12003-03-26 06:55:25 +000022#include <linux/mtd/nand.h>
23#include <linux/mtd/nand_ids.h>
wdenk7a8e9bed2003-05-31 18:35:21 +000024#include <jffs2/jffs2.h>
wdenkdc7c9a12003-03-26 06:55:25 +000025
wdenk1f4bb372003-07-27 00:21:01 +000026#ifdef CONFIG_OMAP1510
27void archflashwp(void *archdata, int wp);
28#endif
29
30#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
31
wdenkdc7c9a12003-03-26 06:55:25 +000032/*
33 * Definition of the out of band configuration structure
34 */
35struct nand_oob_config {
36 int ecc_pos[6]; /* position of ECC bytes inside oob */
37 int badblock_pos; /* position of bad block flag inside oob -1 = inactive */
38 int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */
39} oob_config = { {0}, 0, 0};
40
wdenk7a8e9bed2003-05-31 18:35:21 +000041#undef NAND_DEBUG
wdenkdc7c9a12003-03-26 06:55:25 +000042#undef PSYCHO_DEBUG
wdenk7a8e9bed2003-05-31 18:35:21 +000043
44/* ****************** WARNING *********************
45 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
46 * erase (or at least attempt to erase) blocks that are marked
47 * bad. This can be very handy if you are _sure_ that the block
48 * is OK, say because you marked a good block bad to test bad
49 * block handling and you are done testing, or if you have
50 * accidentally marked blocks bad.
51 *
52 * Erasing factory marked bad blocks is a _bad_ idea. If the
53 * erase succeeds there is no reliable way to find them again,
54 * and attempting to program or erase bad blocks can affect
55 * the data in _other_ (good) blocks.
56 */
57#define ALLOW_ERASE_BAD_DEBUG 0
wdenkdc7c9a12003-03-26 06:55:25 +000058
59#define CONFIG_MTD_NAND_ECC /* enable ECC */
wdenk1f4bb372003-07-27 00:21:01 +000060#define CONFIG_MTD_NAND_ECC_JFFS2
wdenkdc7c9a12003-03-26 06:55:25 +000061
wdenk7a8e9bed2003-05-31 18:35:21 +000062/* bits for nand_rw() `cmd'; or together as needed */
63#define NANDRW_READ 0x01
64#define NANDRW_WRITE 0x00
65#define NANDRW_JFFS2 0x02
66
wdenkdc7c9a12003-03-26 06:55:25 +000067/*
68 * Function Prototypes
69 */
70static void nand_print(struct nand_chip *nand);
71static int nand_rw (struct nand_chip* nand, int cmd,
72 size_t start, size_t len,
73 size_t * retlen, u_char * buf);
wdenk7a8e9bed2003-05-31 18:35:21 +000074static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);
wdenkdc7c9a12003-03-26 06:55:25 +000075static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
76 size_t * retlen, u_char *buf, u_char *ecc_code);
77static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
78 size_t * retlen, const u_char * buf, u_char * ecc_code);
wdenk7a8e9bed2003-05-31 18:35:21 +000079static void nand_print_bad(struct nand_chip *nand);
80static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
81 size_t * retlen, u_char * buf);
82static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
83 size_t * retlen, const u_char * buf);
wdenk1f4bb372003-07-27 00:21:01 +000084static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
wdenkdc7c9a12003-03-26 06:55:25 +000085#ifdef CONFIG_MTD_NAND_ECC
86static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
87static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
88#endif
89
wdenk7a8e9bed2003-05-31 18:35:21 +000090struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
wdenkdc7c9a12003-03-26 06:55:25 +000091
92/* Current NAND Device */
93static int curr_device = -1;
94
95/* ------------------------------------------------------------------------- */
96
97int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
98{
99 int rcode = 0;
100
101 switch (argc) {
102 case 0:
103 case 1:
104 printf ("Usage:\n%s\n", cmdtp->usage);
105 return 1;
106 case 2:
wdenk8bde7f72003-06-27 21:31:46 +0000107 if (strcmp(argv[1],"info") == 0) {
wdenkdc7c9a12003-03-26 06:55:25 +0000108 int i;
109
110 putc ('\n');
111
112 for (i=0; i<CFG_MAX_NAND_DEVICE; ++i) {
113 if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)
114 continue; /* list only known devices */
115 printf ("Device %d: ", i);
116 nand_print(&nand_dev_desc[i]);
117 }
118 return 0;
119
120 } else if (strcmp(argv[1],"device") == 0) {
121 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
122 puts ("\nno devices available\n");
123 return 1;
124 }
125 printf ("\nDevice %d: ", curr_device);
126 nand_print(&nand_dev_desc[curr_device]);
127 return 0;
wdenk7a8e9bed2003-05-31 18:35:21 +0000128
129 } else if (strcmp(argv[1],"bad") == 0) {
130 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
131 puts ("\nno devices available\n");
132 return 1;
133 }
134 printf ("\nDevice %d bad blocks:\n", curr_device);
135 nand_print_bad(&nand_dev_desc[curr_device]);
136 return 0;
137
wdenkdc7c9a12003-03-26 06:55:25 +0000138 }
139 printf ("Usage:\n%s\n", cmdtp->usage);
140 return 1;
141 case 3:
142 if (strcmp(argv[1],"device") == 0) {
143 int dev = (int)simple_strtoul(argv[2], NULL, 10);
144
145 printf ("\nDevice %d: ", dev);
146 if (dev >= CFG_MAX_NAND_DEVICE) {
147 puts ("unknown device\n");
148 return 1;
149 }
150 nand_print(&nand_dev_desc[dev]);
151 /*nand_print (dev);*/
152
153 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {
154 return 1;
155 }
156
157 curr_device = dev;
158
159 puts ("... is now current device\n");
160
161 return 0;
162 }
wdenk7a8e9bed2003-05-31 18:35:21 +0000163 else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) {
164 struct nand_chip* nand = &nand_dev_desc[curr_device];
165 ulong off = 0;
166 ulong size = nand->totlen;
167 int ret;
168
169 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
170 curr_device, off, size);
171
172 ret = nand_erase (nand, off, size, 1);
173
174 printf("%s\n", ret ? "ERROR" : "OK");
175
176 return ret;
177 }
wdenkdc7c9a12003-03-26 06:55:25 +0000178
179 printf ("Usage:\n%s\n", cmdtp->usage);
180 return 1;
181 default:
182 /* at least 4 args */
183
wdenk7a8e9bed2003-05-31 18:35:21 +0000184 if (strncmp(argv[1], "read", 4) == 0 ||
185 strncmp(argv[1], "write", 5) == 0) {
wdenkdc7c9a12003-03-26 06:55:25 +0000186 ulong addr = simple_strtoul(argv[2], NULL, 16);
187 ulong off = simple_strtoul(argv[3], NULL, 16);
188 ulong size = simple_strtoul(argv[4], NULL, 16);
wdenk7a8e9bed2003-05-31 18:35:21 +0000189 int cmd = (strncmp(argv[1], "read", 4) == 0) ?
190 NANDRW_READ : NANDRW_WRITE;
wdenkdc7c9a12003-03-26 06:55:25 +0000191 int ret, total;
wdenk7a8e9bed2003-05-31 18:35:21 +0000192 char* cmdtail = strchr(argv[1], '.');
193
194 if (cmdtail && !strncmp(cmdtail, ".oob", 2)) {
195 /* read out-of-band data */
196 if (cmd & NANDRW_READ) {
197 ret = nand_read_oob(nand_dev_desc + curr_device,
198 off, size, &total,
199 (u_char*)addr);
200 }
201 else {
202 ret = nand_write_oob(nand_dev_desc + curr_device,
203 off, size, &total,
204 (u_char*)addr);
205 }
206 return ret;
207 }
208 else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
209 cmd |= NANDRW_JFFS2; /* skip bad blocks */
210#ifdef SXNI855T
211 /* need ".e" same as ".j" for compatibility with older units */
212 else if (cmdtail && !strcmp(cmdtail, ".e"))
213 cmd |= NANDRW_JFFS2; /* skip bad blocks */
214#endif
215 else if (cmdtail) {
216 printf ("Usage:\n%s\n", cmdtp->usage);
217 return 1;
218 }
wdenkdc7c9a12003-03-26 06:55:25 +0000219
220 printf ("\nNAND %s: device %d offset %ld, size %ld ... ",
wdenk7a8e9bed2003-05-31 18:35:21 +0000221 (cmd & NANDRW_READ) ? "read" : "write",
222 curr_device, off, size);
wdenkdc7c9a12003-03-26 06:55:25 +0000223
224 ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size,
225 &total, (u_char*)addr);
226
wdenk1f4bb372003-07-27 00:21:01 +0000227 printf (" %d bytes %s: %s\n", total,
wdenk7a8e9bed2003-05-31 18:35:21 +0000228 (cmd & NANDRW_READ) ? "read" : "write",
wdenkdc7c9a12003-03-26 06:55:25 +0000229 ret ? "ERROR" : "OK");
230
231 return ret;
wdenk7a8e9bed2003-05-31 18:35:21 +0000232 } else if (strcmp(argv[1],"erase") == 0 &&
233 (argc == 4 || strcmp("clean", argv[2]) == 0)) {
234 int clean = argc == 5;
235 ulong off = simple_strtoul(argv[2 + clean], NULL, 16);
236 ulong size = simple_strtoul(argv[3 + clean], NULL, 16);
wdenkdc7c9a12003-03-26 06:55:25 +0000237 int ret;
238
239 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
240 curr_device, off, size);
241
wdenk7a8e9bed2003-05-31 18:35:21 +0000242 ret = nand_erase (nand_dev_desc + curr_device, off, size, clean);
wdenkdc7c9a12003-03-26 06:55:25 +0000243
244 printf("%s\n", ret ? "ERROR" : "OK");
245
246 return ret;
247 } else {
248 printf ("Usage:\n%s\n", cmdtp->usage);
249 rcode = 1;
250 }
251
252 return rcode;
253 }
254}
255
wdenk0d498392003-07-01 21:06:45 +0000256U_BOOT_CMD(
257 nand, 5, 1, do_nand,
wdenkb0fce992003-06-29 21:03:46 +0000258 "nand - NAND sub-system\n",
259 "info - show available NAND devices\n"
260 "nand device [dev] - show or set current device\n"
261 "nand read[.jffs2] addr off size\n"
262 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
263 " at offset `off' to/from memory address `addr'\n"
264 "nand erase [clean] [off size] - erase `size' bytes from\n"
265 " offset `off' (entire device if not specified)\n"
266 "nand bad - show bad blocks\n"
267 "nand read.oob addr off size - read out-of-band data\n"
268 "nand write.oob addr off size - read out-of-band data\n"
269);
270
wdenkdc7c9a12003-03-26 06:55:25 +0000271int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
272{
273 char *boot_device = NULL;
274 char *ep;
275 int dev;
276 ulong cnt;
277 ulong addr;
278 ulong offset = 0;
279 image_header_t *hdr;
280 int rcode = 0;
281 switch (argc) {
282 case 1:
283 addr = CFG_LOAD_ADDR;
284 boot_device = getenv ("bootdevice");
285 break;
286 case 2:
287 addr = simple_strtoul(argv[1], NULL, 16);
288 boot_device = getenv ("bootdevice");
289 break;
290 case 3:
291 addr = simple_strtoul(argv[1], NULL, 16);
292 boot_device = argv[2];
293 break;
294 case 4:
295 addr = simple_strtoul(argv[1], NULL, 16);
296 boot_device = argv[2];
297 offset = simple_strtoul(argv[3], NULL, 16);
298 break;
299 default:
300 printf ("Usage:\n%s\n", cmdtp->usage);
301 SHOW_BOOT_PROGRESS (-1);
302 return 1;
303 }
304
305 if (!boot_device) {
306 puts ("\n** No boot device **\n");
307 SHOW_BOOT_PROGRESS (-1);
308 return 1;
309 }
310
311 dev = simple_strtoul(boot_device, &ep, 16);
312
313 if ((dev >= CFG_MAX_NAND_DEVICE) ||
314 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {
315 printf ("\n** Device %d not available\n", dev);
316 SHOW_BOOT_PROGRESS (-1);
317 return 1;
318 }
319
wdenk7a8e9bed2003-05-31 18:35:21 +0000320 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
wdenkdc7c9a12003-03-26 06:55:25 +0000321 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
322 offset);
323
wdenk7a8e9bed2003-05-31 18:35:21 +0000324 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset,
wdenkdc7c9a12003-03-26 06:55:25 +0000325 SECTORSIZE, NULL, (u_char *)addr)) {
326 printf ("** Read error on %d\n", dev);
327 SHOW_BOOT_PROGRESS (-1);
328 return 1;
329 }
330
331 hdr = (image_header_t *)addr;
332
333 if (ntohl(hdr->ih_magic) == IH_MAGIC) {
334
335 print_image_hdr (hdr);
336
337 cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
338 cnt -= SECTORSIZE;
339 } else {
340 printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
341 SHOW_BOOT_PROGRESS (-1);
342 return 1;
343 }
344
wdenk7a8e9bed2003-05-31 18:35:21 +0000345 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt,
wdenkdc7c9a12003-03-26 06:55:25 +0000346 NULL, (u_char *)(addr+SECTORSIZE))) {
347 printf ("** Read error on %d\n", dev);
348 SHOW_BOOT_PROGRESS (-1);
349 return 1;
350 }
351
352 /* Loading ok, update default load address */
353
354 load_addr = addr;
355
356 /* Check if we should attempt an auto-start */
357 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
358 char *local_args[2];
359 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
360
361 local_args[0] = argv[0];
362 local_args[1] = NULL;
363
wdenk7a8e9bed2003-05-31 18:35:21 +0000364 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);
wdenkdc7c9a12003-03-26 06:55:25 +0000365
366 do_bootm (cmdtp, 0, 1, local_args);
367 rcode = 1;
368 }
369 return rcode;
370}
371
wdenk0d498392003-07-01 21:06:45 +0000372U_BOOT_CMD(
373 nboot, 4, 1, do_nandboot,
wdenkb0fce992003-06-29 21:03:46 +0000374 "nboot - boot from NAND device\n",
375 "loadAddr dev\n"
376);
377
wdenk7a8e9bed2003-05-31 18:35:21 +0000378/* returns 0 if block containing pos is OK:
379 * valid erase block and
380 * not marked bad, or no bad mark position is specified
381 * returns 1 if marked bad or otherwise invalid
382 */
383int check_block(struct nand_chip* nand, unsigned long pos)
384{
385 int retlen;
386 uint8_t oob_data;
387 int page0 = pos & (-nand->erasesize);
388 int page1 = page0 + nand->oobblock;
389 int badpos = oob_config.badblock_pos;
390
391 if (pos >= nand->totlen)
392 return 1;
393
394 if (badpos < 0)
395 return 0; /* no way to check, assume OK */
396
397 /* Note - bad block marker can be on first or second page */
398 if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data) ||
399 oob_data != 0xff ||
400 nand_read_oob(nand, page1 + badpos, 1, &retlen, &oob_data) ||
401 oob_data != 0xff)
402 return 1;
403
404 return 0;
405}
wdenk8bde7f72003-06-27 21:31:46 +0000406
wdenk7a8e9bed2003-05-31 18:35:21 +0000407/* print bad blocks in NAND flash */
408static void nand_print_bad(struct nand_chip* nand)
409{
410 unsigned long pos;
411
412 for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
413 if (check_block(nand, pos))
414 printf(" 0x%8.8lx\n", pos);
415 }
416 puts("\n");
417}
418
419/* cmd: 0: NANDRW_WRITE write, fail on bad block
420 * 1: NANDRW_READ read, fail on bad block
421 * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
422 * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
423 */
wdenkdc7c9a12003-03-26 06:55:25 +0000424static int nand_rw (struct nand_chip* nand, int cmd,
425 size_t start, size_t len,
426 size_t * retlen, u_char * buf)
427{
wdenk1f4bb372003-07-27 00:21:01 +0000428 int ret = 0, n, total = 0;
wdenkdc7c9a12003-03-26 06:55:25 +0000429 char eccbuf[6];
wdenk7a8e9bed2003-05-31 18:35:21 +0000430 /* eblk (once set) is the start of the erase block containing the
431 * data being processed.
432 */
433 unsigned long eblk = ~0; /* force mismatch on first pass */
434 unsigned long erasesize = nand->erasesize;
wdenkdc7c9a12003-03-26 06:55:25 +0000435
wdenk7a8e9bed2003-05-31 18:35:21 +0000436 while (len) {
437 if ((start & (-erasesize)) != eblk) {
438 /* have crossed into new erase block, deal with
439 * it if it is sure marked bad.
440 */
441 eblk = start & (-erasesize); /* start of block */
442 if (check_block(nand, eblk)) {
443 if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
444 while (len > 0 &&
445 start - eblk < erasesize) {
446 *(buf++) = 0xff;
447 ++start;
448 ++total;
449 --len;
450 }
451 continue;
452 }
453 else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
454 /* skip bad block */
455 start += erasesize;
456 continue;
457 }
458 else {
459 ret = 1;
460 break;
461 }
462 }
463 }
wdenkdc7c9a12003-03-26 06:55:25 +0000464 /* The ECC will not be calculated correctly if
465 less than 512 is written or read */
wdenk1f4bb372003-07-27 00:21:01 +0000466 /* Is request at least 512 bytes AND it starts on a proper boundry */
467 if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
468 printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
469
wdenk7a8e9bed2003-05-31 18:35:21 +0000470 if (cmd & NANDRW_READ)
471 ret = nand_read_ecc(nand, start,
472 min(len, eblk + erasesize - start),
wdenk1f4bb372003-07-27 00:21:01 +0000473 &n, (u_char*)buf, eccbuf);
wdenkdc7c9a12003-03-26 06:55:25 +0000474 else
wdenk7a8e9bed2003-05-31 18:35:21 +0000475 ret = nand_write_ecc(nand, start,
476 min(len, eblk + erasesize - start),
wdenk1f4bb372003-07-27 00:21:01 +0000477 &n, (u_char*)buf, eccbuf);
wdenkdc7c9a12003-03-26 06:55:25 +0000478
479 if (ret)
480 break;
481
482 start += n;
483 buf += n;
484 total += n;
485 len -= n;
486 }
487 if (retlen)
488 *retlen = total;
489
490 return ret;
491}
492
493static void nand_print(struct nand_chip *nand)
wdenk0db5bca2003-03-31 17:27:09 +0000494{
wdenk7a8e9bed2003-05-31 18:35:21 +0000495 if (nand->numchips > 1) {
496 printf("%s at 0x%lx,\n"
497 "\t %d chips %s, size %d MB, \n"
498 "\t total size %ld MB, sector size %ld kB\n",
499 nand->name, nand->IO_ADDR, nand->numchips,
500 nand->chips_name, 1 << (nand->chipshift - 20),
501 nand->totlen >> 20, nand->erasesize >> 10);
502 }
503 else {
wdenk8bde7f72003-06-27 21:31:46 +0000504 printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
wdenk7a8e9bed2003-05-31 18:35:21 +0000505 print_size(nand->totlen, ", ");
506 print_size(nand->erasesize, " sector)\n");
wdenkdc7c9a12003-03-26 06:55:25 +0000507 }
508}
509
510/* ------------------------------------------------------------------------- */
511
wdenk1f4bb372003-07-27 00:21:01 +0000512static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
wdenkdc7c9a12003-03-26 06:55:25 +0000513{
514 /* This is inline, to optimise the common case, where it's ready instantly */
515 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +0000516
wdenk1f4bb372003-07-27 00:21:01 +0000517#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */
518 if(ale_wait)
519 NAND_WAIT_READY(nand); /* do the worst case 25us wait */
520 else
521 udelay(10);
522#else /* has functional r/b signal */
wdenk12f34242003-09-02 22:48:03 +0000523 NAND_WAIT_READY(nand);
wdenk1f4bb372003-07-27 00:21:01 +0000524#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000525 return ret;
526}
527
528/* NanD_Command: Send a flash command to the flash chip */
529
530static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
531{
532 unsigned long nandptr = nand->IO_ADDR;
533
534 /* Assert the CLE (Command Latch Enable) line to the flash chip */
535 NAND_CTL_SETCLE(nandptr);
536
537 /* Send the command */
538 WRITE_NAND_COMMAND(command, nandptr);
539
540 /* Lower the CLE line */
541 NAND_CTL_CLRCLE(nandptr);
542
wdenk1f4bb372003-07-27 00:21:01 +0000543#ifdef NAND_NO_RB
544 if(command == NAND_CMD_RESET){
545 u_char ret_val;
546 NanD_Command(nand, NAND_CMD_STATUS);
547 do{
548 ret_val = READ_NAND(nandptr);/* wait till ready */
549 } while((ret_val & 0x40) != 0x40);
550 }
551#endif
552 return NanD_WaitReady(nand, 0);
wdenkdc7c9a12003-03-26 06:55:25 +0000553}
554
555/* NanD_Address: Set the current address for the flash chip */
556
557static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
wdenk0db5bca2003-03-31 17:27:09 +0000558{
559 unsigned long nandptr;
560 int i;
wdenkdc7c9a12003-03-26 06:55:25 +0000561
wdenk0db5bca2003-03-31 17:27:09 +0000562 nandptr = nand->IO_ADDR;
wdenkdc7c9a12003-03-26 06:55:25 +0000563
564 /* Assert the ALE (Address Latch Enable) line to the flash chip */
wdenk0db5bca2003-03-31 17:27:09 +0000565 NAND_CTL_SETALE(nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000566
wdenk0db5bca2003-03-31 17:27:09 +0000567 /* Send the address */
568 /* Devices with 256-byte page are addressed as:
569 * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
570 * there is no device on the market with page256
571 * and more than 24 bits.
572 * Devices with 512-byte page are addressed as:
573 * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
574 * 25-31 is sent only if the chip support it.
575 * bit 8 changes the read command to be sent
576 * (NAND_CMD_READ0 or NAND_CMD_READ1).
wdenkdc7c9a12003-03-26 06:55:25 +0000577 */
578
wdenk0db5bca2003-03-31 17:27:09 +0000579 if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
580 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000581
wdenk0db5bca2003-03-31 17:27:09 +0000582 ofs = ofs >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000583
wdenk0db5bca2003-03-31 17:27:09 +0000584 if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
585 for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8)
586 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000587
wdenk0db5bca2003-03-31 17:27:09 +0000588 /* Lower the ALE line */
589 NAND_CTL_CLRALE(nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000590
wdenk0db5bca2003-03-31 17:27:09 +0000591 /* Wait for the chip to respond */
wdenk1f4bb372003-07-27 00:21:01 +0000592 return NanD_WaitReady(nand, 1);
wdenk0db5bca2003-03-31 17:27:09 +0000593}
wdenkdc7c9a12003-03-26 06:55:25 +0000594
595/* NanD_SelectChip: Select a given flash chip within the current floor */
596
597static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
598{
599 /* Wait for it to be ready */
wdenk1f4bb372003-07-27 00:21:01 +0000600 return NanD_WaitReady(nand, 0);
wdenkdc7c9a12003-03-26 06:55:25 +0000601}
602
603/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
604
605static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
606{
607 int mfr, id, i;
608
wdenk0db5bca2003-03-31 17:27:09 +0000609 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +0000610 /* Reset the chip */
611 if (NanD_Command(nand, NAND_CMD_RESET)) {
612#ifdef NAND_DEBUG
613 printf("NanD_Command (reset) for %d,%d returned true\n",
614 floor, chip);
615#endif
wdenk0db5bca2003-03-31 17:27:09 +0000616 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000617 return 0;
618 }
619
620 /* Read the NAND chip ID: 1. Send ReadID command */
621 if (NanD_Command(nand, NAND_CMD_READID)) {
622#ifdef NAND_DEBUG
623 printf("NanD_Command (ReadID) for %d,%d returned true\n",
624 floor, chip);
625#endif
wdenk0db5bca2003-03-31 17:27:09 +0000626 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000627 return 0;
628 }
629
630 /* Read the NAND chip ID: 2. Send address byte zero */
631 NanD_Address(nand, ADDR_COLUMN, 0);
632
633 /* Read the manufacturer and device id codes from the device */
634
635 mfr = READ_NAND(nand->IO_ADDR);
636
637 id = READ_NAND(nand->IO_ADDR);
638
wdenk8bde7f72003-06-27 21:31:46 +0000639 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000640 /* No response - return failure */
wdenk0db5bca2003-03-31 17:27:09 +0000641 if (mfr == 0xff || mfr == 0) {
wdenk4d816772003-09-03 14:03:26 +0000642#ifdef NAND_DEBUG
wdenk0db5bca2003-03-31 17:27:09 +0000643 printf("NanD_Command (ReadID) got %d %d\n", mfr, id);
wdenk4d816772003-09-03 14:03:26 +0000644#endif
wdenk0db5bca2003-03-31 17:27:09 +0000645 return 0;
646 }
wdenkdc7c9a12003-03-26 06:55:25 +0000647
648 /* Check it's the same as the first chip we identified.
649 * M-Systems say that any given nand_chip device should only
650 * contain _one_ type of flash part, although that's not a
651 * hardware restriction. */
652 if (nand->mfr) {
653 if (nand->mfr == mfr && nand->id == id)
654 return 1; /* This is another the same the first */
655 else
656 printf("Flash chip at floor %d, chip %d is different:\n",
657 floor, chip);
658 }
659
660 /* Print and store the manufacturer and ID codes. */
661 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
662 if (mfr == nand_flash_ids[i].manufacture_id &&
663 id == nand_flash_ids[i].model_id) {
664#ifdef NAND_DEBUG
665 printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
666 "Chip ID: 0x%2.2X (%s)\n", mfr, id,
667 nand_flash_ids[i].name);
668#endif
669 if (!nand->mfr) {
670 nand->mfr = mfr;
671 nand->id = id;
672 nand->chipshift =
673 nand_flash_ids[i].chipshift;
674 nand->page256 = nand_flash_ids[i].page256;
wdenk7a8e9bed2003-05-31 18:35:21 +0000675 nand->eccsize = 256;
wdenkdc7c9a12003-03-26 06:55:25 +0000676 if (nand->page256) {
677 nand->oobblock = 256;
678 nand->oobsize = 8;
679 nand->page_shift = 8;
680 } else {
681 nand->oobblock = 512;
682 nand->oobsize = 16;
683 nand->page_shift = 9;
684 }
685 nand->pageadrlen =
686 nand_flash_ids[i].pageadrlen;
687 nand->erasesize =
688 nand_flash_ids[i].erasesize;
689 nand->chips_name =
690 nand_flash_ids[i].name;
691 return 1;
692 }
693 return 0;
694 }
695 }
696
697
698#ifdef NAND_DEBUG
699 /* We haven't fully identified the chip. Print as much as we know. */
700 printf("Unknown flash chip found: %2.2X %2.2X\n",
701 id, mfr);
702#endif
703
704 return 0;
705}
706
707/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
708
709static void NanD_ScanChips(struct nand_chip *nand)
710{
711 int floor, chip;
712 int numchips[NAND_MAX_FLOORS];
713 int maxchips = NAND_MAX_CHIPS;
714 int ret = 1;
715
716 nand->numchips = 0;
717 nand->mfr = 0;
718 nand->id = 0;
719
720
721 /* For each floor, find the number of valid chips it contains */
722 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
723 ret = 1;
724 numchips[floor] = 0;
725 for (chip = 0; chip < maxchips && ret != 0; chip++) {
726
727 ret = NanD_IdentChip(nand, floor, chip);
728 if (ret) {
729 numchips[floor]++;
730 nand->numchips++;
731 }
732 }
733 }
734
735 /* If there are none at all that we recognise, bail */
736 if (!nand->numchips) {
wdenk4d816772003-09-03 14:03:26 +0000737 puts ("No NAND flash chips recognised.\n");
wdenkdc7c9a12003-03-26 06:55:25 +0000738 return;
739 }
740
741 /* Allocate an array to hold the information for each chip */
742 nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
743 if (!nand->chips) {
744 puts ("No memory for allocating chip info structures\n");
745 return;
746 }
747
748 ret = 0;
749
750 /* Fill out the chip array with {floor, chipno} for each
751 * detected chip in the device. */
752 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
753 for (chip = 0; chip < numchips[floor]; chip++) {
754 nand->chips[ret].floor = floor;
755 nand->chips[ret].chip = chip;
756 nand->chips[ret].curadr = 0;
757 nand->chips[ret].curmode = 0x50;
758 ret++;
759 }
760 }
761
762 /* Calculate and print the total size of the device */
763 nand->totlen = nand->numchips * (1 << nand->chipshift);
764
765#ifdef NAND_DEBUG
766 printf("%d flash chips found. Total nand_chip size: %ld MB\n",
767 nand->numchips, nand->totlen >> 20);
768#endif
769}
wdenk0db5bca2003-03-31 17:27:09 +0000770
wdenkdc7c9a12003-03-26 06:55:25 +0000771/* we need to be fast here, 1 us per read translates to 1 second per meg */
wdenk7a8e9bed2003-05-31 18:35:21 +0000772static void NanD_ReadBuf(struct nand_chip *nand, u_char *data_buf, int cntr)
wdenk0db5bca2003-03-31 17:27:09 +0000773{
wdenk7a8e9bed2003-05-31 18:35:21 +0000774 unsigned long nandptr = nand->IO_ADDR;
wdenk0db5bca2003-03-31 17:27:09 +0000775
wdenk7a8e9bed2003-05-31 18:35:21 +0000776 while (cntr >= 16) {
wdenk0db5bca2003-03-31 17:27:09 +0000777 *data_buf++ = READ_NAND(nandptr);
778 *data_buf++ = READ_NAND(nandptr);
779 *data_buf++ = READ_NAND(nandptr);
780 *data_buf++ = READ_NAND(nandptr);
781 *data_buf++ = READ_NAND(nandptr);
782 *data_buf++ = READ_NAND(nandptr);
783 *data_buf++ = READ_NAND(nandptr);
784 *data_buf++ = READ_NAND(nandptr);
785 *data_buf++ = READ_NAND(nandptr);
786 *data_buf++ = READ_NAND(nandptr);
787 *data_buf++ = READ_NAND(nandptr);
788 *data_buf++ = READ_NAND(nandptr);
789 *data_buf++ = READ_NAND(nandptr);
790 *data_buf++ = READ_NAND(nandptr);
791 *data_buf++ = READ_NAND(nandptr);
792 *data_buf++ = READ_NAND(nandptr);
793 cntr -= 16;
794 }
795
796 while (cntr > 0) {
797 *data_buf++ = READ_NAND(nandptr);
798 cntr--;
799 }
800}
wdenkdc7c9a12003-03-26 06:55:25 +0000801
wdenkdc7c9a12003-03-26 06:55:25 +0000802/*
803 * NAND read with ECC
804 */
805static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
806 size_t * retlen, u_char *buf, u_char *ecc_code)
807{
808 int col, page;
809 int ecc_status = 0;
810#ifdef CONFIG_MTD_NAND_ECC
811 int j;
812 int ecc_failed = 0;
813 u_char *data_poi;
814 u_char ecc_calc[6];
815#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000816
817 /* Do not allow reads past end of device */
818 if ((start + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +0000819 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 +0000820 *retlen = 0;
821 return -1;
822 }
823
824 /* First we calculate the starting page */
wdenk0db5bca2003-03-31 17:27:09 +0000825 /*page = shr(start, nand->page_shift);*/
826 page = start >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000827
828 /* Get raw starting column */
829 col = start & (nand->oobblock - 1);
830
831 /* Initialize return value */
832 *retlen = 0;
833
834 /* Select the NAND device */
835 NAND_ENABLE_CE(nand); /* set pin low */
836
837 /* Loop until all data read */
838 while (*retlen < len) {
839
840
841#ifdef CONFIG_MTD_NAND_ECC
842
843 /* Do we have this page in cache ? */
844 if (nand->cache_page == page)
845 goto readdata;
846 /* Send the read command */
847 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000848 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000849 /* Read in a page + oob data */
wdenk7a8e9bed2003-05-31 18:35:21 +0000850 NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
wdenkdc7c9a12003-03-26 06:55:25 +0000851
852 /* copy data into cache, for read out of cache and if ecc fails */
853 if (nand->data_cache)
854 memcpy (nand->data_cache, nand->data_buf, nand->oobblock + nand->oobsize);
855
856 /* Pick the ECC bytes out of the oob data */
857 for (j = 0; j < 6; j++)
858 ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
859
860 /* Calculate the ECC and verify it */
861 /* If block was not written with ECC, skip ECC */
862 if (oob_config.eccvalid_pos != -1 &&
863 (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
864
865 nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
866 switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
867 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000868 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000869 ecc_failed++;
870 break;
871 case 1:
872 case 2: /* transfer ECC corrected data to cache */
wdenk7a8e9bed2003-05-31 18:35:21 +0000873 if (nand->data_cache)
874 memcpy (nand->data_cache, nand->data_buf, 256);
wdenkdc7c9a12003-03-26 06:55:25 +0000875 break;
876 }
877 }
878
879 if (oob_config.eccvalid_pos != -1 &&
880 nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
881
882 nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
883 switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
884 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000885 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000886 ecc_failed++;
887 break;
888 case 1:
889 case 2: /* transfer ECC corrected data to cache */
890 if (nand->data_cache)
891 memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
892 break;
893 }
894 }
895readdata:
896 /* Read the data from ECC data buffer into return buffer */
897 data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
898 data_poi += col;
899 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000900 memcpy (buf + *retlen, data_poi, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000901 *retlen = len;
902 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000903 memcpy (buf + *retlen, data_poi, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000904 *retlen += nand->oobblock - col;
905 }
906 /* Set cache page address, invalidate, if ecc_failed */
907 nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
908
909 ecc_status += ecc_failed;
910 ecc_failed = 0;
911
912#else
913 /* Send the read command */
914 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000915 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000916 /* Read the data directly into the return buffer */
917 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000918 NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000919 *retlen = len;
920 /* We're done */
921 continue;
922 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000923 NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000924 *retlen += nand->oobblock - col;
925 }
926#endif
927 /* For subsequent reads align to page boundary. */
928 col = 0;
929 /* Increment page address */
930 page++;
931 }
932
933 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +0000934 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000935
936 /*
937 * Return success, if no ECC failures, else -EIO
938 * fs driver will take care of that, because
939 * retlen == desired len and result == -EIO
940 */
941 return ecc_status ? -1 : 0;
942}
943
wdenkdc7c9a12003-03-26 06:55:25 +0000944/*
945 * Nand_page_program function is used for write and writev !
946 */
947static int nand_write_page (struct nand_chip *nand,
948 int page, int col, int last, u_char * ecc_code)
949{
950
951 int i;
wdenkdc7c9a12003-03-26 06:55:25 +0000952 unsigned long nandptr = nand->IO_ADDR;
wdenk1f4bb372003-07-27 00:21:01 +0000953#ifdef CONFIG_MTD_NAND_ECC
wdenkdc7c9a12003-03-26 06:55:25 +0000954#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
955 int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
956#endif
957#endif
958 /* pad oob area */
959 for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
960 nand->data_buf[i] = 0xff;
961
962#ifdef CONFIG_MTD_NAND_ECC
963 /* Zero out the ECC array */
964 for (i = 0; i < 6; i++)
965 ecc_code[i] = 0x00;
966
967 /* Read back previous written data, if col > 0 */
968 if (col) {
969 NanD_Command(nand, NAND_CMD_READ0);
wdenk0db5bca2003-03-31 17:27:09 +0000970 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000971 for (i = 0; i < col; i++)
972 nand->data_buf[i] = READ_NAND (nandptr);
973 }
974
975 /* Calculate and write the ECC if we have enough data */
976 if ((col < nand->eccsize) && (last >= nand->eccsize)) {
977 nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
978 for (i = 0; i < 3; i++)
979 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
980 if (oob_config.eccvalid_pos != -1)
981 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] = 0xf0;
982 }
983
984 /* Calculate and write the second ECC if we have enough data */
985 if ((nand->oobblock == 512) && (last == nand->oobblock)) {
986 nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
987 for (i = 3; i < 6; i++)
988 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
989 if (oob_config.eccvalid_pos != -1)
990 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] &= 0x0f;
991 }
992#endif
993 /* Prepad for partial page programming !!! */
994 for (i = 0; i < col; i++)
995 nand->data_buf[i] = 0xff;
996
997 /* Postpad for partial page programming !!! oob is already padded */
998 for (i = last; i < nand->oobblock; i++)
999 nand->data_buf[i] = 0xff;
1000
1001 /* Send command to begin auto page programming */
wdenk7a8e9bed2003-05-31 18:35:21 +00001002 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001003 NanD_Command(nand, NAND_CMD_SEQIN);
1004 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1005
1006 /* Write out complete page of data */
1007 for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
wdenk0db5bca2003-03-31 17:27:09 +00001008 WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
wdenkdc7c9a12003-03-26 06:55:25 +00001009
1010 /* Send command to actually program the data */
wdenk0db5bca2003-03-31 17:27:09 +00001011 NanD_Command(nand, NAND_CMD_PAGEPROG);
1012 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001013#ifdef NAND_NO_RB
1014 { u_char ret_val;
wdenkdc7c9a12003-03-26 06:55:25 +00001015
wdenk1f4bb372003-07-27 00:21:01 +00001016 do{
1017 ret_val = READ_NAND(nandptr); /* wait till ready */
1018 } while((ret_val & 0x40) != 0x40);
1019 }
1020#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001021 /* See if device thinks it succeeded */
1022 if (READ_NAND(nand->IO_ADDR) & 0x01) {
wdenk0db5bca2003-03-31 17:27:09 +00001023 printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001024 return -1;
1025 }
wdenk1f4bb372003-07-27 00:21:01 +00001026
wdenkdc7c9a12003-03-26 06:55:25 +00001027#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1028 /*
1029 * The NAND device assumes that it is always writing to
1030 * a cleanly erased page. Hence, it performs its internal
1031 * write verification only on bits that transitioned from
1032 * 1 to 0. The device does NOT verify the whole page on a
1033 * byte by byte basis. It is possible that the page was
1034 * not completely erased or the page is becoming unusable
1035 * due to wear. The read with ECC would catch the error
1036 * later when the ECC page check fails, but we would rather
1037 * catch it early in the page write stage. Better to write
1038 * no data than invalid data.
1039 */
1040
1041 /* Send command to read back the page */
1042 if (col < nand->eccsize)
wdenk0db5bca2003-03-31 17:27:09 +00001043 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001044 else
wdenk0db5bca2003-03-31 17:27:09 +00001045 NanD_Command(nand, NAND_CMD_READ1);
1046 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +00001047
1048 /* Loop through and verify the data */
1049 for (i = col; i < last; i++) {
1050 if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
wdenk0db5bca2003-03-31 17:27:09 +00001051 printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001052 return -1;
1053 }
1054 }
1055
1056#ifdef CONFIG_MTD_NAND_ECC
1057 /*
1058 * We also want to check that the ECC bytes wrote
1059 * correctly for the same reasons stated above.
1060 */
1061 NanD_Command(nand, NAND_CMD_READOOB);
1062 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1063 for (i = 0; i < nand->oobsize; i++)
1064 nand->data_buf[i] = readb (nand->IO_ADDR);
1065 for (i = 0; i < ecc_bytes; i++) {
1066 if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
wdenk0db5bca2003-03-31 17:27:09 +00001067 printf ("%s: Failed ECC write "
1068 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
wdenkdc7c9a12003-03-26 06:55:25 +00001069 return -1;
1070 }
1071 }
1072#endif
1073#endif
1074 return 0;
1075}
wdenk0db5bca2003-03-31 17:27:09 +00001076
wdenkdc7c9a12003-03-26 06:55:25 +00001077static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
1078 size_t * retlen, const u_char * buf, u_char * ecc_code)
1079{
1080 int i, page, col, cnt, ret = 0;
1081
1082 /* Do not allow write past end of device */
1083 if ((to + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +00001084 printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001085 return -1;
1086 }
1087
1088 /* Shift to get page */
1089 page = ((int) to) >> nand->page_shift;
1090
1091 /* Get the starting column */
1092 col = to & (nand->oobblock - 1);
1093
1094 /* Initialize return length value */
1095 *retlen = 0;
1096
1097 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001098#ifdef CONFIG_OMAP1510
1099 archflashwp(0,0);
1100#endif
1101 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001102
1103 /* Check the WP bit */
wdenk0db5bca2003-03-31 17:27:09 +00001104 NanD_Command(nand, NAND_CMD_STATUS);
wdenkdc7c9a12003-03-26 06:55:25 +00001105 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
wdenk0db5bca2003-03-31 17:27:09 +00001106 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001107 ret = -1;
1108 goto out;
1109 }
1110
1111 /* Loop until all data is written */
1112 while (*retlen < len) {
1113 /* Invalidate cache, if we write to this page */
1114 if (nand->cache_page == page)
1115 nand->cache_page = -1;
1116
1117 /* Write data into buffer */
1118 if ((col + len) >= nand->oobblock)
1119 for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++)
1120 nand->data_buf[i] = buf[(*retlen + cnt)];
1121 else
1122 for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++)
1123 nand->data_buf[i] = buf[(*retlen + cnt)];
1124 /* We use the same function for write and writev !) */
1125 ret = nand_write_page (nand, page, col, i, ecc_code);
1126 if (ret)
1127 goto out;
1128
1129 /* Next data start at page boundary */
1130 col = 0;
1131
1132 /* Update written bytes count */
1133 *retlen += cnt;
1134
1135 /* Increment page address */
1136 page++;
1137 }
1138
1139 /* Return happy */
1140 *retlen = len;
1141
1142out:
1143 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +00001144 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001145#ifdef CONFIG_OMAP1510
1146 archflashwp(0,1);
1147#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001148 return ret;
1149}
1150
wdenk7a8e9bed2003-05-31 18:35:21 +00001151/* read from the 16 bytes of oob data that correspond to a 512 byte
1152 * page or 2 256-byte pages.
wdenkdc7c9a12003-03-26 06:55:25 +00001153 */
wdenkdc7c9a12003-03-26 06:55:25 +00001154static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
wdenk7a8e9bed2003-05-31 18:35:21 +00001155 size_t * retlen, u_char * buf)
wdenkdc7c9a12003-03-26 06:55:25 +00001156{
wdenk7a8e9bed2003-05-31 18:35:21 +00001157 int len256 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001158 struct Nand *mychip;
wdenk0db5bca2003-03-31 17:27:09 +00001159 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001160
wdenk7a8e9bed2003-05-31 18:35:21 +00001161 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001162
1163 /* update address for 2M x 8bit devices. OOB starts on the second */
1164 /* page to maintain compatibility with nand_read_ecc. */
1165 if (nand->page256) {
1166 if (!(ofs & 0x8))
1167 ofs += 0x100;
1168 else
1169 ofs -= 0x8;
1170 }
1171
wdenk7a8e9bed2003-05-31 18:35:21 +00001172 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001173 NanD_Command(nand, NAND_CMD_READOOB);
1174 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1175
1176 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1177 /* Note: datasheet says it should automaticaly wrap to the */
1178 /* next OOB block, but it didn't work here. mf. */
1179 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1180 len256 = (ofs | 0x7) + 1 - ofs;
1181 NanD_ReadBuf(nand, buf, len256);
1182
1183 NanD_Command(nand, NAND_CMD_READOOB);
1184 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1185 }
1186
1187 NanD_ReadBuf(nand, &buf[len256], len - len256);
1188
1189 *retlen = len;
1190 /* Reading the full OOB data drops us off of the end of the page,
wdenk8bde7f72003-06-27 21:31:46 +00001191 * causing the flash device to go into busy mode, so we need
1192 * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
wdenkdc7c9a12003-03-26 06:55:25 +00001193
wdenk1f4bb372003-07-27 00:21:01 +00001194 ret = NanD_WaitReady(nand, 1);
wdenk8bde7f72003-06-27 21:31:46 +00001195 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001196
1197 return ret;
1198
1199}
wdenk7a8e9bed2003-05-31 18:35:21 +00001200
1201/* write to the 16 bytes of oob data that correspond to a 512 byte
1202 * page or 2 256-byte pages.
1203 */
wdenkdc7c9a12003-03-26 06:55:25 +00001204static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
1205 size_t * retlen, const u_char * buf)
1206{
1207 int len256 = 0;
wdenk7a8e9bed2003-05-31 18:35:21 +00001208 int i;
wdenkdc7c9a12003-03-26 06:55:25 +00001209 unsigned long nandptr = nand->IO_ADDR;
1210
1211#ifdef PSYCHO_DEBUG
1212 printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1213 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1214 buf[8], buf[9], buf[14],buf[15]);
1215#endif
1216
wdenk7a8e9bed2003-05-31 18:35:21 +00001217 NAND_ENABLE_CE(nand); /* set pin low to enable chip */
1218
wdenkdc7c9a12003-03-26 06:55:25 +00001219 /* Reset the chip */
1220 NanD_Command(nand, NAND_CMD_RESET);
1221
1222 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1223 NanD_Command(nand, NAND_CMD_READOOB);
1224 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1225
1226 /* update address for 2M x 8bit devices. OOB starts on the second */
1227 /* page to maintain compatibility with nand_read_ecc. */
1228 if (nand->page256) {
1229 if (!(ofs & 0x8))
1230 ofs += 0x100;
1231 else
1232 ofs -= 0x8;
1233 }
1234
1235 /* issue the Serial Data In command to initial the Page Program process */
1236 NanD_Command(nand, NAND_CMD_SEQIN);
1237 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1238
1239 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1240 /* Note: datasheet says it should automaticaly wrap to the */
1241 /* next OOB block, but it didn't work here. mf. */
1242 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1243 len256 = (ofs | 0x7) + 1 - ofs;
wdenk7a8e9bed2003-05-31 18:35:21 +00001244 for (i = 0; i < len256; i++)
1245 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001246
1247 NanD_Command(nand, NAND_CMD_PAGEPROG);
1248 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001249#ifdef NAND_NO_RB
1250 { u_char ret_val;
1251 do{
1252 ret_val = READ_NAND(nandptr); /* wait till ready */
1253 }while((ret_val & 0x40) != 0x40);
1254 }
1255#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001256 if (READ_NAND(nandptr) & 1) {
1257 puts ("Error programming oob data\n");
1258 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001259 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001260 *retlen = 0;
1261 return -1;
1262 }
1263 NanD_Command(nand, NAND_CMD_SEQIN);
1264 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1265 }
1266
wdenk7a8e9bed2003-05-31 18:35:21 +00001267 for (i = len256; i < len; i++)
1268 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001269
1270 NanD_Command(nand, NAND_CMD_PAGEPROG);
1271 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001272#ifdef NAND_NO_RB
1273 { u_char ret_val;
1274 do{
1275 ret_val = READ_NAND(nandptr); /* wait till ready */
1276 } while((ret_val & 0x40) != 0x40);
1277 }
1278#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001279 if (READ_NAND(nandptr) & 1) {
1280 puts ("Error programming oob data\n");
1281 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001282 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001283 *retlen = 0;
1284 return -1;
1285 }
1286
wdenk7a8e9bed2003-05-31 18:35:21 +00001287 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001288 *retlen = len;
1289 return 0;
1290
1291}
wdenkdc7c9a12003-03-26 06:55:25 +00001292
wdenk7a8e9bed2003-05-31 18:35:21 +00001293static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
wdenkdc7c9a12003-03-26 06:55:25 +00001294{
wdenk7a8e9bed2003-05-31 18:35:21 +00001295 /* This is defined as a structure so it will work on any system
1296 * using native endian jffs2 (the default).
1297 */
1298 static struct jffs2_unknown_node clean_marker = {
1299 JFFS2_MAGIC_BITMASK,
1300 JFFS2_NODETYPE_CLEANMARKER,
1301 8 /* 8 bytes in this node */
1302 };
wdenkdc7c9a12003-03-26 06:55:25 +00001303 unsigned long nandptr;
1304 struct Nand *mychip;
wdenk85ec0bc2003-03-31 16:34:49 +00001305 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001306
1307 if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
1308 printf ("Offset and size must be sector aligned, erasesize = %d\n",
wdenk8bde7f72003-06-27 21:31:46 +00001309 (int) nand->erasesize);
wdenkdc7c9a12003-03-26 06:55:25 +00001310 return -1;
1311 }
1312
1313 nandptr = nand->IO_ADDR;
1314
wdenk85ec0bc2003-03-31 16:34:49 +00001315 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001316#ifdef CONFIG_OMAP1510
1317 archflashwp(0,0);
1318#endif
1319 NAND_ENABLE_CE(nand); /* set pin low */
wdenk85ec0bc2003-03-31 16:34:49 +00001320
1321 /* Check the WP bit */
1322 NanD_Command(nand, NAND_CMD_STATUS);
1323 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1324 printf ("nand_write_ecc: Device is write protected!!!\n");
1325 ret = -1;
1326 goto out;
1327 }
1328
wdenk0db5bca2003-03-31 17:27:09 +00001329 /* Check the WP bit */
1330 NanD_Command(nand, NAND_CMD_STATUS);
1331 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1332 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
1333 ret = -1;
1334 goto out;
1335 }
1336
wdenkdc7c9a12003-03-26 06:55:25 +00001337 /* FIXME: Do nand in the background. Use timers or schedule_task() */
1338 while(len) {
wdenk0db5bca2003-03-31 17:27:09 +00001339 /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
1340 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001341
wdenk7a8e9bed2003-05-31 18:35:21 +00001342 /* always check for bad block first, genuine bad blocks
1343 * should _never_ be erased.
1344 */
1345 if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
1346 /* Select the NAND device */
1347 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001348
wdenk7a8e9bed2003-05-31 18:35:21 +00001349 NanD_Command(nand, NAND_CMD_ERASE1);
1350 NanD_Address(nand, ADDR_PAGE, ofs);
1351 NanD_Command(nand, NAND_CMD_ERASE2);
wdenkdc7c9a12003-03-26 06:55:25 +00001352
wdenk7a8e9bed2003-05-31 18:35:21 +00001353 NanD_Command(nand, NAND_CMD_STATUS);
1354
wdenk1f4bb372003-07-27 00:21:01 +00001355#ifdef NAND_NO_RB
1356 { u_char ret_val;
1357 do{
1358 ret_val = READ_NAND(nandptr); /* wait till ready */
1359 } while((ret_val & 0x40) != 0x40);
1360 }
1361#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001362 if (READ_NAND(nandptr) & 1) {
1363 printf ("%s: Error erasing at 0x%lx\n",
1364 __FUNCTION__, (long)ofs);
1365 /* There was an error */
1366 ret = -1;
1367 goto out;
1368 }
1369 if (clean) {
1370 int n; /* return value not used */
1371 int p, l;
1372
1373 /* clean marker position and size depend
1374 * on the page size, since 256 byte pages
1375 * only have 8 bytes of oob data
1376 */
1377 if (nand->page256) {
1378 p = NAND_JFFS2_OOB8_FSDAPOS;
1379 l = NAND_JFFS2_OOB8_FSDALEN;
1380 }
1381 else {
1382 p = NAND_JFFS2_OOB16_FSDAPOS;
1383 l = NAND_JFFS2_OOB16_FSDALEN;
1384 }
1385
1386 ret = nand_write_oob(nand, ofs + p, l, &n,
1387 (u_char *)&clean_marker);
1388 /* quit here if write failed */
1389 if (ret)
1390 goto out;
1391 }
wdenkdc7c9a12003-03-26 06:55:25 +00001392 }
1393 ofs += nand->erasesize;
1394 len -= nand->erasesize;
1395 }
1396
wdenk85ec0bc2003-03-31 16:34:49 +00001397out:
1398 /* De-select the NAND device */
1399 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001400#ifdef CONFIG_OMAP1510
1401 archflashwp(0,1);
1402#endif
wdenk85ec0bc2003-03-31 16:34:49 +00001403 return ret;
wdenkdc7c9a12003-03-26 06:55:25 +00001404}
1405
1406static inline int nandcheck(unsigned long potential, unsigned long physadr)
1407{
wdenkdc7c9a12003-03-26 06:55:25 +00001408 return 0;
1409}
1410
1411void nand_probe(unsigned long physadr)
1412{
1413 struct nand_chip *nand = NULL;
1414 int i = 0, ChipID = 1;
1415
1416#ifdef CONFIG_MTD_NAND_ECC_JFFS2
1417 oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
1418 oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
1419 oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
1420 oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
1421 oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
1422 oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001423 oob_config.eccvalid_pos = 4;
1424#else
1425 oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
1426 oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
1427 oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
1428 oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
1429 oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
1430 oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001431 oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
1432#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001433 oob_config.badblock_pos = 5;
wdenkdc7c9a12003-03-26 06:55:25 +00001434
1435 for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
1436 if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
1437 nand = nand_dev_desc + i;
1438 break;
1439 }
1440 }
1441
wdenk7a8e9bed2003-05-31 18:35:21 +00001442 memset((char *)nand, 0, sizeof(struct nand_chip));
1443
1444 nand->IO_ADDR = physadr;
1445 nand->cache_page = -1; /* init the cache page */
1446 NanD_ScanChips(nand);
1447
1448 if (nand->totlen == 0) {
1449 /* no chips found, clean up and quit */
1450 memset((char *)nand, 0, sizeof(struct nand_chip));
1451 nand->ChipID = NAND_ChipID_UNKNOWN;
1452 return;
1453 }
1454
1455 nand->ChipID = ChipID;
wdenk0db5bca2003-03-31 17:27:09 +00001456 if (curr_device == -1)
1457 curr_device = i;
wdenkdc7c9a12003-03-26 06:55:25 +00001458
wdenk0db5bca2003-03-31 17:27:09 +00001459 nand->data_buf = malloc (nand->oobblock + nand->oobsize);
1460 if (!nand->data_buf) {
1461 puts ("Cannot allocate memory for data structures.\n");
1462 return;
1463 }
wdenkdc7c9a12003-03-26 06:55:25 +00001464}
1465
1466#ifdef CONFIG_MTD_NAND_ECC
1467/*
1468 * Pre-calculated 256-way 1 byte column parity
1469 */
1470static const u_char nand_ecc_precalc_table[] = {
1471 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
1472 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1473 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1474 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1475 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1476 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1477 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1478 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1479 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1480 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1481 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1482 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1483 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1484 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1485 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1486 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
1487};
1488
1489
1490/*
1491 * Creates non-inverted ECC code from line parity
1492 */
1493static void nand_trans_result(u_char reg2, u_char reg3,
1494 u_char *ecc_code)
1495{
1496 u_char a, b, i, tmp1, tmp2;
1497
1498 /* Initialize variables */
1499 a = b = 0x80;
1500 tmp1 = tmp2 = 0;
1501
1502 /* Calculate first ECC byte */
1503 for (i = 0; i < 4; i++) {
1504 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
1505 tmp1 |= b;
1506 b >>= 1;
1507 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
1508 tmp1 |= b;
1509 b >>= 1;
1510 a >>= 1;
1511 }
1512
1513 /* Calculate second ECC byte */
1514 b = 0x80;
1515 for (i = 0; i < 4; i++) {
1516 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
1517 tmp2 |= b;
1518 b >>= 1;
1519 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
1520 tmp2 |= b;
1521 b >>= 1;
1522 a >>= 1;
1523 }
1524
1525 /* Store two of the ECC bytes */
1526 ecc_code[0] = tmp1;
1527 ecc_code[1] = tmp2;
1528}
1529
1530/*
1531 * Calculate 3 byte ECC code for 256 byte block
1532 */
1533static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
1534{
wdenk7a8e9bed2003-05-31 18:35:21 +00001535 u_char idx, reg1, reg3;
wdenkdc7c9a12003-03-26 06:55:25 +00001536 int j;
1537
1538 /* Initialize variables */
wdenk7a8e9bed2003-05-31 18:35:21 +00001539 reg1 = reg3 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001540 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
1541
1542 /* Build up column parity */
1543 for(j = 0; j < 256; j++) {
1544
1545 /* Get CP0 - CP5 from table */
1546 idx = nand_ecc_precalc_table[dat[j]];
wdenk7a8e9bed2003-05-31 18:35:21 +00001547 reg1 ^= idx;
wdenkdc7c9a12003-03-26 06:55:25 +00001548
1549 /* All bit XOR = 1 ? */
1550 if (idx & 0x40) {
1551 reg3 ^= (u_char) j;
wdenkdc7c9a12003-03-26 06:55:25 +00001552 }
1553 }
1554
1555 /* Create non-inverted ECC code from line parity */
wdenk7a8e9bed2003-05-31 18:35:21 +00001556 nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
wdenkdc7c9a12003-03-26 06:55:25 +00001557
1558 /* Calculate final ECC code */
1559 ecc_code[0] = ~ecc_code[0];
1560 ecc_code[1] = ~ecc_code[1];
1561 ecc_code[2] = ((~reg1) << 2) | 0x03;
1562}
1563
1564/*
1565 * Detect and correct a 1 bit error for 256 byte block
1566 */
1567static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
1568{
1569 u_char a, b, c, d1, d2, d3, add, bit, i;
1570
1571 /* Do error detection */
1572 d1 = calc_ecc[0] ^ read_ecc[0];
1573 d2 = calc_ecc[1] ^ read_ecc[1];
1574 d3 = calc_ecc[2] ^ read_ecc[2];
1575
1576 if ((d1 | d2 | d3) == 0) {
1577 /* No errors */
1578 return 0;
1579 }
1580 else {
1581 a = (d1 ^ (d1 >> 1)) & 0x55;
1582 b = (d2 ^ (d2 >> 1)) & 0x55;
1583 c = (d3 ^ (d3 >> 1)) & 0x54;
1584
1585 /* Found and will correct single bit error in the data */
1586 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
1587 c = 0x80;
1588 add = 0;
1589 a = 0x80;
1590 for (i=0; i<4; i++) {
1591 if (d1 & c)
1592 add |= a;
1593 c >>= 2;
1594 a >>= 1;
1595 }
1596 c = 0x80;
1597 for (i=0; i<4; i++) {
1598 if (d2 & c)
1599 add |= a;
1600 c >>= 2;
1601 a >>= 1;
1602 }
1603 bit = 0;
1604 b = 0x04;
1605 c = 0x80;
1606 for (i=0; i<3; i++) {
1607 if (d3 & c)
1608 bit |= b;
1609 c >>= 2;
1610 b >>= 1;
1611 }
1612 b = 0x01;
1613 a = dat[add];
1614 a ^= (b << bit);
1615 dat[add] = a;
1616 return 1;
1617 }
1618 else {
1619 i = 0;
1620 while (d1) {
1621 if (d1 & 0x01)
1622 ++i;
1623 d1 >>= 1;
1624 }
1625 while (d2) {
1626 if (d2 & 0x01)
1627 ++i;
1628 d2 >>= 1;
1629 }
1630 while (d3) {
1631 if (d3 & 0x01)
1632 ++i;
1633 d3 >>= 1;
1634 }
1635 if (i == 1) {
1636 /* ECC Code Error Correction */
1637 read_ecc[0] = calc_ecc[0];
1638 read_ecc[1] = calc_ecc[1];
1639 read_ecc[2] = calc_ecc[2];
1640 return 2;
1641 }
1642 else {
1643 /* Uncorrectable Error */
1644 return -1;
1645 }
1646 }
1647 }
1648
1649 /* Should never happen */
1650 return -1;
1651}
wdenk1f4bb372003-07-27 00:21:01 +00001652
wdenkdc7c9a12003-03-26 06:55:25 +00001653#endif
1654#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */