blob: 26cbe5d1f28f5a4ef1c37cbe28047960d5721c72 [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) {
642 printf("NanD_Command (ReadID) got %d %d\n", mfr, id);
643 return 0;
644 }
wdenkdc7c9a12003-03-26 06:55:25 +0000645
646 /* Check it's the same as the first chip we identified.
647 * M-Systems say that any given nand_chip device should only
648 * contain _one_ type of flash part, although that's not a
649 * hardware restriction. */
650 if (nand->mfr) {
651 if (nand->mfr == mfr && nand->id == id)
652 return 1; /* This is another the same the first */
653 else
654 printf("Flash chip at floor %d, chip %d is different:\n",
655 floor, chip);
656 }
657
658 /* Print and store the manufacturer and ID codes. */
659 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
660 if (mfr == nand_flash_ids[i].manufacture_id &&
661 id == nand_flash_ids[i].model_id) {
662#ifdef NAND_DEBUG
663 printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
664 "Chip ID: 0x%2.2X (%s)\n", mfr, id,
665 nand_flash_ids[i].name);
666#endif
667 if (!nand->mfr) {
668 nand->mfr = mfr;
669 nand->id = id;
670 nand->chipshift =
671 nand_flash_ids[i].chipshift;
672 nand->page256 = nand_flash_ids[i].page256;
wdenk7a8e9bed2003-05-31 18:35:21 +0000673 nand->eccsize = 256;
wdenkdc7c9a12003-03-26 06:55:25 +0000674 if (nand->page256) {
675 nand->oobblock = 256;
676 nand->oobsize = 8;
677 nand->page_shift = 8;
678 } else {
679 nand->oobblock = 512;
680 nand->oobsize = 16;
681 nand->page_shift = 9;
682 }
683 nand->pageadrlen =
684 nand_flash_ids[i].pageadrlen;
685 nand->erasesize =
686 nand_flash_ids[i].erasesize;
687 nand->chips_name =
688 nand_flash_ids[i].name;
689 return 1;
690 }
691 return 0;
692 }
693 }
694
695
696#ifdef NAND_DEBUG
697 /* We haven't fully identified the chip. Print as much as we know. */
698 printf("Unknown flash chip found: %2.2X %2.2X\n",
699 id, mfr);
700#endif
701
702 return 0;
703}
704
705/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
706
707static void NanD_ScanChips(struct nand_chip *nand)
708{
709 int floor, chip;
710 int numchips[NAND_MAX_FLOORS];
711 int maxchips = NAND_MAX_CHIPS;
712 int ret = 1;
713
714 nand->numchips = 0;
715 nand->mfr = 0;
716 nand->id = 0;
717
718
719 /* For each floor, find the number of valid chips it contains */
720 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
721 ret = 1;
722 numchips[floor] = 0;
723 for (chip = 0; chip < maxchips && ret != 0; chip++) {
724
725 ret = NanD_IdentChip(nand, floor, chip);
726 if (ret) {
727 numchips[floor]++;
728 nand->numchips++;
729 }
730 }
731 }
732
733 /* If there are none at all that we recognise, bail */
734 if (!nand->numchips) {
735 puts ("No flash chips recognised.\n");
736 return;
737 }
738
739 /* Allocate an array to hold the information for each chip */
740 nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
741 if (!nand->chips) {
742 puts ("No memory for allocating chip info structures\n");
743 return;
744 }
745
746 ret = 0;
747
748 /* Fill out the chip array with {floor, chipno} for each
749 * detected chip in the device. */
750 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
751 for (chip = 0; chip < numchips[floor]; chip++) {
752 nand->chips[ret].floor = floor;
753 nand->chips[ret].chip = chip;
754 nand->chips[ret].curadr = 0;
755 nand->chips[ret].curmode = 0x50;
756 ret++;
757 }
758 }
759
760 /* Calculate and print the total size of the device */
761 nand->totlen = nand->numchips * (1 << nand->chipshift);
762
763#ifdef NAND_DEBUG
764 printf("%d flash chips found. Total nand_chip size: %ld MB\n",
765 nand->numchips, nand->totlen >> 20);
766#endif
767}
wdenk0db5bca2003-03-31 17:27:09 +0000768
wdenkdc7c9a12003-03-26 06:55:25 +0000769/* we need to be fast here, 1 us per read translates to 1 second per meg */
wdenk7a8e9bed2003-05-31 18:35:21 +0000770static void NanD_ReadBuf(struct nand_chip *nand, u_char *data_buf, int cntr)
wdenk0db5bca2003-03-31 17:27:09 +0000771{
wdenk7a8e9bed2003-05-31 18:35:21 +0000772 unsigned long nandptr = nand->IO_ADDR;
wdenk0db5bca2003-03-31 17:27:09 +0000773
wdenk7a8e9bed2003-05-31 18:35:21 +0000774 while (cntr >= 16) {
wdenk0db5bca2003-03-31 17:27:09 +0000775 *data_buf++ = READ_NAND(nandptr);
776 *data_buf++ = READ_NAND(nandptr);
777 *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 cntr -= 16;
792 }
793
794 while (cntr > 0) {
795 *data_buf++ = READ_NAND(nandptr);
796 cntr--;
797 }
798}
wdenkdc7c9a12003-03-26 06:55:25 +0000799
wdenkdc7c9a12003-03-26 06:55:25 +0000800/*
801 * NAND read with ECC
802 */
803static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
804 size_t * retlen, u_char *buf, u_char *ecc_code)
805{
806 int col, page;
807 int ecc_status = 0;
808#ifdef CONFIG_MTD_NAND_ECC
809 int j;
810 int ecc_failed = 0;
811 u_char *data_poi;
812 u_char ecc_calc[6];
813#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000814
815 /* Do not allow reads past end of device */
816 if ((start + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +0000817 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 +0000818 *retlen = 0;
819 return -1;
820 }
821
822 /* First we calculate the starting page */
wdenk0db5bca2003-03-31 17:27:09 +0000823 /*page = shr(start, nand->page_shift);*/
824 page = start >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000825
826 /* Get raw starting column */
827 col = start & (nand->oobblock - 1);
828
829 /* Initialize return value */
830 *retlen = 0;
831
832 /* Select the NAND device */
833 NAND_ENABLE_CE(nand); /* set pin low */
834
835 /* Loop until all data read */
836 while (*retlen < len) {
837
838
839#ifdef CONFIG_MTD_NAND_ECC
840
841 /* Do we have this page in cache ? */
842 if (nand->cache_page == page)
843 goto readdata;
844 /* Send the read command */
845 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000846 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000847 /* Read in a page + oob data */
wdenk7a8e9bed2003-05-31 18:35:21 +0000848 NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
wdenkdc7c9a12003-03-26 06:55:25 +0000849
850 /* copy data into cache, for read out of cache and if ecc fails */
851 if (nand->data_cache)
852 memcpy (nand->data_cache, nand->data_buf, nand->oobblock + nand->oobsize);
853
854 /* Pick the ECC bytes out of the oob data */
855 for (j = 0; j < 6; j++)
856 ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
857
858 /* Calculate the ECC and verify it */
859 /* If block was not written with ECC, skip ECC */
860 if (oob_config.eccvalid_pos != -1 &&
861 (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
862
863 nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
864 switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
865 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000866 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000867 ecc_failed++;
868 break;
869 case 1:
870 case 2: /* transfer ECC corrected data to cache */
wdenk7a8e9bed2003-05-31 18:35:21 +0000871 if (nand->data_cache)
872 memcpy (nand->data_cache, nand->data_buf, 256);
wdenkdc7c9a12003-03-26 06:55:25 +0000873 break;
874 }
875 }
876
877 if (oob_config.eccvalid_pos != -1 &&
878 nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
879
880 nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
881 switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
882 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000883 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000884 ecc_failed++;
885 break;
886 case 1:
887 case 2: /* transfer ECC corrected data to cache */
888 if (nand->data_cache)
889 memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
890 break;
891 }
892 }
893readdata:
894 /* Read the data from ECC data buffer into return buffer */
895 data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
896 data_poi += col;
897 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000898 memcpy (buf + *retlen, data_poi, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000899 *retlen = len;
900 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000901 memcpy (buf + *retlen, data_poi, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000902 *retlen += nand->oobblock - col;
903 }
904 /* Set cache page address, invalidate, if ecc_failed */
905 nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
906
907 ecc_status += ecc_failed;
908 ecc_failed = 0;
909
910#else
911 /* Send the read command */
912 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000913 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000914 /* Read the data directly into the return buffer */
915 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000916 NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000917 *retlen = len;
918 /* We're done */
919 continue;
920 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000921 NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000922 *retlen += nand->oobblock - col;
923 }
924#endif
925 /* For subsequent reads align to page boundary. */
926 col = 0;
927 /* Increment page address */
928 page++;
929 }
930
931 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +0000932 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000933
934 /*
935 * Return success, if no ECC failures, else -EIO
936 * fs driver will take care of that, because
937 * retlen == desired len and result == -EIO
938 */
939 return ecc_status ? -1 : 0;
940}
941
wdenkdc7c9a12003-03-26 06:55:25 +0000942/*
943 * Nand_page_program function is used for write and writev !
944 */
945static int nand_write_page (struct nand_chip *nand,
946 int page, int col, int last, u_char * ecc_code)
947{
948
949 int i;
wdenkdc7c9a12003-03-26 06:55:25 +0000950 unsigned long nandptr = nand->IO_ADDR;
wdenk1f4bb372003-07-27 00:21:01 +0000951#ifdef CONFIG_MTD_NAND_ECC
wdenkdc7c9a12003-03-26 06:55:25 +0000952#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
953 int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
954#endif
955#endif
956 /* pad oob area */
957 for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
958 nand->data_buf[i] = 0xff;
959
960#ifdef CONFIG_MTD_NAND_ECC
961 /* Zero out the ECC array */
962 for (i = 0; i < 6; i++)
963 ecc_code[i] = 0x00;
964
965 /* Read back previous written data, if col > 0 */
966 if (col) {
967 NanD_Command(nand, NAND_CMD_READ0);
wdenk0db5bca2003-03-31 17:27:09 +0000968 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000969 for (i = 0; i < col; i++)
970 nand->data_buf[i] = READ_NAND (nandptr);
971 }
972
973 /* Calculate and write the ECC if we have enough data */
974 if ((col < nand->eccsize) && (last >= nand->eccsize)) {
975 nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
976 for (i = 0; i < 3; i++)
977 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
978 if (oob_config.eccvalid_pos != -1)
979 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] = 0xf0;
980 }
981
982 /* Calculate and write the second ECC if we have enough data */
983 if ((nand->oobblock == 512) && (last == nand->oobblock)) {
984 nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
985 for (i = 3; i < 6; i++)
986 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
987 if (oob_config.eccvalid_pos != -1)
988 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] &= 0x0f;
989 }
990#endif
991 /* Prepad for partial page programming !!! */
992 for (i = 0; i < col; i++)
993 nand->data_buf[i] = 0xff;
994
995 /* Postpad for partial page programming !!! oob is already padded */
996 for (i = last; i < nand->oobblock; i++)
997 nand->data_buf[i] = 0xff;
998
999 /* Send command to begin auto page programming */
wdenk7a8e9bed2003-05-31 18:35:21 +00001000 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001001 NanD_Command(nand, NAND_CMD_SEQIN);
1002 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1003
1004 /* Write out complete page of data */
1005 for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
wdenk0db5bca2003-03-31 17:27:09 +00001006 WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
wdenkdc7c9a12003-03-26 06:55:25 +00001007
1008 /* Send command to actually program the data */
wdenk0db5bca2003-03-31 17:27:09 +00001009 NanD_Command(nand, NAND_CMD_PAGEPROG);
1010 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001011#ifdef NAND_NO_RB
1012 { u_char ret_val;
wdenkdc7c9a12003-03-26 06:55:25 +00001013
wdenk1f4bb372003-07-27 00:21:01 +00001014 do{
1015 ret_val = READ_NAND(nandptr); /* wait till ready */
1016 } while((ret_val & 0x40) != 0x40);
1017 }
1018#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001019 /* See if device thinks it succeeded */
1020 if (READ_NAND(nand->IO_ADDR) & 0x01) {
wdenk0db5bca2003-03-31 17:27:09 +00001021 printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001022 return -1;
1023 }
wdenk1f4bb372003-07-27 00:21:01 +00001024
wdenkdc7c9a12003-03-26 06:55:25 +00001025#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1026 /*
1027 * The NAND device assumes that it is always writing to
1028 * a cleanly erased page. Hence, it performs its internal
1029 * write verification only on bits that transitioned from
1030 * 1 to 0. The device does NOT verify the whole page on a
1031 * byte by byte basis. It is possible that the page was
1032 * not completely erased or the page is becoming unusable
1033 * due to wear. The read with ECC would catch the error
1034 * later when the ECC page check fails, but we would rather
1035 * catch it early in the page write stage. Better to write
1036 * no data than invalid data.
1037 */
1038
1039 /* Send command to read back the page */
1040 if (col < nand->eccsize)
wdenk0db5bca2003-03-31 17:27:09 +00001041 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001042 else
wdenk0db5bca2003-03-31 17:27:09 +00001043 NanD_Command(nand, NAND_CMD_READ1);
1044 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +00001045
1046 /* Loop through and verify the data */
1047 for (i = col; i < last; i++) {
1048 if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
wdenk0db5bca2003-03-31 17:27:09 +00001049 printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001050 return -1;
1051 }
1052 }
1053
1054#ifdef CONFIG_MTD_NAND_ECC
1055 /*
1056 * We also want to check that the ECC bytes wrote
1057 * correctly for the same reasons stated above.
1058 */
1059 NanD_Command(nand, NAND_CMD_READOOB);
1060 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1061 for (i = 0; i < nand->oobsize; i++)
1062 nand->data_buf[i] = readb (nand->IO_ADDR);
1063 for (i = 0; i < ecc_bytes; i++) {
1064 if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
wdenk0db5bca2003-03-31 17:27:09 +00001065 printf ("%s: Failed ECC write "
1066 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
wdenkdc7c9a12003-03-26 06:55:25 +00001067 return -1;
1068 }
1069 }
1070#endif
1071#endif
1072 return 0;
1073}
wdenk0db5bca2003-03-31 17:27:09 +00001074
wdenkdc7c9a12003-03-26 06:55:25 +00001075static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
1076 size_t * retlen, const u_char * buf, u_char * ecc_code)
1077{
1078 int i, page, col, cnt, ret = 0;
1079
1080 /* Do not allow write past end of device */
1081 if ((to + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +00001082 printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001083 return -1;
1084 }
1085
1086 /* Shift to get page */
1087 page = ((int) to) >> nand->page_shift;
1088
1089 /* Get the starting column */
1090 col = to & (nand->oobblock - 1);
1091
1092 /* Initialize return length value */
1093 *retlen = 0;
1094
1095 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001096#ifdef CONFIG_OMAP1510
1097 archflashwp(0,0);
1098#endif
1099 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001100
1101 /* Check the WP bit */
wdenk0db5bca2003-03-31 17:27:09 +00001102 NanD_Command(nand, NAND_CMD_STATUS);
wdenkdc7c9a12003-03-26 06:55:25 +00001103 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
wdenk0db5bca2003-03-31 17:27:09 +00001104 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001105 ret = -1;
1106 goto out;
1107 }
1108
1109 /* Loop until all data is written */
1110 while (*retlen < len) {
1111 /* Invalidate cache, if we write to this page */
1112 if (nand->cache_page == page)
1113 nand->cache_page = -1;
1114
1115 /* Write data into buffer */
1116 if ((col + len) >= nand->oobblock)
1117 for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++)
1118 nand->data_buf[i] = buf[(*retlen + cnt)];
1119 else
1120 for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++)
1121 nand->data_buf[i] = buf[(*retlen + cnt)];
1122 /* We use the same function for write and writev !) */
1123 ret = nand_write_page (nand, page, col, i, ecc_code);
1124 if (ret)
1125 goto out;
1126
1127 /* Next data start at page boundary */
1128 col = 0;
1129
1130 /* Update written bytes count */
1131 *retlen += cnt;
1132
1133 /* Increment page address */
1134 page++;
1135 }
1136
1137 /* Return happy */
1138 *retlen = len;
1139
1140out:
1141 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +00001142 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001143#ifdef CONFIG_OMAP1510
1144 archflashwp(0,1);
1145#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001146 return ret;
1147}
1148
wdenk7a8e9bed2003-05-31 18:35:21 +00001149/* read from the 16 bytes of oob data that correspond to a 512 byte
1150 * page or 2 256-byte pages.
wdenkdc7c9a12003-03-26 06:55:25 +00001151 */
wdenkdc7c9a12003-03-26 06:55:25 +00001152static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
wdenk7a8e9bed2003-05-31 18:35:21 +00001153 size_t * retlen, u_char * buf)
wdenkdc7c9a12003-03-26 06:55:25 +00001154{
wdenk7a8e9bed2003-05-31 18:35:21 +00001155 int len256 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001156 struct Nand *mychip;
wdenk0db5bca2003-03-31 17:27:09 +00001157 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001158
wdenk7a8e9bed2003-05-31 18:35:21 +00001159 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001160
1161 /* update address for 2M x 8bit devices. OOB starts on the second */
1162 /* page to maintain compatibility with nand_read_ecc. */
1163 if (nand->page256) {
1164 if (!(ofs & 0x8))
1165 ofs += 0x100;
1166 else
1167 ofs -= 0x8;
1168 }
1169
wdenk7a8e9bed2003-05-31 18:35:21 +00001170 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001171 NanD_Command(nand, NAND_CMD_READOOB);
1172 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1173
1174 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1175 /* Note: datasheet says it should automaticaly wrap to the */
1176 /* next OOB block, but it didn't work here. mf. */
1177 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1178 len256 = (ofs | 0x7) + 1 - ofs;
1179 NanD_ReadBuf(nand, buf, len256);
1180
1181 NanD_Command(nand, NAND_CMD_READOOB);
1182 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1183 }
1184
1185 NanD_ReadBuf(nand, &buf[len256], len - len256);
1186
1187 *retlen = len;
1188 /* Reading the full OOB data drops us off of the end of the page,
wdenk8bde7f72003-06-27 21:31:46 +00001189 * causing the flash device to go into busy mode, so we need
1190 * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
wdenkdc7c9a12003-03-26 06:55:25 +00001191
wdenk1f4bb372003-07-27 00:21:01 +00001192 ret = NanD_WaitReady(nand, 1);
wdenk8bde7f72003-06-27 21:31:46 +00001193 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001194
1195 return ret;
1196
1197}
wdenk7a8e9bed2003-05-31 18:35:21 +00001198
1199/* write to the 16 bytes of oob data that correspond to a 512 byte
1200 * page or 2 256-byte pages.
1201 */
wdenkdc7c9a12003-03-26 06:55:25 +00001202static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
1203 size_t * retlen, const u_char * buf)
1204{
1205 int len256 = 0;
wdenk7a8e9bed2003-05-31 18:35:21 +00001206 int i;
wdenkdc7c9a12003-03-26 06:55:25 +00001207 unsigned long nandptr = nand->IO_ADDR;
1208
1209#ifdef PSYCHO_DEBUG
1210 printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1211 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1212 buf[8], buf[9], buf[14],buf[15]);
1213#endif
1214
wdenk7a8e9bed2003-05-31 18:35:21 +00001215 NAND_ENABLE_CE(nand); /* set pin low to enable chip */
1216
wdenkdc7c9a12003-03-26 06:55:25 +00001217 /* Reset the chip */
1218 NanD_Command(nand, NAND_CMD_RESET);
1219
1220 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1221 NanD_Command(nand, NAND_CMD_READOOB);
1222 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1223
1224 /* update address for 2M x 8bit devices. OOB starts on the second */
1225 /* page to maintain compatibility with nand_read_ecc. */
1226 if (nand->page256) {
1227 if (!(ofs & 0x8))
1228 ofs += 0x100;
1229 else
1230 ofs -= 0x8;
1231 }
1232
1233 /* issue the Serial Data In command to initial the Page Program process */
1234 NanD_Command(nand, NAND_CMD_SEQIN);
1235 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1236
1237 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1238 /* Note: datasheet says it should automaticaly wrap to the */
1239 /* next OOB block, but it didn't work here. mf. */
1240 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1241 len256 = (ofs | 0x7) + 1 - ofs;
wdenk7a8e9bed2003-05-31 18:35:21 +00001242 for (i = 0; i < len256; i++)
1243 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001244
1245 NanD_Command(nand, NAND_CMD_PAGEPROG);
1246 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001247#ifdef NAND_NO_RB
1248 { u_char ret_val;
1249 do{
1250 ret_val = READ_NAND(nandptr); /* wait till ready */
1251 }while((ret_val & 0x40) != 0x40);
1252 }
1253#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001254 if (READ_NAND(nandptr) & 1) {
1255 puts ("Error programming oob data\n");
1256 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001257 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001258 *retlen = 0;
1259 return -1;
1260 }
1261 NanD_Command(nand, NAND_CMD_SEQIN);
1262 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1263 }
1264
wdenk7a8e9bed2003-05-31 18:35:21 +00001265 for (i = len256; i < len; i++)
1266 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001267
1268 NanD_Command(nand, NAND_CMD_PAGEPROG);
1269 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001270#ifdef NAND_NO_RB
1271 { u_char ret_val;
1272 do{
1273 ret_val = READ_NAND(nandptr); /* wait till ready */
1274 } while((ret_val & 0x40) != 0x40);
1275 }
1276#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001277 if (READ_NAND(nandptr) & 1) {
1278 puts ("Error programming oob data\n");
1279 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001280 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001281 *retlen = 0;
1282 return -1;
1283 }
1284
wdenk7a8e9bed2003-05-31 18:35:21 +00001285 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001286 *retlen = len;
1287 return 0;
1288
1289}
wdenkdc7c9a12003-03-26 06:55:25 +00001290
wdenk7a8e9bed2003-05-31 18:35:21 +00001291static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
wdenkdc7c9a12003-03-26 06:55:25 +00001292{
wdenk7a8e9bed2003-05-31 18:35:21 +00001293 /* This is defined as a structure so it will work on any system
1294 * using native endian jffs2 (the default).
1295 */
1296 static struct jffs2_unknown_node clean_marker = {
1297 JFFS2_MAGIC_BITMASK,
1298 JFFS2_NODETYPE_CLEANMARKER,
1299 8 /* 8 bytes in this node */
1300 };
wdenkdc7c9a12003-03-26 06:55:25 +00001301 unsigned long nandptr;
1302 struct Nand *mychip;
wdenk85ec0bc2003-03-31 16:34:49 +00001303 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001304
1305 if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
1306 printf ("Offset and size must be sector aligned, erasesize = %d\n",
wdenk8bde7f72003-06-27 21:31:46 +00001307 (int) nand->erasesize);
wdenkdc7c9a12003-03-26 06:55:25 +00001308 return -1;
1309 }
1310
1311 nandptr = nand->IO_ADDR;
1312
wdenk85ec0bc2003-03-31 16:34:49 +00001313 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001314#ifdef CONFIG_OMAP1510
1315 archflashwp(0,0);
1316#endif
1317 NAND_ENABLE_CE(nand); /* set pin low */
wdenk85ec0bc2003-03-31 16:34:49 +00001318
1319 /* Check the WP bit */
1320 NanD_Command(nand, NAND_CMD_STATUS);
1321 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1322 printf ("nand_write_ecc: Device is write protected!!!\n");
1323 ret = -1;
1324 goto out;
1325 }
1326
wdenk0db5bca2003-03-31 17:27:09 +00001327 /* Check the WP bit */
1328 NanD_Command(nand, NAND_CMD_STATUS);
1329 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1330 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
1331 ret = -1;
1332 goto out;
1333 }
1334
wdenkdc7c9a12003-03-26 06:55:25 +00001335 /* FIXME: Do nand in the background. Use timers or schedule_task() */
1336 while(len) {
wdenk0db5bca2003-03-31 17:27:09 +00001337 /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
1338 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001339
wdenk7a8e9bed2003-05-31 18:35:21 +00001340 /* always check for bad block first, genuine bad blocks
1341 * should _never_ be erased.
1342 */
1343 if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
1344 /* Select the NAND device */
1345 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001346
wdenk7a8e9bed2003-05-31 18:35:21 +00001347 NanD_Command(nand, NAND_CMD_ERASE1);
1348 NanD_Address(nand, ADDR_PAGE, ofs);
1349 NanD_Command(nand, NAND_CMD_ERASE2);
wdenkdc7c9a12003-03-26 06:55:25 +00001350
wdenk7a8e9bed2003-05-31 18:35:21 +00001351 NanD_Command(nand, NAND_CMD_STATUS);
1352
wdenk1f4bb372003-07-27 00:21:01 +00001353#ifdef NAND_NO_RB
1354 { u_char ret_val;
1355 do{
1356 ret_val = READ_NAND(nandptr); /* wait till ready */
1357 } while((ret_val & 0x40) != 0x40);
1358 }
1359#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001360 if (READ_NAND(nandptr) & 1) {
1361 printf ("%s: Error erasing at 0x%lx\n",
1362 __FUNCTION__, (long)ofs);
1363 /* There was an error */
1364 ret = -1;
1365 goto out;
1366 }
1367 if (clean) {
1368 int n; /* return value not used */
1369 int p, l;
1370
1371 /* clean marker position and size depend
1372 * on the page size, since 256 byte pages
1373 * only have 8 bytes of oob data
1374 */
1375 if (nand->page256) {
1376 p = NAND_JFFS2_OOB8_FSDAPOS;
1377 l = NAND_JFFS2_OOB8_FSDALEN;
1378 }
1379 else {
1380 p = NAND_JFFS2_OOB16_FSDAPOS;
1381 l = NAND_JFFS2_OOB16_FSDALEN;
1382 }
1383
1384 ret = nand_write_oob(nand, ofs + p, l, &n,
1385 (u_char *)&clean_marker);
1386 /* quit here if write failed */
1387 if (ret)
1388 goto out;
1389 }
wdenkdc7c9a12003-03-26 06:55:25 +00001390 }
1391 ofs += nand->erasesize;
1392 len -= nand->erasesize;
1393 }
1394
wdenk85ec0bc2003-03-31 16:34:49 +00001395out:
1396 /* De-select the NAND device */
1397 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001398#ifdef CONFIG_OMAP1510
1399 archflashwp(0,1);
1400#endif
wdenk85ec0bc2003-03-31 16:34:49 +00001401 return ret;
wdenkdc7c9a12003-03-26 06:55:25 +00001402}
1403
1404static inline int nandcheck(unsigned long potential, unsigned long physadr)
1405{
wdenkdc7c9a12003-03-26 06:55:25 +00001406 return 0;
1407}
1408
1409void nand_probe(unsigned long physadr)
1410{
1411 struct nand_chip *nand = NULL;
1412 int i = 0, ChipID = 1;
1413
1414#ifdef CONFIG_MTD_NAND_ECC_JFFS2
1415 oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
1416 oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
1417 oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
1418 oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
1419 oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
1420 oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001421 oob_config.eccvalid_pos = 4;
1422#else
1423 oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
1424 oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
1425 oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
1426 oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
1427 oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
1428 oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001429 oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
1430#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001431 oob_config.badblock_pos = 5;
wdenkdc7c9a12003-03-26 06:55:25 +00001432
1433 for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
1434 if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
1435 nand = nand_dev_desc + i;
1436 break;
1437 }
1438 }
1439
wdenk7a8e9bed2003-05-31 18:35:21 +00001440 memset((char *)nand, 0, sizeof(struct nand_chip));
1441
1442 nand->IO_ADDR = physadr;
1443 nand->cache_page = -1; /* init the cache page */
1444 NanD_ScanChips(nand);
1445
1446 if (nand->totlen == 0) {
1447 /* no chips found, clean up and quit */
1448 memset((char *)nand, 0, sizeof(struct nand_chip));
1449 nand->ChipID = NAND_ChipID_UNKNOWN;
1450 return;
1451 }
1452
1453 nand->ChipID = ChipID;
wdenk0db5bca2003-03-31 17:27:09 +00001454 if (curr_device == -1)
1455 curr_device = i;
wdenkdc7c9a12003-03-26 06:55:25 +00001456
wdenk0db5bca2003-03-31 17:27:09 +00001457 nand->data_buf = malloc (nand->oobblock + nand->oobsize);
1458 if (!nand->data_buf) {
1459 puts ("Cannot allocate memory for data structures.\n");
1460 return;
1461 }
wdenkdc7c9a12003-03-26 06:55:25 +00001462}
1463
1464#ifdef CONFIG_MTD_NAND_ECC
1465/*
1466 * Pre-calculated 256-way 1 byte column parity
1467 */
1468static const u_char nand_ecc_precalc_table[] = {
1469 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
1470 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1471 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1472 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1473 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1474 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1475 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1476 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1477 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1478 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1479 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1480 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1481 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1482 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1483 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1484 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
1485};
1486
1487
1488/*
1489 * Creates non-inverted ECC code from line parity
1490 */
1491static void nand_trans_result(u_char reg2, u_char reg3,
1492 u_char *ecc_code)
1493{
1494 u_char a, b, i, tmp1, tmp2;
1495
1496 /* Initialize variables */
1497 a = b = 0x80;
1498 tmp1 = tmp2 = 0;
1499
1500 /* Calculate first ECC byte */
1501 for (i = 0; i < 4; i++) {
1502 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
1503 tmp1 |= b;
1504 b >>= 1;
1505 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
1506 tmp1 |= b;
1507 b >>= 1;
1508 a >>= 1;
1509 }
1510
1511 /* Calculate second ECC byte */
1512 b = 0x80;
1513 for (i = 0; i < 4; i++) {
1514 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
1515 tmp2 |= b;
1516 b >>= 1;
1517 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
1518 tmp2 |= b;
1519 b >>= 1;
1520 a >>= 1;
1521 }
1522
1523 /* Store two of the ECC bytes */
1524 ecc_code[0] = tmp1;
1525 ecc_code[1] = tmp2;
1526}
1527
1528/*
1529 * Calculate 3 byte ECC code for 256 byte block
1530 */
1531static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
1532{
wdenk7a8e9bed2003-05-31 18:35:21 +00001533 u_char idx, reg1, reg3;
wdenkdc7c9a12003-03-26 06:55:25 +00001534 int j;
1535
1536 /* Initialize variables */
wdenk7a8e9bed2003-05-31 18:35:21 +00001537 reg1 = reg3 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001538 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
1539
1540 /* Build up column parity */
1541 for(j = 0; j < 256; j++) {
1542
1543 /* Get CP0 - CP5 from table */
1544 idx = nand_ecc_precalc_table[dat[j]];
wdenk7a8e9bed2003-05-31 18:35:21 +00001545 reg1 ^= idx;
wdenkdc7c9a12003-03-26 06:55:25 +00001546
1547 /* All bit XOR = 1 ? */
1548 if (idx & 0x40) {
1549 reg3 ^= (u_char) j;
wdenkdc7c9a12003-03-26 06:55:25 +00001550 }
1551 }
1552
1553 /* Create non-inverted ECC code from line parity */
wdenk7a8e9bed2003-05-31 18:35:21 +00001554 nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
wdenkdc7c9a12003-03-26 06:55:25 +00001555
1556 /* Calculate final ECC code */
1557 ecc_code[0] = ~ecc_code[0];
1558 ecc_code[1] = ~ecc_code[1];
1559 ecc_code[2] = ((~reg1) << 2) | 0x03;
1560}
1561
1562/*
1563 * Detect and correct a 1 bit error for 256 byte block
1564 */
1565static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
1566{
1567 u_char a, b, c, d1, d2, d3, add, bit, i;
1568
1569 /* Do error detection */
1570 d1 = calc_ecc[0] ^ read_ecc[0];
1571 d2 = calc_ecc[1] ^ read_ecc[1];
1572 d3 = calc_ecc[2] ^ read_ecc[2];
1573
1574 if ((d1 | d2 | d3) == 0) {
1575 /* No errors */
1576 return 0;
1577 }
1578 else {
1579 a = (d1 ^ (d1 >> 1)) & 0x55;
1580 b = (d2 ^ (d2 >> 1)) & 0x55;
1581 c = (d3 ^ (d3 >> 1)) & 0x54;
1582
1583 /* Found and will correct single bit error in the data */
1584 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
1585 c = 0x80;
1586 add = 0;
1587 a = 0x80;
1588 for (i=0; i<4; i++) {
1589 if (d1 & c)
1590 add |= a;
1591 c >>= 2;
1592 a >>= 1;
1593 }
1594 c = 0x80;
1595 for (i=0; i<4; i++) {
1596 if (d2 & c)
1597 add |= a;
1598 c >>= 2;
1599 a >>= 1;
1600 }
1601 bit = 0;
1602 b = 0x04;
1603 c = 0x80;
1604 for (i=0; i<3; i++) {
1605 if (d3 & c)
1606 bit |= b;
1607 c >>= 2;
1608 b >>= 1;
1609 }
1610 b = 0x01;
1611 a = dat[add];
1612 a ^= (b << bit);
1613 dat[add] = a;
1614 return 1;
1615 }
1616 else {
1617 i = 0;
1618 while (d1) {
1619 if (d1 & 0x01)
1620 ++i;
1621 d1 >>= 1;
1622 }
1623 while (d2) {
1624 if (d2 & 0x01)
1625 ++i;
1626 d2 >>= 1;
1627 }
1628 while (d3) {
1629 if (d3 & 0x01)
1630 ++i;
1631 d3 >>= 1;
1632 }
1633 if (i == 1) {
1634 /* ECC Code Error Correction */
1635 read_ecc[0] = calc_ecc[0];
1636 read_ecc[1] = calc_ecc[1];
1637 read_ecc[2] = calc_ecc[2];
1638 return 2;
1639 }
1640 else {
1641 /* Uncorrectable Error */
1642 return -1;
1643 }
1644 }
1645 }
1646
1647 /* Should never happen */
1648 return -1;
1649}
wdenk1f4bb372003-07-27 00:21:01 +00001650
wdenkdc7c9a12003-03-26 06:55:25 +00001651#endif
1652#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */