blob: 4b693a999a1410912806b160000d0722dc8d5f76 [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>
wdenka3d991b2004-04-15 21:48:45 +000012#include <watchdog.h>
wdenkdc7c9a12003-03-26 06:55:25 +000013
14#ifdef CONFIG_SHOW_BOOT_PROGRESS
15# include <status_led.h>
16# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
17#else
18# define SHOW_BOOT_PROGRESS(arg)
19#endif
20
21#if (CONFIG_COMMANDS & CFG_CMD_NAND)
22
wdenkdc7c9a12003-03-26 06:55:25 +000023#include <linux/mtd/nand.h>
24#include <linux/mtd/nand_ids.h>
wdenk7a8e9bed2003-05-31 18:35:21 +000025#include <jffs2/jffs2.h>
wdenkdc7c9a12003-03-26 06:55:25 +000026
wdenk1f4bb372003-07-27 00:21:01 +000027#ifdef CONFIG_OMAP1510
28void archflashwp(void *archdata, int wp);
29#endif
30
31#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
32
wdenkdc7c9a12003-03-26 06:55:25 +000033/*
34 * Definition of the out of band configuration structure
35 */
36struct nand_oob_config {
37 int ecc_pos[6]; /* position of ECC bytes inside oob */
38 int badblock_pos; /* position of bad block flag inside oob -1 = inactive */
39 int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */
40} oob_config = { {0}, 0, 0};
41
wdenka43278a2003-09-11 19:48:06 +000042#undef NAND_DEBUG
wdenkdc7c9a12003-03-26 06:55:25 +000043#undef PSYCHO_DEBUG
wdenk7a8e9bed2003-05-31 18:35:21 +000044
45/* ****************** WARNING *********************
46 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
47 * erase (or at least attempt to erase) blocks that are marked
48 * bad. This can be very handy if you are _sure_ that the block
49 * is OK, say because you marked a good block bad to test bad
50 * block handling and you are done testing, or if you have
51 * accidentally marked blocks bad.
52 *
53 * Erasing factory marked bad blocks is a _bad_ idea. If the
54 * erase succeeds there is no reliable way to find them again,
55 * and attempting to program or erase bad blocks can affect
56 * the data in _other_ (good) blocks.
57 */
58#define ALLOW_ERASE_BAD_DEBUG 0
wdenkdc7c9a12003-03-26 06:55:25 +000059
60#define CONFIG_MTD_NAND_ECC /* enable ECC */
wdenk1f4bb372003-07-27 00:21:01 +000061#define CONFIG_MTD_NAND_ECC_JFFS2
wdenkdc7c9a12003-03-26 06:55:25 +000062
wdenk7a8e9bed2003-05-31 18:35:21 +000063/* bits for nand_rw() `cmd'; or together as needed */
64#define NANDRW_READ 0x01
65#define NANDRW_WRITE 0x00
66#define NANDRW_JFFS2 0x02
wdenka3d991b2004-04-15 21:48:45 +000067#define NANDRW_JFFS2_SKIP 0x04
wdenk7a8e9bed2003-05-31 18:35:21 +000068
wdenkdc7c9a12003-03-26 06:55:25 +000069/*
70 * Function Prototypes
71 */
72static void nand_print(struct nand_chip *nand);
73static int nand_rw (struct nand_chip* nand, int cmd,
74 size_t start, size_t len,
75 size_t * retlen, u_char * buf);
wdenk7a8e9bed2003-05-31 18:35:21 +000076static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);
wdenkdc7c9a12003-03-26 06:55:25 +000077static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
78 size_t * retlen, u_char *buf, u_char *ecc_code);
79static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
80 size_t * retlen, const u_char * buf, u_char * ecc_code);
wdenk7a8e9bed2003-05-31 18:35:21 +000081static void nand_print_bad(struct nand_chip *nand);
82static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
83 size_t * retlen, u_char * buf);
84static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
85 size_t * retlen, const u_char * buf);
wdenk1f4bb372003-07-27 00:21:01 +000086static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
wdenkdc7c9a12003-03-26 06:55:25 +000087#ifdef CONFIG_MTD_NAND_ECC
88static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
89static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
90#endif
91
wdenk7a8e9bed2003-05-31 18:35:21 +000092struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
wdenkdc7c9a12003-03-26 06:55:25 +000093
94/* Current NAND Device */
95static int curr_device = -1;
96
97/* ------------------------------------------------------------------------- */
98
99int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
100{
101 int rcode = 0;
102
103 switch (argc) {
104 case 0:
105 case 1:
106 printf ("Usage:\n%s\n", cmdtp->usage);
107 return 1;
108 case 2:
wdenk8bde7f72003-06-27 21:31:46 +0000109 if (strcmp(argv[1],"info") == 0) {
wdenkdc7c9a12003-03-26 06:55:25 +0000110 int i;
111
112 putc ('\n');
113
114 for (i=0; i<CFG_MAX_NAND_DEVICE; ++i) {
115 if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)
116 continue; /* list only known devices */
117 printf ("Device %d: ", i);
118 nand_print(&nand_dev_desc[i]);
119 }
120 return 0;
121
122 } else if (strcmp(argv[1],"device") == 0) {
123 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
124 puts ("\nno devices available\n");
125 return 1;
126 }
127 printf ("\nDevice %d: ", curr_device);
128 nand_print(&nand_dev_desc[curr_device]);
129 return 0;
wdenk7a8e9bed2003-05-31 18:35:21 +0000130
131 } else if (strcmp(argv[1],"bad") == 0) {
132 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
133 puts ("\nno devices available\n");
134 return 1;
135 }
136 printf ("\nDevice %d bad blocks:\n", curr_device);
137 nand_print_bad(&nand_dev_desc[curr_device]);
138 return 0;
139
wdenkdc7c9a12003-03-26 06:55:25 +0000140 }
141 printf ("Usage:\n%s\n", cmdtp->usage);
142 return 1;
143 case 3:
144 if (strcmp(argv[1],"device") == 0) {
145 int dev = (int)simple_strtoul(argv[2], NULL, 10);
146
147 printf ("\nDevice %d: ", dev);
148 if (dev >= CFG_MAX_NAND_DEVICE) {
149 puts ("unknown device\n");
150 return 1;
151 }
152 nand_print(&nand_dev_desc[dev]);
153 /*nand_print (dev);*/
154
155 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {
156 return 1;
157 }
158
159 curr_device = dev;
160
161 puts ("... is now current device\n");
162
163 return 0;
164 }
wdenk7a8e9bed2003-05-31 18:35:21 +0000165 else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) {
166 struct nand_chip* nand = &nand_dev_desc[curr_device];
167 ulong off = 0;
168 ulong size = nand->totlen;
169 int ret;
170
171 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
172 curr_device, off, size);
173
174 ret = nand_erase (nand, off, size, 1);
175
176 printf("%s\n", ret ? "ERROR" : "OK");
177
178 return ret;
179 }
wdenkdc7c9a12003-03-26 06:55:25 +0000180
181 printf ("Usage:\n%s\n", cmdtp->usage);
182 return 1;
183 default:
184 /* at least 4 args */
185
wdenk7a8e9bed2003-05-31 18:35:21 +0000186 if (strncmp(argv[1], "read", 4) == 0 ||
187 strncmp(argv[1], "write", 5) == 0) {
wdenkdc7c9a12003-03-26 06:55:25 +0000188 ulong addr = simple_strtoul(argv[2], NULL, 16);
189 ulong off = simple_strtoul(argv[3], NULL, 16);
190 ulong size = simple_strtoul(argv[4], NULL, 16);
wdenk7a8e9bed2003-05-31 18:35:21 +0000191 int cmd = (strncmp(argv[1], "read", 4) == 0) ?
192 NANDRW_READ : NANDRW_WRITE;
wdenkdc7c9a12003-03-26 06:55:25 +0000193 int ret, total;
wdenk7a8e9bed2003-05-31 18:35:21 +0000194 char* cmdtail = strchr(argv[1], '.');
195
196 if (cmdtail && !strncmp(cmdtail, ".oob", 2)) {
197 /* read out-of-band data */
198 if (cmd & NANDRW_READ) {
199 ret = nand_read_oob(nand_dev_desc + curr_device,
200 off, size, &total,
201 (u_char*)addr);
202 }
203 else {
204 ret = nand_write_oob(nand_dev_desc + curr_device,
205 off, size, &total,
206 (u_char*)addr);
207 }
208 return ret;
209 }
210 else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
211 cmd |= NANDRW_JFFS2; /* skip bad blocks */
wdenka3d991b2004-04-15 21:48:45 +0000212 else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) {
213 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
214 if (cmd & NANDRW_READ)
215 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
216 }
wdenk7a8e9bed2003-05-31 18:35:21 +0000217#ifdef SXNI855T
218 /* need ".e" same as ".j" for compatibility with older units */
219 else if (cmdtail && !strcmp(cmdtail, ".e"))
220 cmd |= NANDRW_JFFS2; /* skip bad blocks */
221#endif
222 else if (cmdtail) {
223 printf ("Usage:\n%s\n", cmdtp->usage);
224 return 1;
225 }
wdenkdc7c9a12003-03-26 06:55:25 +0000226
227 printf ("\nNAND %s: device %d offset %ld, size %ld ... ",
wdenk7a8e9bed2003-05-31 18:35:21 +0000228 (cmd & NANDRW_READ) ? "read" : "write",
229 curr_device, off, size);
wdenkdc7c9a12003-03-26 06:55:25 +0000230
231 ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size,
232 &total, (u_char*)addr);
233
wdenk1f4bb372003-07-27 00:21:01 +0000234 printf (" %d bytes %s: %s\n", total,
wdenk998eaae2004-04-18 19:43:36 +0000235 (cmd & NANDRW_READ) ? "read" : "written",
wdenkdc7c9a12003-03-26 06:55:25 +0000236 ret ? "ERROR" : "OK");
237
238 return ret;
wdenk7a8e9bed2003-05-31 18:35:21 +0000239 } else if (strcmp(argv[1],"erase") == 0 &&
240 (argc == 4 || strcmp("clean", argv[2]) == 0)) {
241 int clean = argc == 5;
242 ulong off = simple_strtoul(argv[2 + clean], NULL, 16);
243 ulong size = simple_strtoul(argv[3 + clean], NULL, 16);
wdenkdc7c9a12003-03-26 06:55:25 +0000244 int ret;
245
246 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
247 curr_device, off, size);
248
wdenk7a8e9bed2003-05-31 18:35:21 +0000249 ret = nand_erase (nand_dev_desc + curr_device, off, size, clean);
wdenkdc7c9a12003-03-26 06:55:25 +0000250
251 printf("%s\n", ret ? "ERROR" : "OK");
252
253 return ret;
254 } else {
255 printf ("Usage:\n%s\n", cmdtp->usage);
256 rcode = 1;
257 }
258
259 return rcode;
260 }
261}
262
wdenk0d498392003-07-01 21:06:45 +0000263U_BOOT_CMD(
264 nand, 5, 1, do_nand,
wdenkb0fce992003-06-29 21:03:46 +0000265 "nand - NAND sub-system\n",
266 "info - show available NAND devices\n"
267 "nand device [dev] - show or set current device\n"
wdenka3d991b2004-04-15 21:48:45 +0000268 "nand read[.jffs2[s]] addr off size\n"
wdenkb0fce992003-06-29 21:03:46 +0000269 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
270 " at offset `off' to/from memory address `addr'\n"
271 "nand erase [clean] [off size] - erase `size' bytes from\n"
272 " offset `off' (entire device if not specified)\n"
273 "nand bad - show bad blocks\n"
274 "nand read.oob addr off size - read out-of-band data\n"
275 "nand write.oob addr off size - read out-of-band data\n"
276);
277
wdenkdc7c9a12003-03-26 06:55:25 +0000278int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
279{
280 char *boot_device = NULL;
281 char *ep;
282 int dev;
283 ulong cnt;
284 ulong addr;
285 ulong offset = 0;
286 image_header_t *hdr;
287 int rcode = 0;
288 switch (argc) {
289 case 1:
290 addr = CFG_LOAD_ADDR;
291 boot_device = getenv ("bootdevice");
292 break;
293 case 2:
294 addr = simple_strtoul(argv[1], NULL, 16);
295 boot_device = getenv ("bootdevice");
296 break;
297 case 3:
298 addr = simple_strtoul(argv[1], NULL, 16);
299 boot_device = argv[2];
300 break;
301 case 4:
302 addr = simple_strtoul(argv[1], NULL, 16);
303 boot_device = argv[2];
304 offset = simple_strtoul(argv[3], NULL, 16);
305 break;
306 default:
307 printf ("Usage:\n%s\n", cmdtp->usage);
308 SHOW_BOOT_PROGRESS (-1);
309 return 1;
310 }
311
312 if (!boot_device) {
313 puts ("\n** No boot device **\n");
314 SHOW_BOOT_PROGRESS (-1);
315 return 1;
316 }
317
318 dev = simple_strtoul(boot_device, &ep, 16);
319
320 if ((dev >= CFG_MAX_NAND_DEVICE) ||
321 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {
322 printf ("\n** Device %d not available\n", dev);
323 SHOW_BOOT_PROGRESS (-1);
324 return 1;
325 }
326
wdenk7a8e9bed2003-05-31 18:35:21 +0000327 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
wdenkdc7c9a12003-03-26 06:55:25 +0000328 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
329 offset);
330
wdenk7a8e9bed2003-05-31 18:35:21 +0000331 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset,
wdenkdc7c9a12003-03-26 06:55:25 +0000332 SECTORSIZE, NULL, (u_char *)addr)) {
333 printf ("** Read error on %d\n", dev);
334 SHOW_BOOT_PROGRESS (-1);
335 return 1;
336 }
337
338 hdr = (image_header_t *)addr;
339
340 if (ntohl(hdr->ih_magic) == IH_MAGIC) {
341
342 print_image_hdr (hdr);
343
344 cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
345 cnt -= SECTORSIZE;
346 } else {
347 printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
348 SHOW_BOOT_PROGRESS (-1);
349 return 1;
350 }
351
wdenk7a8e9bed2003-05-31 18:35:21 +0000352 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt,
wdenkdc7c9a12003-03-26 06:55:25 +0000353 NULL, (u_char *)(addr+SECTORSIZE))) {
354 printf ("** Read error on %d\n", dev);
355 SHOW_BOOT_PROGRESS (-1);
356 return 1;
357 }
358
359 /* Loading ok, update default load address */
360
361 load_addr = addr;
362
363 /* Check if we should attempt an auto-start */
364 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
365 char *local_args[2];
366 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
367
368 local_args[0] = argv[0];
369 local_args[1] = NULL;
370
wdenk7a8e9bed2003-05-31 18:35:21 +0000371 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);
wdenkdc7c9a12003-03-26 06:55:25 +0000372
373 do_bootm (cmdtp, 0, 1, local_args);
374 rcode = 1;
375 }
376 return rcode;
377}
378
wdenk0d498392003-07-01 21:06:45 +0000379U_BOOT_CMD(
380 nboot, 4, 1, do_nandboot,
wdenkb0fce992003-06-29 21:03:46 +0000381 "nboot - boot from NAND device\n",
382 "loadAddr dev\n"
383);
384
wdenk7a8e9bed2003-05-31 18:35:21 +0000385/* returns 0 if block containing pos is OK:
386 * valid erase block and
387 * not marked bad, or no bad mark position is specified
388 * returns 1 if marked bad or otherwise invalid
389 */
390int check_block(struct nand_chip* nand, unsigned long pos)
391{
392 int retlen;
393 uint8_t oob_data;
394 int page0 = pos & (-nand->erasesize);
395 int page1 = page0 + nand->oobblock;
396 int badpos = oob_config.badblock_pos;
397
398 if (pos >= nand->totlen)
399 return 1;
400
401 if (badpos < 0)
402 return 0; /* no way to check, assume OK */
403
404 /* Note - bad block marker can be on first or second page */
405 if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data) ||
406 oob_data != 0xff ||
407 nand_read_oob(nand, page1 + badpos, 1, &retlen, &oob_data) ||
408 oob_data != 0xff)
409 return 1;
410
411 return 0;
412}
wdenk8bde7f72003-06-27 21:31:46 +0000413
wdenk7a8e9bed2003-05-31 18:35:21 +0000414/* print bad blocks in NAND flash */
415static void nand_print_bad(struct nand_chip* nand)
416{
417 unsigned long pos;
418
419 for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
420 if (check_block(nand, pos))
421 printf(" 0x%8.8lx\n", pos);
422 }
423 puts("\n");
424}
425
426/* cmd: 0: NANDRW_WRITE write, fail on bad block
427 * 1: NANDRW_READ read, fail on bad block
428 * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
429 * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
wdenka3d991b2004-04-15 21:48:45 +0000430 * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
wdenk7a8e9bed2003-05-31 18:35:21 +0000431 */
wdenkdc7c9a12003-03-26 06:55:25 +0000432static int nand_rw (struct nand_chip* nand, int cmd,
433 size_t start, size_t len,
434 size_t * retlen, u_char * buf)
435{
wdenk1f4bb372003-07-27 00:21:01 +0000436 int ret = 0, n, total = 0;
wdenkdc7c9a12003-03-26 06:55:25 +0000437 char eccbuf[6];
wdenk7a8e9bed2003-05-31 18:35:21 +0000438 /* eblk (once set) is the start of the erase block containing the
439 * data being processed.
440 */
441 unsigned long eblk = ~0; /* force mismatch on first pass */
442 unsigned long erasesize = nand->erasesize;
wdenkdc7c9a12003-03-26 06:55:25 +0000443
wdenk7a8e9bed2003-05-31 18:35:21 +0000444 while (len) {
445 if ((start & (-erasesize)) != eblk) {
446 /* have crossed into new erase block, deal with
447 * it if it is sure marked bad.
448 */
449 eblk = start & (-erasesize); /* start of block */
450 if (check_block(nand, eblk)) {
451 if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
452 while (len > 0 &&
453 start - eblk < erasesize) {
454 *(buf++) = 0xff;
455 ++start;
456 ++total;
457 --len;
458 }
459 continue;
460 }
wdenka3d991b2004-04-15 21:48:45 +0000461 else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
462 start += erasesize;
463 continue;
464 }
wdenk7a8e9bed2003-05-31 18:35:21 +0000465 else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
466 /* skip bad block */
467 start += erasesize;
468 continue;
469 }
470 else {
471 ret = 1;
472 break;
473 }
474 }
475 }
wdenkdc7c9a12003-03-26 06:55:25 +0000476 /* The ECC will not be calculated correctly if
477 less than 512 is written or read */
wdenk1f4bb372003-07-27 00:21:01 +0000478 /* Is request at least 512 bytes AND it starts on a proper boundry */
479 if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
480 printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
481
wdenk7a8e9bed2003-05-31 18:35:21 +0000482 if (cmd & NANDRW_READ)
483 ret = nand_read_ecc(nand, start,
484 min(len, eblk + erasesize - start),
wdenk1f4bb372003-07-27 00:21:01 +0000485 &n, (u_char*)buf, eccbuf);
wdenkdc7c9a12003-03-26 06:55:25 +0000486 else
wdenk7a8e9bed2003-05-31 18:35:21 +0000487 ret = nand_write_ecc(nand, start,
488 min(len, eblk + erasesize - start),
wdenk1f4bb372003-07-27 00:21:01 +0000489 &n, (u_char*)buf, eccbuf);
wdenkdc7c9a12003-03-26 06:55:25 +0000490
491 if (ret)
492 break;
493
494 start += n;
495 buf += n;
496 total += n;
497 len -= n;
498 }
499 if (retlen)
500 *retlen = total;
501
502 return ret;
503}
504
505static void nand_print(struct nand_chip *nand)
wdenk0db5bca2003-03-31 17:27:09 +0000506{
wdenk7a8e9bed2003-05-31 18:35:21 +0000507 if (nand->numchips > 1) {
508 printf("%s at 0x%lx,\n"
509 "\t %d chips %s, size %d MB, \n"
510 "\t total size %ld MB, sector size %ld kB\n",
511 nand->name, nand->IO_ADDR, nand->numchips,
512 nand->chips_name, 1 << (nand->chipshift - 20),
513 nand->totlen >> 20, nand->erasesize >> 10);
514 }
515 else {
wdenk8bde7f72003-06-27 21:31:46 +0000516 printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
wdenk7a8e9bed2003-05-31 18:35:21 +0000517 print_size(nand->totlen, ", ");
518 print_size(nand->erasesize, " sector)\n");
wdenkdc7c9a12003-03-26 06:55:25 +0000519 }
520}
521
522/* ------------------------------------------------------------------------- */
523
wdenk1f4bb372003-07-27 00:21:01 +0000524static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
wdenkdc7c9a12003-03-26 06:55:25 +0000525{
526 /* This is inline, to optimise the common case, where it's ready instantly */
527 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +0000528
wdenk1f4bb372003-07-27 00:21:01 +0000529#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */
530 if(ale_wait)
531 NAND_WAIT_READY(nand); /* do the worst case 25us wait */
532 else
533 udelay(10);
534#else /* has functional r/b signal */
wdenk12f34242003-09-02 22:48:03 +0000535 NAND_WAIT_READY(nand);
wdenk1f4bb372003-07-27 00:21:01 +0000536#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000537 return ret;
538}
539
540/* NanD_Command: Send a flash command to the flash chip */
541
542static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
543{
544 unsigned long nandptr = nand->IO_ADDR;
545
546 /* Assert the CLE (Command Latch Enable) line to the flash chip */
547 NAND_CTL_SETCLE(nandptr);
548
549 /* Send the command */
550 WRITE_NAND_COMMAND(command, nandptr);
551
552 /* Lower the CLE line */
553 NAND_CTL_CLRCLE(nandptr);
554
wdenk1f4bb372003-07-27 00:21:01 +0000555#ifdef NAND_NO_RB
556 if(command == NAND_CMD_RESET){
557 u_char ret_val;
558 NanD_Command(nand, NAND_CMD_STATUS);
559 do{
560 ret_val = READ_NAND(nandptr);/* wait till ready */
561 } while((ret_val & 0x40) != 0x40);
562 }
563#endif
564 return NanD_WaitReady(nand, 0);
wdenkdc7c9a12003-03-26 06:55:25 +0000565}
566
567/* NanD_Address: Set the current address for the flash chip */
568
569static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
wdenk0db5bca2003-03-31 17:27:09 +0000570{
571 unsigned long nandptr;
572 int i;
wdenkdc7c9a12003-03-26 06:55:25 +0000573
wdenk0db5bca2003-03-31 17:27:09 +0000574 nandptr = nand->IO_ADDR;
wdenkdc7c9a12003-03-26 06:55:25 +0000575
576 /* Assert the ALE (Address Latch Enable) line to the flash chip */
wdenk0db5bca2003-03-31 17:27:09 +0000577 NAND_CTL_SETALE(nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000578
wdenk0db5bca2003-03-31 17:27:09 +0000579 /* Send the address */
580 /* Devices with 256-byte page are addressed as:
581 * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
582 * there is no device on the market with page256
583 * and more than 24 bits.
584 * Devices with 512-byte page are addressed as:
585 * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
586 * 25-31 is sent only if the chip support it.
587 * bit 8 changes the read command to be sent
588 * (NAND_CMD_READ0 or NAND_CMD_READ1).
wdenkdc7c9a12003-03-26 06:55:25 +0000589 */
590
wdenk0db5bca2003-03-31 17:27:09 +0000591 if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
592 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000593
wdenk0db5bca2003-03-31 17:27:09 +0000594 ofs = ofs >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000595
wdenk0db5bca2003-03-31 17:27:09 +0000596 if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
597 for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8)
598 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000599
wdenk0db5bca2003-03-31 17:27:09 +0000600 /* Lower the ALE line */
601 NAND_CTL_CLRALE(nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +0000602
wdenk0db5bca2003-03-31 17:27:09 +0000603 /* Wait for the chip to respond */
wdenk1f4bb372003-07-27 00:21:01 +0000604 return NanD_WaitReady(nand, 1);
wdenk0db5bca2003-03-31 17:27:09 +0000605}
wdenkdc7c9a12003-03-26 06:55:25 +0000606
607/* NanD_SelectChip: Select a given flash chip within the current floor */
608
609static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
610{
611 /* Wait for it to be ready */
wdenk1f4bb372003-07-27 00:21:01 +0000612 return NanD_WaitReady(nand, 0);
wdenkdc7c9a12003-03-26 06:55:25 +0000613}
614
615/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
616
617static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
618{
619 int mfr, id, i;
620
wdenk0db5bca2003-03-31 17:27:09 +0000621 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +0000622 /* Reset the chip */
623 if (NanD_Command(nand, NAND_CMD_RESET)) {
624#ifdef NAND_DEBUG
625 printf("NanD_Command (reset) for %d,%d returned true\n",
626 floor, chip);
627#endif
wdenk0db5bca2003-03-31 17:27:09 +0000628 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000629 return 0;
630 }
631
632 /* Read the NAND chip ID: 1. Send ReadID command */
633 if (NanD_Command(nand, NAND_CMD_READID)) {
634#ifdef NAND_DEBUG
635 printf("NanD_Command (ReadID) for %d,%d returned true\n",
636 floor, chip);
637#endif
wdenk0db5bca2003-03-31 17:27:09 +0000638 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000639 return 0;
640 }
641
642 /* Read the NAND chip ID: 2. Send address byte zero */
643 NanD_Address(nand, ADDR_COLUMN, 0);
644
645 /* Read the manufacturer and device id codes from the device */
646
647 mfr = READ_NAND(nand->IO_ADDR);
648
649 id = READ_NAND(nand->IO_ADDR);
650
wdenk8bde7f72003-06-27 21:31:46 +0000651 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000652 /* No response - return failure */
wdenk0db5bca2003-03-31 17:27:09 +0000653 if (mfr == 0xff || mfr == 0) {
wdenk4d816772003-09-03 14:03:26 +0000654#ifdef NAND_DEBUG
wdenk0db5bca2003-03-31 17:27:09 +0000655 printf("NanD_Command (ReadID) got %d %d\n", mfr, id);
wdenk4d816772003-09-03 14:03:26 +0000656#endif
wdenk0db5bca2003-03-31 17:27:09 +0000657 return 0;
658 }
wdenkdc7c9a12003-03-26 06:55:25 +0000659
660 /* Check it's the same as the first chip we identified.
661 * M-Systems say that any given nand_chip device should only
662 * contain _one_ type of flash part, although that's not a
663 * hardware restriction. */
664 if (nand->mfr) {
665 if (nand->mfr == mfr && nand->id == id)
666 return 1; /* This is another the same the first */
667 else
668 printf("Flash chip at floor %d, chip %d is different:\n",
669 floor, chip);
670 }
671
672 /* Print and store the manufacturer and ID codes. */
673 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
674 if (mfr == nand_flash_ids[i].manufacture_id &&
675 id == nand_flash_ids[i].model_id) {
676#ifdef NAND_DEBUG
677 printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
678 "Chip ID: 0x%2.2X (%s)\n", mfr, id,
679 nand_flash_ids[i].name);
680#endif
681 if (!nand->mfr) {
682 nand->mfr = mfr;
683 nand->id = id;
684 nand->chipshift =
685 nand_flash_ids[i].chipshift;
686 nand->page256 = nand_flash_ids[i].page256;
wdenk7a8e9bed2003-05-31 18:35:21 +0000687 nand->eccsize = 256;
wdenkdc7c9a12003-03-26 06:55:25 +0000688 if (nand->page256) {
689 nand->oobblock = 256;
690 nand->oobsize = 8;
691 nand->page_shift = 8;
692 } else {
693 nand->oobblock = 512;
694 nand->oobsize = 16;
695 nand->page_shift = 9;
696 }
697 nand->pageadrlen =
698 nand_flash_ids[i].pageadrlen;
699 nand->erasesize =
700 nand_flash_ids[i].erasesize;
701 nand->chips_name =
702 nand_flash_ids[i].name;
703 return 1;
704 }
705 return 0;
706 }
707 }
708
709
710#ifdef NAND_DEBUG
711 /* We haven't fully identified the chip. Print as much as we know. */
712 printf("Unknown flash chip found: %2.2X %2.2X\n",
713 id, mfr);
714#endif
715
716 return 0;
717}
718
719/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
720
721static void NanD_ScanChips(struct nand_chip *nand)
722{
723 int floor, chip;
724 int numchips[NAND_MAX_FLOORS];
725 int maxchips = NAND_MAX_CHIPS;
726 int ret = 1;
727
728 nand->numchips = 0;
729 nand->mfr = 0;
730 nand->id = 0;
731
732
733 /* For each floor, find the number of valid chips it contains */
734 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
735 ret = 1;
736 numchips[floor] = 0;
737 for (chip = 0; chip < maxchips && ret != 0; chip++) {
738
739 ret = NanD_IdentChip(nand, floor, chip);
740 if (ret) {
741 numchips[floor]++;
742 nand->numchips++;
743 }
744 }
745 }
746
747 /* If there are none at all that we recognise, bail */
748 if (!nand->numchips) {
wdenka43278a2003-09-11 19:48:06 +0000749#ifdef NAND_DEBUG
wdenk4d816772003-09-03 14:03:26 +0000750 puts ("No NAND flash chips recognised.\n");
wdenka43278a2003-09-11 19:48:06 +0000751#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000752 return;
753 }
754
755 /* Allocate an array to hold the information for each chip */
756 nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
757 if (!nand->chips) {
758 puts ("No memory for allocating chip info structures\n");
759 return;
760 }
761
762 ret = 0;
763
764 /* Fill out the chip array with {floor, chipno} for each
765 * detected chip in the device. */
766 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
767 for (chip = 0; chip < numchips[floor]; chip++) {
768 nand->chips[ret].floor = floor;
769 nand->chips[ret].chip = chip;
770 nand->chips[ret].curadr = 0;
771 nand->chips[ret].curmode = 0x50;
772 ret++;
773 }
774 }
775
776 /* Calculate and print the total size of the device */
777 nand->totlen = nand->numchips * (1 << nand->chipshift);
778
779#ifdef NAND_DEBUG
780 printf("%d flash chips found. Total nand_chip size: %ld MB\n",
781 nand->numchips, nand->totlen >> 20);
782#endif
783}
wdenk0db5bca2003-03-31 17:27:09 +0000784
wdenkdc7c9a12003-03-26 06:55:25 +0000785/* we need to be fast here, 1 us per read translates to 1 second per meg */
wdenk7a8e9bed2003-05-31 18:35:21 +0000786static void NanD_ReadBuf(struct nand_chip *nand, u_char *data_buf, int cntr)
wdenk0db5bca2003-03-31 17:27:09 +0000787{
wdenk7a8e9bed2003-05-31 18:35:21 +0000788 unsigned long nandptr = nand->IO_ADDR;
wdenk0db5bca2003-03-31 17:27:09 +0000789
wdenk7a8e9bed2003-05-31 18:35:21 +0000790 while (cntr >= 16) {
wdenk0db5bca2003-03-31 17:27:09 +0000791 *data_buf++ = READ_NAND(nandptr);
792 *data_buf++ = READ_NAND(nandptr);
793 *data_buf++ = READ_NAND(nandptr);
794 *data_buf++ = READ_NAND(nandptr);
795 *data_buf++ = READ_NAND(nandptr);
796 *data_buf++ = READ_NAND(nandptr);
797 *data_buf++ = READ_NAND(nandptr);
798 *data_buf++ = READ_NAND(nandptr);
799 *data_buf++ = READ_NAND(nandptr);
800 *data_buf++ = READ_NAND(nandptr);
801 *data_buf++ = READ_NAND(nandptr);
802 *data_buf++ = READ_NAND(nandptr);
803 *data_buf++ = READ_NAND(nandptr);
804 *data_buf++ = READ_NAND(nandptr);
805 *data_buf++ = READ_NAND(nandptr);
806 *data_buf++ = READ_NAND(nandptr);
807 cntr -= 16;
808 }
809
810 while (cntr > 0) {
811 *data_buf++ = READ_NAND(nandptr);
812 cntr--;
813 }
814}
wdenkdc7c9a12003-03-26 06:55:25 +0000815
wdenkdc7c9a12003-03-26 06:55:25 +0000816/*
817 * NAND read with ECC
818 */
819static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
820 size_t * retlen, u_char *buf, u_char *ecc_code)
821{
822 int col, page;
823 int ecc_status = 0;
824#ifdef CONFIG_MTD_NAND_ECC
825 int j;
826 int ecc_failed = 0;
827 u_char *data_poi;
828 u_char ecc_calc[6];
829#endif
wdenkdc7c9a12003-03-26 06:55:25 +0000830
831 /* Do not allow reads past end of device */
832 if ((start + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +0000833 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 +0000834 *retlen = 0;
835 return -1;
836 }
837
838 /* First we calculate the starting page */
wdenk0db5bca2003-03-31 17:27:09 +0000839 /*page = shr(start, nand->page_shift);*/
840 page = start >> nand->page_shift;
wdenkdc7c9a12003-03-26 06:55:25 +0000841
842 /* Get raw starting column */
843 col = start & (nand->oobblock - 1);
844
845 /* Initialize return value */
846 *retlen = 0;
847
848 /* Select the NAND device */
849 NAND_ENABLE_CE(nand); /* set pin low */
850
851 /* Loop until all data read */
852 while (*retlen < len) {
853
854
855#ifdef CONFIG_MTD_NAND_ECC
856
857 /* Do we have this page in cache ? */
858 if (nand->cache_page == page)
859 goto readdata;
860 /* Send the read command */
861 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000862 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000863 /* Read in a page + oob data */
wdenk7a8e9bed2003-05-31 18:35:21 +0000864 NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
wdenkdc7c9a12003-03-26 06:55:25 +0000865
866 /* copy data into cache, for read out of cache and if ecc fails */
867 if (nand->data_cache)
868 memcpy (nand->data_cache, nand->data_buf, nand->oobblock + nand->oobsize);
869
870 /* Pick the ECC bytes out of the oob data */
871 for (j = 0; j < 6; j++)
872 ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
873
874 /* Calculate the ECC and verify it */
875 /* If block was not written with ECC, skip ECC */
876 if (oob_config.eccvalid_pos != -1 &&
877 (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
878
879 nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
880 switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
881 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000882 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000883 ecc_failed++;
884 break;
885 case 1:
886 case 2: /* transfer ECC corrected data to cache */
wdenk7a8e9bed2003-05-31 18:35:21 +0000887 if (nand->data_cache)
888 memcpy (nand->data_cache, nand->data_buf, 256);
wdenkdc7c9a12003-03-26 06:55:25 +0000889 break;
890 }
891 }
892
893 if (oob_config.eccvalid_pos != -1 &&
894 nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
895
896 nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
897 switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
898 case -1:
wdenk0db5bca2003-03-31 17:27:09 +0000899 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +0000900 ecc_failed++;
901 break;
902 case 1:
903 case 2: /* transfer ECC corrected data to cache */
904 if (nand->data_cache)
905 memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
906 break;
907 }
908 }
909readdata:
910 /* Read the data from ECC data buffer into return buffer */
911 data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
912 data_poi += col;
913 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000914 memcpy (buf + *retlen, data_poi, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000915 *retlen = len;
916 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000917 memcpy (buf + *retlen, data_poi, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000918 *retlen += nand->oobblock - col;
919 }
920 /* Set cache page address, invalidate, if ecc_failed */
921 nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
922
923 ecc_status += ecc_failed;
924 ecc_failed = 0;
925
926#else
927 /* Send the read command */
928 NanD_Command(nand, NAND_CMD_READ0);
wdenk8bde7f72003-06-27 21:31:46 +0000929 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000930 /* Read the data directly into the return buffer */
931 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenk7a8e9bed2003-05-31 18:35:21 +0000932 NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
wdenkdc7c9a12003-03-26 06:55:25 +0000933 *retlen = len;
934 /* We're done */
935 continue;
936 } else {
wdenk7a8e9bed2003-05-31 18:35:21 +0000937 NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
wdenkdc7c9a12003-03-26 06:55:25 +0000938 *retlen += nand->oobblock - col;
939 }
940#endif
941 /* For subsequent reads align to page boundary. */
942 col = 0;
943 /* Increment page address */
944 page++;
945 }
946
947 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +0000948 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +0000949
950 /*
951 * Return success, if no ECC failures, else -EIO
952 * fs driver will take care of that, because
953 * retlen == desired len and result == -EIO
954 */
955 return ecc_status ? -1 : 0;
956}
957
wdenkdc7c9a12003-03-26 06:55:25 +0000958/*
959 * Nand_page_program function is used for write and writev !
960 */
961static int nand_write_page (struct nand_chip *nand,
962 int page, int col, int last, u_char * ecc_code)
963{
964
965 int i;
wdenkdc7c9a12003-03-26 06:55:25 +0000966 unsigned long nandptr = nand->IO_ADDR;
wdenk1f4bb372003-07-27 00:21:01 +0000967#ifdef CONFIG_MTD_NAND_ECC
wdenkdc7c9a12003-03-26 06:55:25 +0000968#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
969 int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
970#endif
971#endif
972 /* pad oob area */
973 for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
974 nand->data_buf[i] = 0xff;
975
976#ifdef CONFIG_MTD_NAND_ECC
977 /* Zero out the ECC array */
978 for (i = 0; i < 6; i++)
979 ecc_code[i] = 0x00;
980
981 /* Read back previous written data, if col > 0 */
982 if (col) {
983 NanD_Command(nand, NAND_CMD_READ0);
wdenk0db5bca2003-03-31 17:27:09 +0000984 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +0000985 for (i = 0; i < col; i++)
986 nand->data_buf[i] = READ_NAND (nandptr);
987 }
988
989 /* Calculate and write the ECC if we have enough data */
990 if ((col < nand->eccsize) && (last >= nand->eccsize)) {
991 nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
992 for (i = 0; i < 3; i++)
993 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
994 if (oob_config.eccvalid_pos != -1)
995 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] = 0xf0;
996 }
997
998 /* Calculate and write the second ECC if we have enough data */
999 if ((nand->oobblock == 512) && (last == nand->oobblock)) {
1000 nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
1001 for (i = 3; i < 6; i++)
1002 nand->data_buf[(nand->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
1003 if (oob_config.eccvalid_pos != -1)
1004 nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] &= 0x0f;
1005 }
1006#endif
1007 /* Prepad for partial page programming !!! */
1008 for (i = 0; i < col; i++)
1009 nand->data_buf[i] = 0xff;
1010
1011 /* Postpad for partial page programming !!! oob is already padded */
1012 for (i = last; i < nand->oobblock; i++)
1013 nand->data_buf[i] = 0xff;
1014
1015 /* Send command to begin auto page programming */
wdenk7a8e9bed2003-05-31 18:35:21 +00001016 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001017 NanD_Command(nand, NAND_CMD_SEQIN);
1018 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1019
1020 /* Write out complete page of data */
1021 for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
wdenk0db5bca2003-03-31 17:27:09 +00001022 WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
wdenkdc7c9a12003-03-26 06:55:25 +00001023
1024 /* Send command to actually program the data */
wdenk0db5bca2003-03-31 17:27:09 +00001025 NanD_Command(nand, NAND_CMD_PAGEPROG);
1026 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001027#ifdef NAND_NO_RB
1028 { u_char ret_val;
wdenkdc7c9a12003-03-26 06:55:25 +00001029
wdenk1f4bb372003-07-27 00:21:01 +00001030 do{
1031 ret_val = READ_NAND(nandptr); /* wait till ready */
1032 } while((ret_val & 0x40) != 0x40);
1033 }
1034#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001035 /* See if device thinks it succeeded */
1036 if (READ_NAND(nand->IO_ADDR) & 0x01) {
wdenk0db5bca2003-03-31 17:27:09 +00001037 printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001038 return -1;
1039 }
wdenk1f4bb372003-07-27 00:21:01 +00001040
wdenkdc7c9a12003-03-26 06:55:25 +00001041#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1042 /*
1043 * The NAND device assumes that it is always writing to
1044 * a cleanly erased page. Hence, it performs its internal
1045 * write verification only on bits that transitioned from
1046 * 1 to 0. The device does NOT verify the whole page on a
1047 * byte by byte basis. It is possible that the page was
1048 * not completely erased or the page is becoming unusable
1049 * due to wear. The read with ECC would catch the error
1050 * later when the ECC page check fails, but we would rather
1051 * catch it early in the page write stage. Better to write
1052 * no data than invalid data.
1053 */
1054
1055 /* Send command to read back the page */
1056 if (col < nand->eccsize)
wdenk0db5bca2003-03-31 17:27:09 +00001057 NanD_Command(nand, NAND_CMD_READ0);
wdenkdc7c9a12003-03-26 06:55:25 +00001058 else
wdenk0db5bca2003-03-31 17:27:09 +00001059 NanD_Command(nand, NAND_CMD_READ1);
1060 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
wdenkdc7c9a12003-03-26 06:55:25 +00001061
1062 /* Loop through and verify the data */
1063 for (i = col; i < last; i++) {
1064 if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
wdenk0db5bca2003-03-31 17:27:09 +00001065 printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
wdenkdc7c9a12003-03-26 06:55:25 +00001066 return -1;
1067 }
1068 }
1069
1070#ifdef CONFIG_MTD_NAND_ECC
1071 /*
1072 * We also want to check that the ECC bytes wrote
1073 * correctly for the same reasons stated above.
1074 */
1075 NanD_Command(nand, NAND_CMD_READOOB);
1076 NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
1077 for (i = 0; i < nand->oobsize; i++)
1078 nand->data_buf[i] = readb (nand->IO_ADDR);
1079 for (i = 0; i < ecc_bytes; i++) {
1080 if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
wdenk0db5bca2003-03-31 17:27:09 +00001081 printf ("%s: Failed ECC write "
1082 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
wdenkdc7c9a12003-03-26 06:55:25 +00001083 return -1;
1084 }
1085 }
1086#endif
1087#endif
1088 return 0;
1089}
wdenk0db5bca2003-03-31 17:27:09 +00001090
wdenkdc7c9a12003-03-26 06:55:25 +00001091static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
1092 size_t * retlen, const u_char * buf, u_char * ecc_code)
1093{
1094 int i, page, col, cnt, ret = 0;
1095
1096 /* Do not allow write past end of device */
1097 if ((to + len) > nand->totlen) {
wdenk0db5bca2003-03-31 17:27:09 +00001098 printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001099 return -1;
1100 }
1101
1102 /* Shift to get page */
1103 page = ((int) to) >> nand->page_shift;
1104
1105 /* Get the starting column */
1106 col = to & (nand->oobblock - 1);
1107
1108 /* Initialize return length value */
1109 *retlen = 0;
1110
1111 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001112#ifdef CONFIG_OMAP1510
1113 archflashwp(0,0);
1114#endif
1115 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001116
1117 /* Check the WP bit */
wdenk0db5bca2003-03-31 17:27:09 +00001118 NanD_Command(nand, NAND_CMD_STATUS);
wdenkdc7c9a12003-03-26 06:55:25 +00001119 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
wdenk0db5bca2003-03-31 17:27:09 +00001120 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
wdenkdc7c9a12003-03-26 06:55:25 +00001121 ret = -1;
1122 goto out;
1123 }
1124
1125 /* Loop until all data is written */
1126 while (*retlen < len) {
1127 /* Invalidate cache, if we write to this page */
1128 if (nand->cache_page == page)
1129 nand->cache_page = -1;
1130
1131 /* Write data into buffer */
1132 if ((col + len) >= nand->oobblock)
1133 for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++)
1134 nand->data_buf[i] = buf[(*retlen + cnt)];
1135 else
1136 for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++)
1137 nand->data_buf[i] = buf[(*retlen + cnt)];
1138 /* We use the same function for write and writev !) */
1139 ret = nand_write_page (nand, page, col, i, ecc_code);
1140 if (ret)
1141 goto out;
1142
1143 /* Next data start at page boundary */
1144 col = 0;
1145
1146 /* Update written bytes count */
1147 *retlen += cnt;
1148
1149 /* Increment page address */
1150 page++;
1151 }
1152
1153 /* Return happy */
1154 *retlen = len;
1155
1156out:
1157 /* De-select the NAND device */
wdenk0db5bca2003-03-31 17:27:09 +00001158 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001159#ifdef CONFIG_OMAP1510
1160 archflashwp(0,1);
1161#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001162 return ret;
1163}
1164
wdenk7a8e9bed2003-05-31 18:35:21 +00001165/* read from the 16 bytes of oob data that correspond to a 512 byte
1166 * page or 2 256-byte pages.
wdenkdc7c9a12003-03-26 06:55:25 +00001167 */
wdenkdc7c9a12003-03-26 06:55:25 +00001168static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
wdenk7a8e9bed2003-05-31 18:35:21 +00001169 size_t * retlen, u_char * buf)
wdenkdc7c9a12003-03-26 06:55:25 +00001170{
wdenk7a8e9bed2003-05-31 18:35:21 +00001171 int len256 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001172 struct Nand *mychip;
wdenk0db5bca2003-03-31 17:27:09 +00001173 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001174
wdenk7a8e9bed2003-05-31 18:35:21 +00001175 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001176
1177 /* update address for 2M x 8bit devices. OOB starts on the second */
1178 /* page to maintain compatibility with nand_read_ecc. */
1179 if (nand->page256) {
1180 if (!(ofs & 0x8))
1181 ofs += 0x100;
1182 else
1183 ofs -= 0x8;
1184 }
1185
wdenk7a8e9bed2003-05-31 18:35:21 +00001186 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001187 NanD_Command(nand, NAND_CMD_READOOB);
1188 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1189
1190 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1191 /* Note: datasheet says it should automaticaly wrap to the */
1192 /* next OOB block, but it didn't work here. mf. */
1193 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1194 len256 = (ofs | 0x7) + 1 - ofs;
1195 NanD_ReadBuf(nand, buf, len256);
1196
1197 NanD_Command(nand, NAND_CMD_READOOB);
1198 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1199 }
1200
1201 NanD_ReadBuf(nand, &buf[len256], len - len256);
1202
1203 *retlen = len;
1204 /* Reading the full OOB data drops us off of the end of the page,
wdenk8bde7f72003-06-27 21:31:46 +00001205 * causing the flash device to go into busy mode, so we need
1206 * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
wdenkdc7c9a12003-03-26 06:55:25 +00001207
wdenk1f4bb372003-07-27 00:21:01 +00001208 ret = NanD_WaitReady(nand, 1);
wdenk8bde7f72003-06-27 21:31:46 +00001209 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001210
1211 return ret;
1212
1213}
wdenk7a8e9bed2003-05-31 18:35:21 +00001214
1215/* write to the 16 bytes of oob data that correspond to a 512 byte
1216 * page or 2 256-byte pages.
1217 */
wdenkdc7c9a12003-03-26 06:55:25 +00001218static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
1219 size_t * retlen, const u_char * buf)
1220{
1221 int len256 = 0;
wdenk7a8e9bed2003-05-31 18:35:21 +00001222 int i;
wdenkdc7c9a12003-03-26 06:55:25 +00001223 unsigned long nandptr = nand->IO_ADDR;
1224
1225#ifdef PSYCHO_DEBUG
1226 printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1227 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1228 buf[8], buf[9], buf[14],buf[15]);
1229#endif
1230
wdenk7a8e9bed2003-05-31 18:35:21 +00001231 NAND_ENABLE_CE(nand); /* set pin low to enable chip */
1232
wdenkdc7c9a12003-03-26 06:55:25 +00001233 /* Reset the chip */
1234 NanD_Command(nand, NAND_CMD_RESET);
1235
1236 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1237 NanD_Command(nand, NAND_CMD_READOOB);
1238 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1239
1240 /* update address for 2M x 8bit devices. OOB starts on the second */
1241 /* page to maintain compatibility with nand_read_ecc. */
1242 if (nand->page256) {
1243 if (!(ofs & 0x8))
1244 ofs += 0x100;
1245 else
1246 ofs -= 0x8;
1247 }
1248
1249 /* issue the Serial Data In command to initial the Page Program process */
1250 NanD_Command(nand, NAND_CMD_SEQIN);
1251 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1252
1253 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1254 /* Note: datasheet says it should automaticaly wrap to the */
1255 /* next OOB block, but it didn't work here. mf. */
1256 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1257 len256 = (ofs | 0x7) + 1 - ofs;
wdenk7a8e9bed2003-05-31 18:35:21 +00001258 for (i = 0; i < len256; i++)
1259 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001260
1261 NanD_Command(nand, NAND_CMD_PAGEPROG);
1262 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001263#ifdef NAND_NO_RB
1264 { u_char ret_val;
1265 do{
1266 ret_val = READ_NAND(nandptr); /* wait till ready */
1267 }while((ret_val & 0x40) != 0x40);
1268 }
1269#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001270 if (READ_NAND(nandptr) & 1) {
1271 puts ("Error programming oob data\n");
1272 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001273 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001274 *retlen = 0;
1275 return -1;
1276 }
1277 NanD_Command(nand, NAND_CMD_SEQIN);
1278 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1279 }
1280
wdenk7a8e9bed2003-05-31 18:35:21 +00001281 for (i = len256; i < len; i++)
1282 WRITE_NAND(buf[i], nandptr);
wdenkdc7c9a12003-03-26 06:55:25 +00001283
1284 NanD_Command(nand, NAND_CMD_PAGEPROG);
1285 NanD_Command(nand, NAND_CMD_STATUS);
wdenk1f4bb372003-07-27 00:21:01 +00001286#ifdef NAND_NO_RB
1287 { u_char ret_val;
1288 do{
1289 ret_val = READ_NAND(nandptr); /* wait till ready */
1290 } while((ret_val & 0x40) != 0x40);
1291 }
1292#endif
wdenkdc7c9a12003-03-26 06:55:25 +00001293 if (READ_NAND(nandptr) & 1) {
1294 puts ("Error programming oob data\n");
1295 /* There was an error */
wdenk7a8e9bed2003-05-31 18:35:21 +00001296 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001297 *retlen = 0;
1298 return -1;
1299 }
1300
wdenk7a8e9bed2003-05-31 18:35:21 +00001301 NAND_DISABLE_CE(nand); /* set pin high */
wdenkdc7c9a12003-03-26 06:55:25 +00001302 *retlen = len;
1303 return 0;
1304
1305}
wdenkdc7c9a12003-03-26 06:55:25 +00001306
wdenk7a8e9bed2003-05-31 18:35:21 +00001307static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
wdenkdc7c9a12003-03-26 06:55:25 +00001308{
wdenk7a8e9bed2003-05-31 18:35:21 +00001309 /* This is defined as a structure so it will work on any system
1310 * using native endian jffs2 (the default).
1311 */
1312 static struct jffs2_unknown_node clean_marker = {
1313 JFFS2_MAGIC_BITMASK,
1314 JFFS2_NODETYPE_CLEANMARKER,
1315 8 /* 8 bytes in this node */
1316 };
wdenkdc7c9a12003-03-26 06:55:25 +00001317 unsigned long nandptr;
1318 struct Nand *mychip;
wdenk85ec0bc2003-03-31 16:34:49 +00001319 int ret = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001320
1321 if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
1322 printf ("Offset and size must be sector aligned, erasesize = %d\n",
wdenk8bde7f72003-06-27 21:31:46 +00001323 (int) nand->erasesize);
wdenkdc7c9a12003-03-26 06:55:25 +00001324 return -1;
1325 }
1326
1327 nandptr = nand->IO_ADDR;
1328
wdenk85ec0bc2003-03-31 16:34:49 +00001329 /* Select the NAND device */
wdenk1f4bb372003-07-27 00:21:01 +00001330#ifdef CONFIG_OMAP1510
1331 archflashwp(0,0);
1332#endif
1333 NAND_ENABLE_CE(nand); /* set pin low */
wdenk85ec0bc2003-03-31 16:34:49 +00001334
1335 /* Check the WP bit */
1336 NanD_Command(nand, NAND_CMD_STATUS);
1337 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1338 printf ("nand_write_ecc: Device is write protected!!!\n");
1339 ret = -1;
1340 goto out;
1341 }
1342
wdenk0db5bca2003-03-31 17:27:09 +00001343 /* Check the WP bit */
1344 NanD_Command(nand, NAND_CMD_STATUS);
1345 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1346 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
1347 ret = -1;
1348 goto out;
1349 }
1350
wdenkdc7c9a12003-03-26 06:55:25 +00001351 /* FIXME: Do nand in the background. Use timers or schedule_task() */
1352 while(len) {
wdenk0db5bca2003-03-31 17:27:09 +00001353 /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
1354 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkdc7c9a12003-03-26 06:55:25 +00001355
wdenk7a8e9bed2003-05-31 18:35:21 +00001356 /* always check for bad block first, genuine bad blocks
1357 * should _never_ be erased.
1358 */
1359 if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
1360 /* Select the NAND device */
1361 NAND_ENABLE_CE(nand); /* set pin low */
wdenkdc7c9a12003-03-26 06:55:25 +00001362
wdenk7a8e9bed2003-05-31 18:35:21 +00001363 NanD_Command(nand, NAND_CMD_ERASE1);
1364 NanD_Address(nand, ADDR_PAGE, ofs);
1365 NanD_Command(nand, NAND_CMD_ERASE2);
wdenkdc7c9a12003-03-26 06:55:25 +00001366
wdenk7a8e9bed2003-05-31 18:35:21 +00001367 NanD_Command(nand, NAND_CMD_STATUS);
1368
wdenk1f4bb372003-07-27 00:21:01 +00001369#ifdef NAND_NO_RB
1370 { u_char ret_val;
1371 do{
1372 ret_val = READ_NAND(nandptr); /* wait till ready */
1373 } while((ret_val & 0x40) != 0x40);
1374 }
1375#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001376 if (READ_NAND(nandptr) & 1) {
1377 printf ("%s: Error erasing at 0x%lx\n",
1378 __FUNCTION__, (long)ofs);
1379 /* There was an error */
1380 ret = -1;
1381 goto out;
1382 }
1383 if (clean) {
1384 int n; /* return value not used */
1385 int p, l;
1386
1387 /* clean marker position and size depend
1388 * on the page size, since 256 byte pages
1389 * only have 8 bytes of oob data
1390 */
1391 if (nand->page256) {
1392 p = NAND_JFFS2_OOB8_FSDAPOS;
1393 l = NAND_JFFS2_OOB8_FSDALEN;
1394 }
1395 else {
1396 p = NAND_JFFS2_OOB16_FSDAPOS;
1397 l = NAND_JFFS2_OOB16_FSDALEN;
1398 }
1399
1400 ret = nand_write_oob(nand, ofs + p, l, &n,
1401 (u_char *)&clean_marker);
1402 /* quit here if write failed */
1403 if (ret)
1404 goto out;
1405 }
wdenkdc7c9a12003-03-26 06:55:25 +00001406 }
1407 ofs += nand->erasesize;
1408 len -= nand->erasesize;
1409 }
1410
wdenk85ec0bc2003-03-31 16:34:49 +00001411out:
1412 /* De-select the NAND device */
1413 NAND_DISABLE_CE(nand); /* set pin high */
wdenk1f4bb372003-07-27 00:21:01 +00001414#ifdef CONFIG_OMAP1510
1415 archflashwp(0,1);
1416#endif
wdenk85ec0bc2003-03-31 16:34:49 +00001417 return ret;
wdenkdc7c9a12003-03-26 06:55:25 +00001418}
1419
1420static inline int nandcheck(unsigned long potential, unsigned long physadr)
1421{
wdenkdc7c9a12003-03-26 06:55:25 +00001422 return 0;
1423}
1424
wdenka43278a2003-09-11 19:48:06 +00001425unsigned long nand_probe(unsigned long physadr)
wdenkdc7c9a12003-03-26 06:55:25 +00001426{
1427 struct nand_chip *nand = NULL;
1428 int i = 0, ChipID = 1;
1429
1430#ifdef CONFIG_MTD_NAND_ECC_JFFS2
1431 oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
1432 oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
1433 oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
1434 oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
1435 oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
1436 oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001437 oob_config.eccvalid_pos = 4;
1438#else
1439 oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
1440 oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
1441 oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
1442 oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
1443 oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
1444 oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
wdenkdc7c9a12003-03-26 06:55:25 +00001445 oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
1446#endif
wdenk7a8e9bed2003-05-31 18:35:21 +00001447 oob_config.badblock_pos = 5;
wdenkdc7c9a12003-03-26 06:55:25 +00001448
1449 for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
1450 if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
wdenka43278a2003-09-11 19:48:06 +00001451 nand = &nand_dev_desc[i];
wdenkdc7c9a12003-03-26 06:55:25 +00001452 break;
1453 }
1454 }
wdenka43278a2003-09-11 19:48:06 +00001455 if (!nand)
1456 return (0);
wdenkdc7c9a12003-03-26 06:55:25 +00001457
wdenk7a8e9bed2003-05-31 18:35:21 +00001458 memset((char *)nand, 0, sizeof(struct nand_chip));
1459
1460 nand->IO_ADDR = physadr;
1461 nand->cache_page = -1; /* init the cache page */
1462 NanD_ScanChips(nand);
1463
1464 if (nand->totlen == 0) {
1465 /* no chips found, clean up and quit */
1466 memset((char *)nand, 0, sizeof(struct nand_chip));
1467 nand->ChipID = NAND_ChipID_UNKNOWN;
wdenka43278a2003-09-11 19:48:06 +00001468 return (0);
wdenk7a8e9bed2003-05-31 18:35:21 +00001469 }
1470
1471 nand->ChipID = ChipID;
wdenk0db5bca2003-03-31 17:27:09 +00001472 if (curr_device == -1)
1473 curr_device = i;
wdenkdc7c9a12003-03-26 06:55:25 +00001474
wdenk0db5bca2003-03-31 17:27:09 +00001475 nand->data_buf = malloc (nand->oobblock + nand->oobsize);
1476 if (!nand->data_buf) {
1477 puts ("Cannot allocate memory for data structures.\n");
wdenka43278a2003-09-11 19:48:06 +00001478 return (0);
wdenk0db5bca2003-03-31 17:27:09 +00001479 }
wdenka43278a2003-09-11 19:48:06 +00001480
1481 return (nand->totlen);
wdenkdc7c9a12003-03-26 06:55:25 +00001482}
1483
1484#ifdef CONFIG_MTD_NAND_ECC
1485/*
1486 * Pre-calculated 256-way 1 byte column parity
1487 */
1488static const u_char nand_ecc_precalc_table[] = {
1489 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
1490 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1491 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1492 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1493 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1494 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1495 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1496 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1497 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1498 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1499 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1500 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1501 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1502 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1503 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1504 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
1505};
1506
1507
1508/*
1509 * Creates non-inverted ECC code from line parity
1510 */
1511static void nand_trans_result(u_char reg2, u_char reg3,
1512 u_char *ecc_code)
1513{
1514 u_char a, b, i, tmp1, tmp2;
1515
1516 /* Initialize variables */
1517 a = b = 0x80;
1518 tmp1 = tmp2 = 0;
1519
1520 /* Calculate first ECC byte */
1521 for (i = 0; i < 4; i++) {
1522 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
1523 tmp1 |= b;
1524 b >>= 1;
1525 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
1526 tmp1 |= b;
1527 b >>= 1;
1528 a >>= 1;
1529 }
1530
1531 /* Calculate second ECC byte */
1532 b = 0x80;
1533 for (i = 0; i < 4; i++) {
1534 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
1535 tmp2 |= b;
1536 b >>= 1;
1537 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
1538 tmp2 |= b;
1539 b >>= 1;
1540 a >>= 1;
1541 }
1542
1543 /* Store two of the ECC bytes */
1544 ecc_code[0] = tmp1;
1545 ecc_code[1] = tmp2;
1546}
1547
1548/*
1549 * Calculate 3 byte ECC code for 256 byte block
1550 */
1551static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
1552{
wdenk7a8e9bed2003-05-31 18:35:21 +00001553 u_char idx, reg1, reg3;
wdenkdc7c9a12003-03-26 06:55:25 +00001554 int j;
1555
1556 /* Initialize variables */
wdenk7a8e9bed2003-05-31 18:35:21 +00001557 reg1 = reg3 = 0;
wdenkdc7c9a12003-03-26 06:55:25 +00001558 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
1559
1560 /* Build up column parity */
1561 for(j = 0; j < 256; j++) {
1562
1563 /* Get CP0 - CP5 from table */
1564 idx = nand_ecc_precalc_table[dat[j]];
wdenk7a8e9bed2003-05-31 18:35:21 +00001565 reg1 ^= idx;
wdenkdc7c9a12003-03-26 06:55:25 +00001566
1567 /* All bit XOR = 1 ? */
1568 if (idx & 0x40) {
1569 reg3 ^= (u_char) j;
wdenkdc7c9a12003-03-26 06:55:25 +00001570 }
1571 }
1572
1573 /* Create non-inverted ECC code from line parity */
wdenk7a8e9bed2003-05-31 18:35:21 +00001574 nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
wdenkdc7c9a12003-03-26 06:55:25 +00001575
1576 /* Calculate final ECC code */
1577 ecc_code[0] = ~ecc_code[0];
1578 ecc_code[1] = ~ecc_code[1];
1579 ecc_code[2] = ((~reg1) << 2) | 0x03;
1580}
1581
1582/*
1583 * Detect and correct a 1 bit error for 256 byte block
1584 */
1585static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
1586{
1587 u_char a, b, c, d1, d2, d3, add, bit, i;
1588
1589 /* Do error detection */
1590 d1 = calc_ecc[0] ^ read_ecc[0];
1591 d2 = calc_ecc[1] ^ read_ecc[1];
1592 d3 = calc_ecc[2] ^ read_ecc[2];
1593
1594 if ((d1 | d2 | d3) == 0) {
1595 /* No errors */
1596 return 0;
1597 }
1598 else {
1599 a = (d1 ^ (d1 >> 1)) & 0x55;
1600 b = (d2 ^ (d2 >> 1)) & 0x55;
1601 c = (d3 ^ (d3 >> 1)) & 0x54;
1602
1603 /* Found and will correct single bit error in the data */
1604 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
1605 c = 0x80;
1606 add = 0;
1607 a = 0x80;
1608 for (i=0; i<4; i++) {
1609 if (d1 & c)
1610 add |= a;
1611 c >>= 2;
1612 a >>= 1;
1613 }
1614 c = 0x80;
1615 for (i=0; i<4; i++) {
1616 if (d2 & c)
1617 add |= a;
1618 c >>= 2;
1619 a >>= 1;
1620 }
1621 bit = 0;
1622 b = 0x04;
1623 c = 0x80;
1624 for (i=0; i<3; i++) {
1625 if (d3 & c)
1626 bit |= b;
1627 c >>= 2;
1628 b >>= 1;
1629 }
1630 b = 0x01;
1631 a = dat[add];
1632 a ^= (b << bit);
1633 dat[add] = a;
1634 return 1;
1635 }
1636 else {
1637 i = 0;
1638 while (d1) {
1639 if (d1 & 0x01)
1640 ++i;
1641 d1 >>= 1;
1642 }
1643 while (d2) {
1644 if (d2 & 0x01)
1645 ++i;
1646 d2 >>= 1;
1647 }
1648 while (d3) {
1649 if (d3 & 0x01)
1650 ++i;
1651 d3 >>= 1;
1652 }
1653 if (i == 1) {
1654 /* ECC Code Error Correction */
1655 read_ecc[0] = calc_ecc[0];
1656 read_ecc[1] = calc_ecc[1];
1657 read_ecc[2] = calc_ecc[2];
1658 return 2;
1659 }
1660 else {
1661 /* Uncorrectable Error */
1662 return -1;
1663 }
1664 }
1665 }
1666
1667 /* Should never happen */
1668 return -1;
1669}
wdenk1f4bb372003-07-27 00:21:01 +00001670
wdenkdc7c9a12003-03-26 06:55:25 +00001671#endif
wdenk998eaae2004-04-18 19:43:36 +00001672
1673#ifdef CONFIG_JFFS2_NAND
1674
1675int read_jffs2_nand(size_t start, size_t len,
1676 size_t * retlen, u_char * buf, int nanddev)
1677{
1678 return nand_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2,
1679 start, len, retlen, buf);
1680}
1681
1682#endif /* CONFIG_JFFS2_NAND */
1683
1684
wdenkdc7c9a12003-03-26 06:55:25 +00001685#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */