blob: 0e49e9f08dad95d0170ae3c5e43d38c0d265265a [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
wdenka43278a2003-09-11 19:48:06 +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) {
wdenka43278a2003-09-11 19:48:06 +0000737#ifdef NAND_DEBUG
wdenk4d816772003-09-03 14:03:26 +0000738 puts ("No NAND flash chips recognised.\n");
wdenka43278a2003-09-11 19:48:06 +0000739#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000740 return;
741 }
742
743 /* Allocate an array to hold the information for each chip */
744 nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
745 if (!nand->chips) {
746 puts ("No memory for allocating chip info structures\n");
747 return;
748 }
749
750 ret = 0;
751
752 /* Fill out the chip array with {floor, chipno} for each
753 * detected chip in the device. */
754 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
755 for (chip = 0; chip < numchips[floor]; chip++) {
756 nand->chips[ret].floor = floor;
757 nand->chips[ret].chip = chip;
758 nand->chips[ret].curadr = 0;
759 nand->chips[ret].curmode = 0x50;
760 ret++;
761 }
762 }
763
764 /* Calculate and print the total size of the device */
765 nand->totlen = nand->numchips * (1 << nand->chipshift);
766
767#ifdef NAND_DEBUG
768 printf("%d flash chips found. Total nand_chip size: %ld MB\n",
769 nand->numchips, nand->totlen >> 20);
770#endif
771}
wdenk0db5bca2003-03-31 17:27:09 +0000772
wdenkdc7c9a12003-03-26 06:55:25 +0000773/* we need to be fast here, 1 us per read translates to 1 second per meg */
wdenk7a8e9bed2003-05-31 18:35:21 +0000774static void NanD_ReadBuf(struct nand_chip *nand, u_char *data_buf, int cntr)
wdenk0db5bca2003-03-31 17:27:09 +0000775{
wdenk7a8e9bed2003-05-31 18:35:21 +0000776 unsigned long nandptr = nand->IO_ADDR;
wdenk0db5bca2003-03-31 17:27:09 +0000777
wdenk7a8e9bed2003-05-31 18:35:21 +0000778 while (cntr >= 16) {
wdenk0db5bca2003-03-31 17:27:09 +0000779 *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 *data_buf++ = READ_NAND(nandptr);
794 *data_buf++ = READ_NAND(nandptr);
795 cntr -= 16;
796 }
797
798 while (cntr > 0) {
799 *data_buf++ = READ_NAND(nandptr);
800 cntr--;
801 }
802}
wdenkdc7c9a12003-03-26 06:55:25 +0000803
wdenkdc7c9a12003-03-26 06:55:25 +0000804/*
805 * NAND read with ECC
806 */
807static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
808 size_t * retlen, u_char *buf, u_char *ecc_code)
809{
810 int col, page;
811 int ecc_status = 0;
812#ifdef CONFIG_MTD_NAND_ECC
813 int j;
814 int ecc_failed = 0;
815 u_char *data_poi;
816 u_char ecc_calc[6];
817#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000818
819 /* Do not allow reads past end of device */
820 if ((start + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +0000821 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 +0000822 *retlen = 0;
823 return -1;
824 }
825
826 /* First we calculate the starting page */
wdenk0db5bca2003-03-31 17:27:09 +0000827 /*page = shr(start, nand->page_shift);*/
828 page = start >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000829
830 /* Get raw starting column */
831 col = start & (nand->oobblock - 1);
832
833 /* Initialize return value */
834 *retlen = 0;
835
836 /* Select the NAND device */
837 NAND_ENABLE_CE(nand); /* set pin low */
838
839 /* Loop until all data read */
840 while (*retlen < len) {
841
842
843#ifdef CONFIG_MTD_NAND_ECC
844
845 /* Do we have this page in cache ? */
846 if (nand->cache_page == page)
847 goto readdata;
848 /* Send the read command */
849 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000850 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000851 /* Read in a page + oob data */
wdenk7a8e9bed2003-05-31 18:35:21 +0000852 NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
wdenkdc7c9a12003-03-26 06:55:25 +0000853
854 /* copy data into cache, for read out of cache and if ecc fails */
855 if (nand->data_cache)
856 memcpy (nand->data_cache, nand->data_buf, nand->oobblock + nand->oobsize);
857
858 /* Pick the ECC bytes out of the oob data */
859 for (j = 0; j < 6; j++)
860 ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
861
862 /* Calculate the ECC and verify it */
863 /* If block was not written with ECC, skip ECC */
864 if (oob_config.eccvalid_pos != -1 &&
865 (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
866
867 nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
868 switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
869 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000870 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000871 ecc_failed++;
872 break;
873 case 1:
874 case 2: /* transfer ECC corrected data to cache */
wdenk7a8e9bed2003-05-31 18:35:21 +0000875 if (nand->data_cache)
876 memcpy (nand->data_cache, nand->data_buf, 256);
wdenkdc7c9a12003-03-26 06:55:25 +0000877 break;
878 }
879 }
880
881 if (oob_config.eccvalid_pos != -1 &&
882 nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
883
884 nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
885 switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
886 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000887 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000888 ecc_failed++;
889 break;
890 case 1:
891 case 2: /* transfer ECC corrected data to cache */
892 if (nand->data_cache)
893 memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
894 break;
895 }
896 }
897readdata:
898 /* Read the data from ECC data buffer into return buffer */
899 data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
900 data_poi += col;
901 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000902 memcpy (buf + *retlen, data_poi, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000903 *retlen = len;
904 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000905 memcpy (buf + *retlen, data_poi, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000906 *retlen += nand->oobblock - col;
907 }
908 /* Set cache page address, invalidate, if ecc_failed */
909 nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
910
911 ecc_status += ecc_failed;
912 ecc_failed = 0;
913
914#else
915 /* Send the read command */
916 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000917 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000918 /* Read the data directly into the return buffer */
919 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000920 NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000921 *retlen = len;
922 /* We're done */
923 continue;
924 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000925 NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000926 *retlen += nand->oobblock - col;
927 }
928#endif
929 /* For subsequent reads align to page boundary. */
930 col = 0;
931 /* Increment page address */
932 page++;
933 }
934
935 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +0000936 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000937
938 /*
939 * Return success, if no ECC failures, else -EIO
940 * fs driver will take care of that, because
941 * retlen == desired len and result == -EIO
942 */
943 return ecc_status ? -1 : 0;
944}
945
wdenkdc7c9a12003-03-26 06:55:25 +0000946/*
947 * Nand_page_program function is used for write and writev !
948 */
949static int nand_write_page (struct nand_chip *nand,
950 int page, int col, int last, u_char * ecc_code)
951{
952
953 int i;
wdenkdc7c9a12003-03-26 06:55:25 +0000954 unsigned long nandptr = nand->IO_ADDR;
wdenk1f4bb372003-07-27 00:21:01 +0000955#ifdef CONFIG_MTD_NAND_ECC
wdenkdc7c9a12003-03-26 06:55:25 +0000956#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
957 int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
958#endif
959#endif
960 /* pad oob area */
961 for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
962 nand->data_buf[i] = 0xff;
963
964#ifdef CONFIG_MTD_NAND_ECC
965 /* Zero out the ECC array */
966 for (i = 0; i < 6; i++)
967 ecc_code[i] = 0x00;
968
969 /* Read back previous written data, if col > 0 */
970 if (col) {
971 NanD_Command(nand, NAND_CMD_READ0);
wdenk0db5bca2003-03-31 17:27:09 +0000972 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000973 for (i = 0; i < col; i++)
974 nand->data_buf[i] = READ_NAND (nandptr);
975 }
976
977 /* Calculate and write the ECC if we have enough data */
978 if ((col < nand->eccsize) && (last >= nand->eccsize)) {
979 nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
980 for (i = 0; i < 3; i++)
981 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
982 if (oob_config.eccvalid_pos != -1)
983 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] = 0xf0;
984 }
985
986 /* Calculate and write the second ECC if we have enough data */
987 if ((nand->oobblock == 512) && (last == nand->oobblock)) {
988 nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
989 for (i = 3; i < 6; i++)
990 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
991 if (oob_config.eccvalid_pos != -1)
992 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] &= 0x0f;
993 }
994#endif
995 /* Prepad for partial page programming !!! */
996 for (i = 0; i < col; i++)
997 nand->data_buf[i] = 0xff;
998
999 /* Postpad for partial page programming !!! oob is already padded */
1000 for (i = last; i < nand->oobblock; i++)
1001 nand->data_buf[i] = 0xff;
1002
1003 /* Send command to begin auto page programming */
wdenk7a8e9bed2003-05-31 18:35:21 +00001004 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001005 NanD_Command(nand, NAND_CMD_SEQIN);
1006 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1007
1008 /* Write out complete page of data */
1009 for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
wdenk0db5bca2003-03-31 17:27:09 +00001010 WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
wdenkdc7c9a12003-03-26 06:55:25 +00001011
1012 /* Send command to actually program the data */
wdenk0db5bca2003-03-31 17:27:09 +00001013 NanD_Command(nand, NAND_CMD_PAGEPROG);
1014 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001015#ifdef NAND_NO_RB
1016 { u_char ret_val;
wdenkdc7c9a12003-03-26 06:55:25 +00001017
wdenk1f4bb372003-07-27 00:21:01 +00001018 do{
1019 ret_val = READ_NAND(nandptr); /* wait till ready */
1020 } while((ret_val & 0x40) != 0x40);
1021 }
1022#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001023 /* See if device thinks it succeeded */
1024 if (READ_NAND(nand->IO_ADDR) & 0x01) {
wdenk0db5bca2003-03-31 17:27:09 +00001025 printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001026 return -1;
1027 }
wdenk1f4bb372003-07-27 00:21:01 +00001028
wdenkdc7c9a12003-03-26 06:55:25 +00001029#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1030 /*
1031 * The NAND device assumes that it is always writing to
1032 * a cleanly erased page. Hence, it performs its internal
1033 * write verification only on bits that transitioned from
1034 * 1 to 0. The device does NOT verify the whole page on a
1035 * byte by byte basis. It is possible that the page was
1036 * not completely erased or the page is becoming unusable
1037 * due to wear. The read with ECC would catch the error
1038 * later when the ECC page check fails, but we would rather
1039 * catch it early in the page write stage. Better to write
1040 * no data than invalid data.
1041 */
1042
1043 /* Send command to read back the page */
1044 if (col < nand->eccsize)
wdenk0db5bca2003-03-31 17:27:09 +00001045 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001046 else
wdenk0db5bca2003-03-31 17:27:09 +00001047 NanD_Command(nand, NAND_CMD_READ1);
1048 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +00001049
1050 /* Loop through and verify the data */
1051 for (i = col; i < last; i++) {
1052 if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
wdenk0db5bca2003-03-31 17:27:09 +00001053 printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001054 return -1;
1055 }
1056 }
1057
1058#ifdef CONFIG_MTD_NAND_ECC
1059 /*
1060 * We also want to check that the ECC bytes wrote
1061 * correctly for the same reasons stated above.
1062 */
1063 NanD_Command(nand, NAND_CMD_READOOB);
1064 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1065 for (i = 0; i < nand->oobsize; i++)
1066 nand->data_buf[i] = readb (nand->IO_ADDR);
1067 for (i = 0; i < ecc_bytes; i++) {
1068 if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
wdenk0db5bca2003-03-31 17:27:09 +00001069 printf ("%s: Failed ECC write "
1070 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
wdenkdc7c9a12003-03-26 06:55:25 +00001071 return -1;
1072 }
1073 }
1074#endif
1075#endif
1076 return 0;
1077}
wdenk0db5bca2003-03-31 17:27:09 +00001078
wdenkdc7c9a12003-03-26 06:55:25 +00001079static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
1080 size_t * retlen, const u_char * buf, u_char * ecc_code)
1081{
1082 int i, page, col, cnt, ret = 0;
1083
1084 /* Do not allow write past end of device */
1085 if ((to + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +00001086 printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001087 return -1;
1088 }
1089
1090 /* Shift to get page */
1091 page = ((int) to) >> nand->page_shift;
1092
1093 /* Get the starting column */
1094 col = to & (nand->oobblock - 1);
1095
1096 /* Initialize return length value */
1097 *retlen = 0;
1098
1099 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001100#ifdef CONFIG_OMAP1510
1101 archflashwp(0,0);
1102#endif
1103 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001104
1105 /* Check the WP bit */
wdenk0db5bca2003-03-31 17:27:09 +00001106 NanD_Command(nand, NAND_CMD_STATUS);
wdenkdc7c9a12003-03-26 06:55:25 +00001107 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
wdenk0db5bca2003-03-31 17:27:09 +00001108 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001109 ret = -1;
1110 goto out;
1111 }
1112
1113 /* Loop until all data is written */
1114 while (*retlen < len) {
1115 /* Invalidate cache, if we write to this page */
1116 if (nand->cache_page == page)
1117 nand->cache_page = -1;
1118
1119 /* Write data into buffer */
1120 if ((col + len) >= nand->oobblock)
1121 for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++)
1122 nand->data_buf[i] = buf[(*retlen + cnt)];
1123 else
1124 for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++)
1125 nand->data_buf[i] = buf[(*retlen + cnt)];
1126 /* We use the same function for write and writev !) */
1127 ret = nand_write_page (nand, page, col, i, ecc_code);
1128 if (ret)
1129 goto out;
1130
1131 /* Next data start at page boundary */
1132 col = 0;
1133
1134 /* Update written bytes count */
1135 *retlen += cnt;
1136
1137 /* Increment page address */
1138 page++;
1139 }
1140
1141 /* Return happy */
1142 *retlen = len;
1143
1144out:
1145 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +00001146 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001147#ifdef CONFIG_OMAP1510
1148 archflashwp(0,1);
1149#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001150 return ret;
1151}
1152
wdenk7a8e9bed2003-05-31 18:35:21 +00001153/* read from the 16 bytes of oob data that correspond to a 512 byte
1154 * page or 2 256-byte pages.
wdenkdc7c9a12003-03-26 06:55:25 +00001155 */
wdenkdc7c9a12003-03-26 06:55:25 +00001156static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
wdenk7a8e9bed2003-05-31 18:35:21 +00001157 size_t * retlen, u_char * buf)
wdenkdc7c9a12003-03-26 06:55:25 +00001158{
wdenk7a8e9bed2003-05-31 18:35:21 +00001159 int len256 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001160 struct Nand *mychip;
wdenk0db5bca2003-03-31 17:27:09 +00001161 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001162
wdenk7a8e9bed2003-05-31 18:35:21 +00001163 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001164
1165 /* update address for 2M x 8bit devices. OOB starts on the second */
1166 /* page to maintain compatibility with nand_read_ecc. */
1167 if (nand->page256) {
1168 if (!(ofs & 0x8))
1169 ofs += 0x100;
1170 else
1171 ofs -= 0x8;
1172 }
1173
wdenk7a8e9bed2003-05-31 18:35:21 +00001174 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001175 NanD_Command(nand, NAND_CMD_READOOB);
1176 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1177
1178 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1179 /* Note: datasheet says it should automaticaly wrap to the */
1180 /* next OOB block, but it didn't work here. mf. */
1181 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1182 len256 = (ofs | 0x7) + 1 - ofs;
1183 NanD_ReadBuf(nand, buf, len256);
1184
1185 NanD_Command(nand, NAND_CMD_READOOB);
1186 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1187 }
1188
1189 NanD_ReadBuf(nand, &buf[len256], len - len256);
1190
1191 *retlen = len;
1192 /* Reading the full OOB data drops us off of the end of the page,
wdenk8bde7f72003-06-27 21:31:46 +00001193 * causing the flash device to go into busy mode, so we need
1194 * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
wdenkdc7c9a12003-03-26 06:55:25 +00001195
wdenk1f4bb372003-07-27 00:21:01 +00001196 ret = NanD_WaitReady(nand, 1);
wdenk8bde7f72003-06-27 21:31:46 +00001197 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001198
1199 return ret;
1200
1201}
wdenk7a8e9bed2003-05-31 18:35:21 +00001202
1203/* write to the 16 bytes of oob data that correspond to a 512 byte
1204 * page or 2 256-byte pages.
1205 */
wdenkdc7c9a12003-03-26 06:55:25 +00001206static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
1207 size_t * retlen, const u_char * buf)
1208{
1209 int len256 = 0;
wdenk7a8e9bed2003-05-31 18:35:21 +00001210 int i;
wdenkdc7c9a12003-03-26 06:55:25 +00001211 unsigned long nandptr = nand->IO_ADDR;
1212
1213#ifdef PSYCHO_DEBUG
1214 printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1215 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1216 buf[8], buf[9], buf[14],buf[15]);
1217#endif
1218
wdenk7a8e9bed2003-05-31 18:35:21 +00001219 NAND_ENABLE_CE(nand); /* set pin low to enable chip */
1220
wdenkdc7c9a12003-03-26 06:55:25 +00001221 /* Reset the chip */
1222 NanD_Command(nand, NAND_CMD_RESET);
1223
1224 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1225 NanD_Command(nand, NAND_CMD_READOOB);
1226 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1227
1228 /* update address for 2M x 8bit devices. OOB starts on the second */
1229 /* page to maintain compatibility with nand_read_ecc. */
1230 if (nand->page256) {
1231 if (!(ofs & 0x8))
1232 ofs += 0x100;
1233 else
1234 ofs -= 0x8;
1235 }
1236
1237 /* issue the Serial Data In command to initial the Page Program process */
1238 NanD_Command(nand, NAND_CMD_SEQIN);
1239 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1240
1241 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1242 /* Note: datasheet says it should automaticaly wrap to the */
1243 /* next OOB block, but it didn't work here. mf. */
1244 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1245 len256 = (ofs | 0x7) + 1 - ofs;
wdenk7a8e9bed2003-05-31 18:35:21 +00001246 for (i = 0; i < len256; i++)
1247 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001248
1249 NanD_Command(nand, NAND_CMD_PAGEPROG);
1250 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001251#ifdef NAND_NO_RB
1252 { u_char ret_val;
1253 do{
1254 ret_val = READ_NAND(nandptr); /* wait till ready */
1255 }while((ret_val & 0x40) != 0x40);
1256 }
1257#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001258 if (READ_NAND(nandptr) & 1) {
1259 puts ("Error programming oob data\n");
1260 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001261 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001262 *retlen = 0;
1263 return -1;
1264 }
1265 NanD_Command(nand, NAND_CMD_SEQIN);
1266 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1267 }
1268
wdenk7a8e9bed2003-05-31 18:35:21 +00001269 for (i = len256; i < len; i++)
1270 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001271
1272 NanD_Command(nand, NAND_CMD_PAGEPROG);
1273 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001274#ifdef NAND_NO_RB
1275 { u_char ret_val;
1276 do{
1277 ret_val = READ_NAND(nandptr); /* wait till ready */
1278 } while((ret_val & 0x40) != 0x40);
1279 }
1280#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001281 if (READ_NAND(nandptr) & 1) {
1282 puts ("Error programming oob data\n");
1283 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001284 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001285 *retlen = 0;
1286 return -1;
1287 }
1288
wdenk7a8e9bed2003-05-31 18:35:21 +00001289 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001290 *retlen = len;
1291 return 0;
1292
1293}
wdenkdc7c9a12003-03-26 06:55:25 +00001294
wdenk7a8e9bed2003-05-31 18:35:21 +00001295static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
wdenkdc7c9a12003-03-26 06:55:25 +00001296{
wdenk7a8e9bed2003-05-31 18:35:21 +00001297 /* This is defined as a structure so it will work on any system
1298 * using native endian jffs2 (the default).
1299 */
1300 static struct jffs2_unknown_node clean_marker = {
1301 JFFS2_MAGIC_BITMASK,
1302 JFFS2_NODETYPE_CLEANMARKER,
1303 8 /* 8 bytes in this node */
1304 };
wdenkdc7c9a12003-03-26 06:55:25 +00001305 unsigned long nandptr;
1306 struct Nand *mychip;
wdenk85ec0bc2003-03-31 16:34:49 +00001307 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001308
1309 if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
1310 printf ("Offset and size must be sector aligned, erasesize = %d\n",
wdenk8bde7f72003-06-27 21:31:46 +00001311 (int) nand->erasesize);
wdenkdc7c9a12003-03-26 06:55:25 +00001312 return -1;
1313 }
1314
1315 nandptr = nand->IO_ADDR;
1316
wdenk85ec0bc2003-03-31 16:34:49 +00001317 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001318#ifdef CONFIG_OMAP1510
1319 archflashwp(0,0);
1320#endif
1321 NAND_ENABLE_CE(nand); /* set pin low */
wdenk85ec0bc2003-03-31 16:34:49 +00001322
1323 /* Check the WP bit */
1324 NanD_Command(nand, NAND_CMD_STATUS);
1325 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1326 printf ("nand_write_ecc: Device is write protected!!!\n");
1327 ret = -1;
1328 goto out;
1329 }
1330
wdenk0db5bca2003-03-31 17:27:09 +00001331 /* Check the WP bit */
1332 NanD_Command(nand, NAND_CMD_STATUS);
1333 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1334 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
1335 ret = -1;
1336 goto out;
1337 }
1338
wdenkdc7c9a12003-03-26 06:55:25 +00001339 /* FIXME: Do nand in the background. Use timers or schedule_task() */
1340 while(len) {
wdenk0db5bca2003-03-31 17:27:09 +00001341 /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
1342 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001343
wdenk7a8e9bed2003-05-31 18:35:21 +00001344 /* always check for bad block first, genuine bad blocks
1345 * should _never_ be erased.
1346 */
1347 if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
1348 /* Select the NAND device */
1349 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001350
wdenk7a8e9bed2003-05-31 18:35:21 +00001351 NanD_Command(nand, NAND_CMD_ERASE1);
1352 NanD_Address(nand, ADDR_PAGE, ofs);
1353 NanD_Command(nand, NAND_CMD_ERASE2);
wdenkdc7c9a12003-03-26 06:55:25 +00001354
wdenk7a8e9bed2003-05-31 18:35:21 +00001355 NanD_Command(nand, NAND_CMD_STATUS);
1356
wdenk1f4bb372003-07-27 00:21:01 +00001357#ifdef NAND_NO_RB
1358 { u_char ret_val;
1359 do{
1360 ret_val = READ_NAND(nandptr); /* wait till ready */
1361 } while((ret_val & 0x40) != 0x40);
1362 }
1363#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001364 if (READ_NAND(nandptr) & 1) {
1365 printf ("%s: Error erasing at 0x%lx\n",
1366 __FUNCTION__, (long)ofs);
1367 /* There was an error */
1368 ret = -1;
1369 goto out;
1370 }
1371 if (clean) {
1372 int n; /* return value not used */
1373 int p, l;
1374
1375 /* clean marker position and size depend
1376 * on the page size, since 256 byte pages
1377 * only have 8 bytes of oob data
1378 */
1379 if (nand->page256) {
1380 p = NAND_JFFS2_OOB8_FSDAPOS;
1381 l = NAND_JFFS2_OOB8_FSDALEN;
1382 }
1383 else {
1384 p = NAND_JFFS2_OOB16_FSDAPOS;
1385 l = NAND_JFFS2_OOB16_FSDALEN;
1386 }
1387
1388 ret = nand_write_oob(nand, ofs + p, l, &n,
1389 (u_char *)&clean_marker);
1390 /* quit here if write failed */
1391 if (ret)
1392 goto out;
1393 }
wdenkdc7c9a12003-03-26 06:55:25 +00001394 }
1395 ofs += nand->erasesize;
1396 len -= nand->erasesize;
1397 }
1398
wdenk85ec0bc2003-03-31 16:34:49 +00001399out:
1400 /* De-select the NAND device */
1401 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001402#ifdef CONFIG_OMAP1510
1403 archflashwp(0,1);
1404#endif
wdenk85ec0bc2003-03-31 16:34:49 +00001405 return ret;
wdenkdc7c9a12003-03-26 06:55:25 +00001406}
1407
1408static inline int nandcheck(unsigned long potential, unsigned long physadr)
1409{
wdenkdc7c9a12003-03-26 06:55:25 +00001410 return 0;
1411}
1412
wdenka43278a2003-09-11 19:48:06 +00001413unsigned long nand_probe(unsigned long physadr)
wdenkdc7c9a12003-03-26 06:55:25 +00001414{
1415 struct nand_chip *nand = NULL;
1416 int i = 0, ChipID = 1;
1417
1418#ifdef CONFIG_MTD_NAND_ECC_JFFS2
1419 oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
1420 oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
1421 oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
1422 oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
1423 oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
1424 oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001425 oob_config.eccvalid_pos = 4;
1426#else
1427 oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
1428 oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
1429 oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
1430 oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
1431 oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
1432 oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001433 oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
1434#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001435 oob_config.badblock_pos = 5;
wdenkdc7c9a12003-03-26 06:55:25 +00001436
1437 for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
1438 if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
wdenka43278a2003-09-11 19:48:06 +00001439 nand = &nand_dev_desc[i];
wdenkdc7c9a12003-03-26 06:55:25 +00001440 break;
1441 }
1442 }
wdenka43278a2003-09-11 19:48:06 +00001443 if (!nand)
1444 return (0);
wdenkdc7c9a12003-03-26 06:55:25 +00001445
wdenk7a8e9bed2003-05-31 18:35:21 +00001446 memset((char *)nand, 0, sizeof(struct nand_chip));
1447
1448 nand->IO_ADDR = physadr;
1449 nand->cache_page = -1; /* init the cache page */
1450 NanD_ScanChips(nand);
1451
1452 if (nand->totlen == 0) {
1453 /* no chips found, clean up and quit */
1454 memset((char *)nand, 0, sizeof(struct nand_chip));
1455 nand->ChipID = NAND_ChipID_UNKNOWN;
wdenka43278a2003-09-11 19:48:06 +00001456 return (0);
wdenk7a8e9bed2003-05-31 18:35:21 +00001457 }
1458
1459 nand->ChipID = ChipID;
wdenk0db5bca2003-03-31 17:27:09 +00001460 if (curr_device == -1)
1461 curr_device = i;
wdenkdc7c9a12003-03-26 06:55:25 +00001462
wdenk0db5bca2003-03-31 17:27:09 +00001463 nand->data_buf = malloc (nand->oobblock + nand->oobsize);
1464 if (!nand->data_buf) {
1465 puts ("Cannot allocate memory for data structures.\n");
wdenka43278a2003-09-11 19:48:06 +00001466 return (0);
wdenk0db5bca2003-03-31 17:27:09 +00001467 }
wdenka43278a2003-09-11 19:48:06 +00001468
1469 return (nand->totlen);
wdenkdc7c9a12003-03-26 06:55:25 +00001470}
1471
1472#ifdef CONFIG_MTD_NAND_ECC
1473/*
1474 * Pre-calculated 256-way 1 byte column parity
1475 */
1476static const u_char nand_ecc_precalc_table[] = {
1477 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
1478 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1479 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1480 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1481 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1482 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1483 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1484 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1485 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1486 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1487 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1488 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1489 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1490 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1491 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1492 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
1493};
1494
1495
1496/*
1497 * Creates non-inverted ECC code from line parity
1498 */
1499static void nand_trans_result(u_char reg2, u_char reg3,
1500 u_char *ecc_code)
1501{
1502 u_char a, b, i, tmp1, tmp2;
1503
1504 /* Initialize variables */
1505 a = b = 0x80;
1506 tmp1 = tmp2 = 0;
1507
1508 /* Calculate first ECC byte */
1509 for (i = 0; i < 4; i++) {
1510 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
1511 tmp1 |= b;
1512 b >>= 1;
1513 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
1514 tmp1 |= b;
1515 b >>= 1;
1516 a >>= 1;
1517 }
1518
1519 /* Calculate second ECC byte */
1520 b = 0x80;
1521 for (i = 0; i < 4; i++) {
1522 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
1523 tmp2 |= b;
1524 b >>= 1;
1525 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
1526 tmp2 |= b;
1527 b >>= 1;
1528 a >>= 1;
1529 }
1530
1531 /* Store two of the ECC bytes */
1532 ecc_code[0] = tmp1;
1533 ecc_code[1] = tmp2;
1534}
1535
1536/*
1537 * Calculate 3 byte ECC code for 256 byte block
1538 */
1539static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
1540{
wdenk7a8e9bed2003-05-31 18:35:21 +00001541 u_char idx, reg1, reg3;
wdenkdc7c9a12003-03-26 06:55:25 +00001542 int j;
1543
1544 /* Initialize variables */
wdenk7a8e9bed2003-05-31 18:35:21 +00001545 reg1 = reg3 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001546 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
1547
1548 /* Build up column parity */
1549 for(j = 0; j < 256; j++) {
1550
1551 /* Get CP0 - CP5 from table */
1552 idx = nand_ecc_precalc_table[dat[j]];
wdenk7a8e9bed2003-05-31 18:35:21 +00001553 reg1 ^= idx;
wdenkdc7c9a12003-03-26 06:55:25 +00001554
1555 /* All bit XOR = 1 ? */
1556 if (idx & 0x40) {
1557 reg3 ^= (u_char) j;
wdenkdc7c9a12003-03-26 06:55:25 +00001558 }
1559 }
1560
1561 /* Create non-inverted ECC code from line parity */
wdenk7a8e9bed2003-05-31 18:35:21 +00001562 nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
wdenkdc7c9a12003-03-26 06:55:25 +00001563
1564 /* Calculate final ECC code */
1565 ecc_code[0] = ~ecc_code[0];
1566 ecc_code[1] = ~ecc_code[1];
1567 ecc_code[2] = ((~reg1) << 2) | 0x03;
1568}
1569
1570/*
1571 * Detect and correct a 1 bit error for 256 byte block
1572 */
1573static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
1574{
1575 u_char a, b, c, d1, d2, d3, add, bit, i;
1576
1577 /* Do error detection */
1578 d1 = calc_ecc[0] ^ read_ecc[0];
1579 d2 = calc_ecc[1] ^ read_ecc[1];
1580 d3 = calc_ecc[2] ^ read_ecc[2];
1581
1582 if ((d1 | d2 | d3) == 0) {
1583 /* No errors */
1584 return 0;
1585 }
1586 else {
1587 a = (d1 ^ (d1 >> 1)) & 0x55;
1588 b = (d2 ^ (d2 >> 1)) & 0x55;
1589 c = (d3 ^ (d3 >> 1)) & 0x54;
1590
1591 /* Found and will correct single bit error in the data */
1592 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
1593 c = 0x80;
1594 add = 0;
1595 a = 0x80;
1596 for (i=0; i<4; i++) {
1597 if (d1 & c)
1598 add |= a;
1599 c >>= 2;
1600 a >>= 1;
1601 }
1602 c = 0x80;
1603 for (i=0; i<4; i++) {
1604 if (d2 & c)
1605 add |= a;
1606 c >>= 2;
1607 a >>= 1;
1608 }
1609 bit = 0;
1610 b = 0x04;
1611 c = 0x80;
1612 for (i=0; i<3; i++) {
1613 if (d3 & c)
1614 bit |= b;
1615 c >>= 2;
1616 b >>= 1;
1617 }
1618 b = 0x01;
1619 a = dat[add];
1620 a ^= (b << bit);
1621 dat[add] = a;
1622 return 1;
1623 }
1624 else {
1625 i = 0;
1626 while (d1) {
1627 if (d1 & 0x01)
1628 ++i;
1629 d1 >>= 1;
1630 }
1631 while (d2) {
1632 if (d2 & 0x01)
1633 ++i;
1634 d2 >>= 1;
1635 }
1636 while (d3) {
1637 if (d3 & 0x01)
1638 ++i;
1639 d3 >>= 1;
1640 }
1641 if (i == 1) {
1642 /* ECC Code Error Correction */
1643 read_ecc[0] = calc_ecc[0];
1644 read_ecc[1] = calc_ecc[1];
1645 read_ecc[2] = calc_ecc[2];
1646 return 2;
1647 }
1648 else {
1649 /* Uncorrectable Error */
1650 return -1;
1651 }
1652 }
1653 }
1654
1655 /* Should never happen */
1656 return -1;
1657}
wdenk1f4bb372003-07-27 00:21:01 +00001658
wdenkdc7c9a12003-03-26 06:55:25 +00001659#endif
1660#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */