blob: 5648ab21785dee96053a6b85f3620924d4d8f610 [file] [log] [blame]
wdenkc8434db2003-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>
wdenk6d3c6d12005-04-03 22:35:21 +00006 *
7 * Added 16-bit nand support
8 * (C) 2004 Texas Instruments
wdenkc8434db2003-03-26 06:55:25 +00009 */
10
11#include <common.h>
wdenkc8434db2003-03-26 06:55:25 +000012#include <command.h>
13#include <malloc.h>
14#include <asm/io.h>
wdenk145d2c12004-04-15 21:48:45 +000015#include <watchdog.h>
wdenkc8434db2003-03-26 06:55:25 +000016
17#ifdef CONFIG_SHOW_BOOT_PROGRESS
18# include <status_led.h>
19# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
20#else
21# define SHOW_BOOT_PROGRESS(arg)
22#endif
23
24#if (CONFIG_COMMANDS & CFG_CMD_NAND)
25
wdenkc8434db2003-03-26 06:55:25 +000026#include <linux/mtd/nand.h>
27#include <linux/mtd/nand_ids.h>
wdenkabda5ca2003-05-31 18:35:21 +000028#include <jffs2/jffs2.h>
wdenkc8434db2003-03-26 06:55:25 +000029
wdenke58b0dc2003-07-27 00:21:01 +000030#ifdef CONFIG_OMAP1510
31void archflashwp(void *archdata, int wp);
32#endif
33
34#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
35
wdenkc8434db2003-03-26 06:55:25 +000036/*
37 * Definition of the out of band configuration structure
38 */
39struct nand_oob_config {
40 int ecc_pos[6]; /* position of ECC bytes inside oob */
41 int badblock_pos; /* position of bad block flag inside oob -1 = inactive */
42 int eccvalid_pos; /* position of ECC valid flag inside oob -1 = inactive */
43} oob_config = { {0}, 0, 0};
44
wdenk934c4f82003-09-11 19:48:06 +000045#undef NAND_DEBUG
wdenkc8434db2003-03-26 06:55:25 +000046#undef PSYCHO_DEBUG
wdenkabda5ca2003-05-31 18:35:21 +000047
48/* ****************** WARNING *********************
49 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
50 * erase (or at least attempt to erase) blocks that are marked
51 * bad. This can be very handy if you are _sure_ that the block
52 * is OK, say because you marked a good block bad to test bad
53 * block handling and you are done testing, or if you have
54 * accidentally marked blocks bad.
55 *
56 * Erasing factory marked bad blocks is a _bad_ idea. If the
57 * erase succeeds there is no reliable way to find them again,
58 * and attempting to program or erase bad blocks can affect
59 * the data in _other_ (good) blocks.
60 */
61#define ALLOW_ERASE_BAD_DEBUG 0
wdenkc8434db2003-03-26 06:55:25 +000062
63#define CONFIG_MTD_NAND_ECC /* enable ECC */
wdenke58b0dc2003-07-27 00:21:01 +000064#define CONFIG_MTD_NAND_ECC_JFFS2
wdenkc8434db2003-03-26 06:55:25 +000065
wdenkabda5ca2003-05-31 18:35:21 +000066/* bits for nand_rw() `cmd'; or together as needed */
67#define NANDRW_READ 0x01
68#define NANDRW_WRITE 0x00
69#define NANDRW_JFFS2 0x02
wdenk145d2c12004-04-15 21:48:45 +000070#define NANDRW_JFFS2_SKIP 0x04
wdenkabda5ca2003-05-31 18:35:21 +000071
wdenkc8434db2003-03-26 06:55:25 +000072/*
73 * Function Prototypes
74 */
75static void nand_print(struct nand_chip *nand);
wdenk79b59372004-06-09 14:58:14 +000076int nand_rw (struct nand_chip* nand, int cmd,
wdenkc8434db2003-03-26 06:55:25 +000077 size_t start, size_t len,
78 size_t * retlen, u_char * buf);
wdenk79b59372004-06-09 14:58:14 +000079int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);
wdenkc8434db2003-03-26 06:55:25 +000080static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
81 size_t * retlen, u_char *buf, u_char *ecc_code);
82static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
83 size_t * retlen, const u_char * buf, u_char * ecc_code);
wdenkabda5ca2003-05-31 18:35:21 +000084static void nand_print_bad(struct nand_chip *nand);
85static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
86 size_t * retlen, u_char * buf);
87static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
88 size_t * retlen, const u_char * buf);
wdenke58b0dc2003-07-27 00:21:01 +000089static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
wdenkc8434db2003-03-26 06:55:25 +000090#ifdef CONFIG_MTD_NAND_ECC
91static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
92static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
93#endif
94
wdenkabda5ca2003-05-31 18:35:21 +000095struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
wdenkc8434db2003-03-26 06:55:25 +000096
97/* Current NAND Device */
98static int curr_device = -1;
99
100/* ------------------------------------------------------------------------- */
101
102int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
103{
104 int rcode = 0;
105
106 switch (argc) {
107 case 0:
108 case 1:
109 printf ("Usage:\n%s\n", cmdtp->usage);
110 return 1;
111 case 2:
wdenk57b2d802003-06-27 21:31:46 +0000112 if (strcmp(argv[1],"info") == 0) {
wdenkc8434db2003-03-26 06:55:25 +0000113 int i;
114
115 putc ('\n');
116
117 for (i=0; i<CFG_MAX_NAND_DEVICE; ++i) {
118 if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)
119 continue; /* list only known devices */
120 printf ("Device %d: ", i);
121 nand_print(&nand_dev_desc[i]);
122 }
123 return 0;
124
125 } else if (strcmp(argv[1],"device") == 0) {
126 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
127 puts ("\nno devices available\n");
128 return 1;
129 }
130 printf ("\nDevice %d: ", curr_device);
131 nand_print(&nand_dev_desc[curr_device]);
132 return 0;
wdenkabda5ca2003-05-31 18:35:21 +0000133
134 } else if (strcmp(argv[1],"bad") == 0) {
135 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
136 puts ("\nno devices available\n");
137 return 1;
138 }
139 printf ("\nDevice %d bad blocks:\n", curr_device);
140 nand_print_bad(&nand_dev_desc[curr_device]);
141 return 0;
142
wdenkc8434db2003-03-26 06:55:25 +0000143 }
144 printf ("Usage:\n%s\n", cmdtp->usage);
145 return 1;
146 case 3:
147 if (strcmp(argv[1],"device") == 0) {
148 int dev = (int)simple_strtoul(argv[2], NULL, 10);
149
150 printf ("\nDevice %d: ", dev);
151 if (dev >= CFG_MAX_NAND_DEVICE) {
152 puts ("unknown device\n");
153 return 1;
154 }
155 nand_print(&nand_dev_desc[dev]);
156 /*nand_print (dev);*/
157
158 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {
159 return 1;
160 }
161
162 curr_device = dev;
163
164 puts ("... is now current device\n");
165
166 return 0;
167 }
wdenkabda5ca2003-05-31 18:35:21 +0000168 else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) {
169 struct nand_chip* nand = &nand_dev_desc[curr_device];
170 ulong off = 0;
171 ulong size = nand->totlen;
172 int ret;
173
174 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
175 curr_device, off, size);
176
177 ret = nand_erase (nand, off, size, 1);
178
179 printf("%s\n", ret ? "ERROR" : "OK");
180
181 return ret;
182 }
wdenkc8434db2003-03-26 06:55:25 +0000183
184 printf ("Usage:\n%s\n", cmdtp->usage);
185 return 1;
186 default:
187 /* at least 4 args */
188
wdenkabda5ca2003-05-31 18:35:21 +0000189 if (strncmp(argv[1], "read", 4) == 0 ||
190 strncmp(argv[1], "write", 5) == 0) {
wdenkc8434db2003-03-26 06:55:25 +0000191 ulong addr = simple_strtoul(argv[2], NULL, 16);
192 ulong off = simple_strtoul(argv[3], NULL, 16);
193 ulong size = simple_strtoul(argv[4], NULL, 16);
wdenkabda5ca2003-05-31 18:35:21 +0000194 int cmd = (strncmp(argv[1], "read", 4) == 0) ?
195 NANDRW_READ : NANDRW_WRITE;
wdenkc8434db2003-03-26 06:55:25 +0000196 int ret, total;
wdenkabda5ca2003-05-31 18:35:21 +0000197 char* cmdtail = strchr(argv[1], '.');
198
199 if (cmdtail && !strncmp(cmdtail, ".oob", 2)) {
200 /* read out-of-band data */
201 if (cmd & NANDRW_READ) {
202 ret = nand_read_oob(nand_dev_desc + curr_device,
203 off, size, &total,
204 (u_char*)addr);
205 }
206 else {
207 ret = nand_write_oob(nand_dev_desc + curr_device,
208 off, size, &total,
209 (u_char*)addr);
210 }
211 return ret;
212 }
213 else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
214 cmd |= NANDRW_JFFS2; /* skip bad blocks */
wdenk145d2c12004-04-15 21:48:45 +0000215 else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) {
216 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
217 if (cmd & NANDRW_READ)
218 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
219 }
wdenkabda5ca2003-05-31 18:35:21 +0000220#ifdef SXNI855T
221 /* need ".e" same as ".j" for compatibility with older units */
222 else if (cmdtail && !strcmp(cmdtail, ".e"))
223 cmd |= NANDRW_JFFS2; /* skip bad blocks */
224#endif
stroese317cbe62004-12-16 17:45:46 +0000225#ifdef CFG_NAND_SKIP_BAD_DOT_I
226 /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */
227 /* ".i" for image -> read skips bad block (no 0xff) */
Stefan Roesef9b85672005-08-12 16:46:35 +0200228 else if (cmdtail && !strcmp(cmdtail, ".i")) {
stroese317cbe62004-12-16 17:45:46 +0000229 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
230 if (cmd & NANDRW_READ)
231 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
Stefan Roesef9b85672005-08-12 16:46:35 +0200232 }
stroese317cbe62004-12-16 17:45:46 +0000233#endif /* CFG_NAND_SKIP_BAD_DOT_I */
wdenkabda5ca2003-05-31 18:35:21 +0000234 else if (cmdtail) {
235 printf ("Usage:\n%s\n", cmdtp->usage);
236 return 1;
237 }
wdenkc8434db2003-03-26 06:55:25 +0000238
239 printf ("\nNAND %s: device %d offset %ld, size %ld ... ",
wdenkabda5ca2003-05-31 18:35:21 +0000240 (cmd & NANDRW_READ) ? "read" : "write",
241 curr_device, off, size);
wdenkc8434db2003-03-26 06:55:25 +0000242
243 ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size,
244 &total, (u_char*)addr);
245
wdenke58b0dc2003-07-27 00:21:01 +0000246 printf (" %d bytes %s: %s\n", total,
wdenk8886a662004-04-18 19:43:36 +0000247 (cmd & NANDRW_READ) ? "read" : "written",
wdenkc8434db2003-03-26 06:55:25 +0000248 ret ? "ERROR" : "OK");
249
250 return ret;
wdenkabda5ca2003-05-31 18:35:21 +0000251 } else if (strcmp(argv[1],"erase") == 0 &&
252 (argc == 4 || strcmp("clean", argv[2]) == 0)) {
253 int clean = argc == 5;
254 ulong off = simple_strtoul(argv[2 + clean], NULL, 16);
255 ulong size = simple_strtoul(argv[3 + clean], NULL, 16);
wdenkc8434db2003-03-26 06:55:25 +0000256 int ret;
257
258 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
259 curr_device, off, size);
260
wdenkabda5ca2003-05-31 18:35:21 +0000261 ret = nand_erase (nand_dev_desc + curr_device, off, size, clean);
wdenkc8434db2003-03-26 06:55:25 +0000262
263 printf("%s\n", ret ? "ERROR" : "OK");
264
265 return ret;
266 } else {
267 printf ("Usage:\n%s\n", cmdtp->usage);
268 rcode = 1;
269 }
270
271 return rcode;
272 }
273}
274
wdenkf287a242003-07-01 21:06:45 +0000275U_BOOT_CMD(
276 nand, 5, 1, do_nand,
wdenkf12e3962003-06-29 21:03:46 +0000277 "nand - NAND sub-system\n",
278 "info - show available NAND devices\n"
279 "nand device [dev] - show or set current device\n"
wdenk145d2c12004-04-15 21:48:45 +0000280 "nand read[.jffs2[s]] addr off size\n"
wdenkf12e3962003-06-29 21:03:46 +0000281 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
282 " at offset `off' to/from memory address `addr'\n"
283 "nand erase [clean] [off size] - erase `size' bytes from\n"
284 " offset `off' (entire device if not specified)\n"
285 "nand bad - show bad blocks\n"
286 "nand read.oob addr off size - read out-of-band data\n"
287 "nand write.oob addr off size - read out-of-band data\n"
288);
289
wdenkc8434db2003-03-26 06:55:25 +0000290int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
291{
292 char *boot_device = NULL;
293 char *ep;
294 int dev;
295 ulong cnt;
296 ulong addr;
297 ulong offset = 0;
298 image_header_t *hdr;
299 int rcode = 0;
300 switch (argc) {
301 case 1:
302 addr = CFG_LOAD_ADDR;
303 boot_device = getenv ("bootdevice");
304 break;
305 case 2:
306 addr = simple_strtoul(argv[1], NULL, 16);
307 boot_device = getenv ("bootdevice");
308 break;
309 case 3:
310 addr = simple_strtoul(argv[1], NULL, 16);
311 boot_device = argv[2];
312 break;
313 case 4:
314 addr = simple_strtoul(argv[1], NULL, 16);
315 boot_device = argv[2];
316 offset = simple_strtoul(argv[3], NULL, 16);
317 break;
318 default:
319 printf ("Usage:\n%s\n", cmdtp->usage);
320 SHOW_BOOT_PROGRESS (-1);
321 return 1;
322 }
323
324 if (!boot_device) {
325 puts ("\n** No boot device **\n");
326 SHOW_BOOT_PROGRESS (-1);
327 return 1;
328 }
329
330 dev = simple_strtoul(boot_device, &ep, 16);
331
332 if ((dev >= CFG_MAX_NAND_DEVICE) ||
333 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {
334 printf ("\n** Device %d not available\n", dev);
335 SHOW_BOOT_PROGRESS (-1);
336 return 1;
337 }
338
wdenkabda5ca2003-05-31 18:35:21 +0000339 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
wdenkc8434db2003-03-26 06:55:25 +0000340 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
341 offset);
342
wdenkabda5ca2003-05-31 18:35:21 +0000343 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset,
wdenkc8434db2003-03-26 06:55:25 +0000344 SECTORSIZE, NULL, (u_char *)addr)) {
345 printf ("** Read error on %d\n", dev);
346 SHOW_BOOT_PROGRESS (-1);
347 return 1;
348 }
349
350 hdr = (image_header_t *)addr;
351
352 if (ntohl(hdr->ih_magic) == IH_MAGIC) {
353
354 print_image_hdr (hdr);
355
356 cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
357 cnt -= SECTORSIZE;
358 } else {
359 printf ("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
360 SHOW_BOOT_PROGRESS (-1);
361 return 1;
362 }
363
wdenkabda5ca2003-05-31 18:35:21 +0000364 if (nand_rw (nand_dev_desc + dev, NANDRW_READ, offset + SECTORSIZE, cnt,
wdenkc8434db2003-03-26 06:55:25 +0000365 NULL, (u_char *)(addr+SECTORSIZE))) {
366 printf ("** Read error on %d\n", dev);
367 SHOW_BOOT_PROGRESS (-1);
368 return 1;
369 }
370
371 /* Loading ok, update default load address */
372
373 load_addr = addr;
374
375 /* Check if we should attempt an auto-start */
376 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
377 char *local_args[2];
378 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
379
380 local_args[0] = argv[0];
381 local_args[1] = NULL;
382
wdenkabda5ca2003-05-31 18:35:21 +0000383 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);
wdenkc8434db2003-03-26 06:55:25 +0000384
385 do_bootm (cmdtp, 0, 1, local_args);
386 rcode = 1;
387 }
388 return rcode;
389}
390
wdenkf287a242003-07-01 21:06:45 +0000391U_BOOT_CMD(
392 nboot, 4, 1, do_nandboot,
wdenkf12e3962003-06-29 21:03:46 +0000393 "nboot - boot from NAND device\n",
394 "loadAddr dev\n"
395);
396
wdenkabda5ca2003-05-31 18:35:21 +0000397/* returns 0 if block containing pos is OK:
398 * valid erase block and
399 * not marked bad, or no bad mark position is specified
400 * returns 1 if marked bad or otherwise invalid
401 */
wdenk6d3c6d12005-04-03 22:35:21 +0000402int check_block (struct nand_chip *nand, unsigned long pos)
wdenkabda5ca2003-05-31 18:35:21 +0000403{
404 int retlen;
405 uint8_t oob_data;
wdenk6d3c6d12005-04-03 22:35:21 +0000406 uint16_t oob_data16[6];
wdenkabda5ca2003-05-31 18:35:21 +0000407 int page0 = pos & (-nand->erasesize);
408 int page1 = page0 + nand->oobblock;
409 int badpos = oob_config.badblock_pos;
410
411 if (pos >= nand->totlen)
412 return 1;
413
414 if (badpos < 0)
415 return 0; /* no way to check, assume OK */
416
wdenk6d3c6d12005-04-03 22:35:21 +0000417 if (nand->bus16) {
418 if (nand_read_oob(nand, (page0 + 0), 12, &retlen, (uint8_t *)oob_data16)
419 || (oob_data16[2] & 0xff00) != 0xff00)
420 return 1;
421 if (nand_read_oob(nand, (page1 + 0), 12, &retlen, (uint8_t *)oob_data16)
422 || (oob_data16[2] & 0xff00) != 0xff00)
423 return 1;
424 } else {
425 /* Note - bad block marker can be on first or second page */
426 if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data)
427 || oob_data != 0xff
428 || nand_read_oob (nand, page1 + badpos, 1, &retlen, &oob_data)
429 || oob_data != 0xff)
430 return 1;
431 }
wdenkabda5ca2003-05-31 18:35:21 +0000432
433 return 0;
434}
wdenk57b2d802003-06-27 21:31:46 +0000435
wdenkabda5ca2003-05-31 18:35:21 +0000436/* print bad blocks in NAND flash */
437static void nand_print_bad(struct nand_chip* nand)
438{
439 unsigned long pos;
440
441 for (pos = 0; pos < nand->totlen; pos += nand->erasesize) {
442 if (check_block(nand, pos))
443 printf(" 0x%8.8lx\n", pos);
444 }
445 puts("\n");
446}
447
448/* cmd: 0: NANDRW_WRITE write, fail on bad block
449 * 1: NANDRW_READ read, fail on bad block
450 * 2: NANDRW_WRITE | NANDRW_JFFS2 write, skip bad blocks
451 * 3: NANDRW_READ | NANDRW_JFFS2 read, data all 0xff for bad blocks
wdenk145d2c12004-04-15 21:48:45 +0000452 * 7: NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP read, skip bad blocks
wdenkabda5ca2003-05-31 18:35:21 +0000453 */
wdenk79b59372004-06-09 14:58:14 +0000454int nand_rw (struct nand_chip* nand, int cmd,
wdenkc8434db2003-03-26 06:55:25 +0000455 size_t start, size_t len,
456 size_t * retlen, u_char * buf)
457{
wdenke58b0dc2003-07-27 00:21:01 +0000458 int ret = 0, n, total = 0;
wdenkc8434db2003-03-26 06:55:25 +0000459 char eccbuf[6];
wdenkabda5ca2003-05-31 18:35:21 +0000460 /* eblk (once set) is the start of the erase block containing the
461 * data being processed.
462 */
463 unsigned long eblk = ~0; /* force mismatch on first pass */
464 unsigned long erasesize = nand->erasesize;
wdenkc8434db2003-03-26 06:55:25 +0000465
wdenkabda5ca2003-05-31 18:35:21 +0000466 while (len) {
467 if ((start & (-erasesize)) != eblk) {
468 /* have crossed into new erase block, deal with
469 * it if it is sure marked bad.
470 */
471 eblk = start & (-erasesize); /* start of block */
472 if (check_block(nand, eblk)) {
473 if (cmd == (NANDRW_READ | NANDRW_JFFS2)) {
474 while (len > 0 &&
475 start - eblk < erasesize) {
476 *(buf++) = 0xff;
477 ++start;
478 ++total;
479 --len;
480 }
481 continue;
wdenk6d3c6d12005-04-03 22:35:21 +0000482 } else if (cmd == (NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP)) {
wdenk145d2c12004-04-15 21:48:45 +0000483 start += erasesize;
484 continue;
wdenk6d3c6d12005-04-03 22:35:21 +0000485 } else if (cmd == (NANDRW_WRITE | NANDRW_JFFS2)) {
wdenkabda5ca2003-05-31 18:35:21 +0000486 /* skip bad block */
487 start += erasesize;
488 continue;
wdenk6d3c6d12005-04-03 22:35:21 +0000489 } else {
wdenkabda5ca2003-05-31 18:35:21 +0000490 ret = 1;
491 break;
492 }
493 }
494 }
wdenkc8434db2003-03-26 06:55:25 +0000495 /* The ECC will not be calculated correctly if
496 less than 512 is written or read */
wdenke58b0dc2003-07-27 00:21:01 +0000497 /* Is request at least 512 bytes AND it starts on a proper boundry */
498 if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
499 printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
500
wdenk6d3c6d12005-04-03 22:35:21 +0000501 if (cmd & NANDRW_READ) {
wdenkabda5ca2003-05-31 18:35:21 +0000502 ret = nand_read_ecc(nand, start,
503 min(len, eblk + erasesize - start),
wdenke58b0dc2003-07-27 00:21:01 +0000504 &n, (u_char*)buf, eccbuf);
wdenk6d3c6d12005-04-03 22:35:21 +0000505 } else {
wdenkabda5ca2003-05-31 18:35:21 +0000506 ret = nand_write_ecc(nand, start,
507 min(len, eblk + erasesize - start),
wdenke58b0dc2003-07-27 00:21:01 +0000508 &n, (u_char*)buf, eccbuf);
wdenk6d3c6d12005-04-03 22:35:21 +0000509 }
wdenkc8434db2003-03-26 06:55:25 +0000510
511 if (ret)
512 break;
513
514 start += n;
515 buf += n;
516 total += n;
517 len -= n;
518 }
519 if (retlen)
520 *retlen = total;
521
522 return ret;
523}
524
525static void nand_print(struct nand_chip *nand)
wdenk359733b2003-03-31 17:27:09 +0000526{
wdenkabda5ca2003-05-31 18:35:21 +0000527 if (nand->numchips > 1) {
528 printf("%s at 0x%lx,\n"
529 "\t %d chips %s, size %d MB, \n"
530 "\t total size %ld MB, sector size %ld kB\n",
531 nand->name, nand->IO_ADDR, nand->numchips,
532 nand->chips_name, 1 << (nand->chipshift - 20),
533 nand->totlen >> 20, nand->erasesize >> 10);
534 }
535 else {
wdenk57b2d802003-06-27 21:31:46 +0000536 printf("%s at 0x%lx (", nand->chips_name, nand->IO_ADDR);
wdenkabda5ca2003-05-31 18:35:21 +0000537 print_size(nand->totlen, ", ");
538 print_size(nand->erasesize, " sector)\n");
wdenkc8434db2003-03-26 06:55:25 +0000539 }
540}
541
542/* ------------------------------------------------------------------------- */
543
wdenke58b0dc2003-07-27 00:21:01 +0000544static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
wdenkc8434db2003-03-26 06:55:25 +0000545{
546 /* This is inline, to optimise the common case, where it's ready instantly */
547 int ret = 0;
wdenkc8434db2003-03-26 06:55:25 +0000548
wdenke58b0dc2003-07-27 00:21:01 +0000549#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */
550 if(ale_wait)
551 NAND_WAIT_READY(nand); /* do the worst case 25us wait */
552 else
553 udelay(10);
554#else /* has functional r/b signal */
wdenk232fe0b2003-09-02 22:48:03 +0000555 NAND_WAIT_READY(nand);
wdenke58b0dc2003-07-27 00:21:01 +0000556#endif
wdenkc8434db2003-03-26 06:55:25 +0000557 return ret;
558}
559
560/* NanD_Command: Send a flash command to the flash chip */
561
562static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
563{
564 unsigned long nandptr = nand->IO_ADDR;
565
566 /* Assert the CLE (Command Latch Enable) line to the flash chip */
567 NAND_CTL_SETCLE(nandptr);
568
569 /* Send the command */
570 WRITE_NAND_COMMAND(command, nandptr);
571
572 /* Lower the CLE line */
573 NAND_CTL_CLRCLE(nandptr);
574
wdenke58b0dc2003-07-27 00:21:01 +0000575#ifdef NAND_NO_RB
576 if(command == NAND_CMD_RESET){
577 u_char ret_val;
578 NanD_Command(nand, NAND_CMD_STATUS);
wdenk6d3c6d12005-04-03 22:35:21 +0000579 do {
wdenke58b0dc2003-07-27 00:21:01 +0000580 ret_val = READ_NAND(nandptr);/* wait till ready */
581 } while((ret_val & 0x40) != 0x40);
582 }
583#endif
584 return NanD_WaitReady(nand, 0);
wdenkc8434db2003-03-26 06:55:25 +0000585}
586
587/* NanD_Address: Set the current address for the flash chip */
588
589static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
wdenk359733b2003-03-31 17:27:09 +0000590{
591 unsigned long nandptr;
592 int i;
wdenkc8434db2003-03-26 06:55:25 +0000593
wdenk359733b2003-03-31 17:27:09 +0000594 nandptr = nand->IO_ADDR;
wdenkc8434db2003-03-26 06:55:25 +0000595
596 /* Assert the ALE (Address Latch Enable) line to the flash chip */
wdenk359733b2003-03-31 17:27:09 +0000597 NAND_CTL_SETALE(nandptr);
wdenkc8434db2003-03-26 06:55:25 +0000598
wdenk359733b2003-03-31 17:27:09 +0000599 /* Send the address */
600 /* Devices with 256-byte page are addressed as:
601 * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
602 * there is no device on the market with page256
603 * and more than 24 bits.
604 * Devices with 512-byte page are addressed as:
605 * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
606 * 25-31 is sent only if the chip support it.
607 * bit 8 changes the read command to be sent
608 * (NAND_CMD_READ0 or NAND_CMD_READ1).
wdenkc8434db2003-03-26 06:55:25 +0000609 */
610
wdenk359733b2003-03-31 17:27:09 +0000611 if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
612 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenkc8434db2003-03-26 06:55:25 +0000613
wdenk359733b2003-03-31 17:27:09 +0000614 ofs = ofs >> nand->page_shift;
wdenkc8434db2003-03-26 06:55:25 +0000615
wdenk6d3c6d12005-04-03 22:35:21 +0000616 if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
617 for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) {
wdenk359733b2003-03-31 17:27:09 +0000618 WRITE_NAND_ADDRESS(ofs, nandptr);
wdenk6d3c6d12005-04-03 22:35:21 +0000619 }
620 }
wdenkc8434db2003-03-26 06:55:25 +0000621
wdenk359733b2003-03-31 17:27:09 +0000622 /* Lower the ALE line */
623 NAND_CTL_CLRALE(nandptr);
wdenkc8434db2003-03-26 06:55:25 +0000624
wdenk359733b2003-03-31 17:27:09 +0000625 /* Wait for the chip to respond */
wdenke58b0dc2003-07-27 00:21:01 +0000626 return NanD_WaitReady(nand, 1);
wdenk359733b2003-03-31 17:27:09 +0000627}
wdenkc8434db2003-03-26 06:55:25 +0000628
629/* NanD_SelectChip: Select a given flash chip within the current floor */
630
631static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
632{
633 /* Wait for it to be ready */
wdenke58b0dc2003-07-27 00:21:01 +0000634 return NanD_WaitReady(nand, 0);
wdenkc8434db2003-03-26 06:55:25 +0000635}
636
637/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
638
639static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
640{
641 int mfr, id, i;
642
wdenk359733b2003-03-31 17:27:09 +0000643 NAND_ENABLE_CE(nand); /* set pin low */
wdenkc8434db2003-03-26 06:55:25 +0000644 /* Reset the chip */
645 if (NanD_Command(nand, NAND_CMD_RESET)) {
646#ifdef NAND_DEBUG
647 printf("NanD_Command (reset) for %d,%d returned true\n",
648 floor, chip);
649#endif
wdenk359733b2003-03-31 17:27:09 +0000650 NAND_DISABLE_CE(nand); /* set pin high */
wdenkc8434db2003-03-26 06:55:25 +0000651 return 0;
652 }
653
654 /* Read the NAND chip ID: 1. Send ReadID command */
655 if (NanD_Command(nand, NAND_CMD_READID)) {
656#ifdef NAND_DEBUG
657 printf("NanD_Command (ReadID) for %d,%d returned true\n",
658 floor, chip);
659#endif
wdenk359733b2003-03-31 17:27:09 +0000660 NAND_DISABLE_CE(nand); /* set pin high */
wdenkc8434db2003-03-26 06:55:25 +0000661 return 0;
662 }
663
664 /* Read the NAND chip ID: 2. Send address byte zero */
665 NanD_Address(nand, ADDR_COLUMN, 0);
666
667 /* Read the manufacturer and device id codes from the device */
668
669 mfr = READ_NAND(nand->IO_ADDR);
670
671 id = READ_NAND(nand->IO_ADDR);
672
wdenk57b2d802003-06-27 21:31:46 +0000673 NAND_DISABLE_CE(nand); /* set pin high */
wdenka7316b02005-05-12 22:48:09 +0000674
wdenka4685fe2003-09-03 14:03:26 +0000675#ifdef NAND_DEBUG
wdenka7316b02005-05-12 22:48:09 +0000676 printf("NanD_Command (ReadID) got %x %x\n", mfr, id);
wdenka4685fe2003-09-03 14:03:26 +0000677#endif
wdenka7316b02005-05-12 22:48:09 +0000678 if (mfr == 0xff || mfr == 0) {
679 /* No response - return failure */
wdenk359733b2003-03-31 17:27:09 +0000680 return 0;
681 }
wdenkc8434db2003-03-26 06:55:25 +0000682
683 /* Check it's the same as the first chip we identified.
684 * M-Systems say that any given nand_chip device should only
685 * contain _one_ type of flash part, although that's not a
686 * hardware restriction. */
687 if (nand->mfr) {
wdenk6d3c6d12005-04-03 22:35:21 +0000688 if (nand->mfr == mfr && nand->id == id) {
wdenkc8434db2003-03-26 06:55:25 +0000689 return 1; /* This is another the same the first */
wdenk6d3c6d12005-04-03 22:35:21 +0000690 } else {
wdenkc8434db2003-03-26 06:55:25 +0000691 printf("Flash chip at floor %d, chip %d is different:\n",
692 floor, chip);
wdenk6d3c6d12005-04-03 22:35:21 +0000693 }
wdenkc8434db2003-03-26 06:55:25 +0000694 }
695
696 /* Print and store the manufacturer and ID codes. */
697 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
698 if (mfr == nand_flash_ids[i].manufacture_id &&
699 id == nand_flash_ids[i].model_id) {
700#ifdef NAND_DEBUG
701 printf("Flash chip found:\n\t Manufacturer ID: 0x%2.2X, "
702 "Chip ID: 0x%2.2X (%s)\n", mfr, id,
703 nand_flash_ids[i].name);
704#endif
705 if (!nand->mfr) {
706 nand->mfr = mfr;
707 nand->id = id;
708 nand->chipshift =
709 nand_flash_ids[i].chipshift;
710 nand->page256 = nand_flash_ids[i].page256;
wdenkabda5ca2003-05-31 18:35:21 +0000711 nand->eccsize = 256;
wdenkc8434db2003-03-26 06:55:25 +0000712 if (nand->page256) {
713 nand->oobblock = 256;
714 nand->oobsize = 8;
715 nand->page_shift = 8;
716 } else {
717 nand->oobblock = 512;
718 nand->oobsize = 16;
719 nand->page_shift = 9;
720 }
wdenk6d3c6d12005-04-03 22:35:21 +0000721 nand->pageadrlen = nand_flash_ids[i].pageadrlen;
722 nand->erasesize = nand_flash_ids[i].erasesize;
723 nand->chips_name = nand_flash_ids[i].name;
724 nand->bus16 = nand_flash_ids[i].bus16;
725 return 1;
wdenkc8434db2003-03-26 06:55:25 +0000726 }
727 return 0;
728 }
729 }
730
731
732#ifdef NAND_DEBUG
733 /* We haven't fully identified the chip. Print as much as we know. */
734 printf("Unknown flash chip found: %2.2X %2.2X\n",
735 id, mfr);
736#endif
737
738 return 0;
739}
740
741/* NanD_ScanChips: Find all NAND chips present in a nand_chip, and identify them */
742
743static void NanD_ScanChips(struct nand_chip *nand)
744{
745 int floor, chip;
746 int numchips[NAND_MAX_FLOORS];
747 int maxchips = NAND_MAX_CHIPS;
748 int ret = 1;
749
750 nand->numchips = 0;
751 nand->mfr = 0;
752 nand->id = 0;
753
754
755 /* For each floor, find the number of valid chips it contains */
756 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
757 ret = 1;
758 numchips[floor] = 0;
759 for (chip = 0; chip < maxchips && ret != 0; chip++) {
760
761 ret = NanD_IdentChip(nand, floor, chip);
762 if (ret) {
763 numchips[floor]++;
764 nand->numchips++;
765 }
766 }
767 }
768
769 /* If there are none at all that we recognise, bail */
770 if (!nand->numchips) {
wdenk934c4f82003-09-11 19:48:06 +0000771#ifdef NAND_DEBUG
wdenka4685fe2003-09-03 14:03:26 +0000772 puts ("No NAND flash chips recognised.\n");
wdenk934c4f82003-09-11 19:48:06 +0000773#endif
wdenkc8434db2003-03-26 06:55:25 +0000774 return;
775 }
776
777 /* Allocate an array to hold the information for each chip */
778 nand->chips = malloc(sizeof(struct Nand) * nand->numchips);
779 if (!nand->chips) {
780 puts ("No memory for allocating chip info structures\n");
781 return;
782 }
783
784 ret = 0;
785
786 /* Fill out the chip array with {floor, chipno} for each
787 * detected chip in the device. */
788 for (floor = 0; floor < NAND_MAX_FLOORS; floor++) {
789 for (chip = 0; chip < numchips[floor]; chip++) {
790 nand->chips[ret].floor = floor;
791 nand->chips[ret].chip = chip;
792 nand->chips[ret].curadr = 0;
793 nand->chips[ret].curmode = 0x50;
794 ret++;
795 }
796 }
797
798 /* Calculate and print the total size of the device */
799 nand->totlen = nand->numchips * (1 << nand->chipshift);
800
801#ifdef NAND_DEBUG
802 printf("%d flash chips found. Total nand_chip size: %ld MB\n",
803 nand->numchips, nand->totlen >> 20);
804#endif
805}
wdenk359733b2003-03-31 17:27:09 +0000806
wdenkc8434db2003-03-26 06:55:25 +0000807/* we need to be fast here, 1 us per read translates to 1 second per meg */
wdenk6d3c6d12005-04-03 22:35:21 +0000808static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr)
wdenk359733b2003-03-31 17:27:09 +0000809{
wdenkabda5ca2003-05-31 18:35:21 +0000810 unsigned long nandptr = nand->IO_ADDR;
wdenk359733b2003-03-31 17:27:09 +0000811
wdenk6d3c6d12005-04-03 22:35:21 +0000812 NanD_Command (nand, NAND_CMD_READ0);
813
814 if (nand->bus16) {
815 u16 val;
wdenk359733b2003-03-31 17:27:09 +0000816
wdenk6d3c6d12005-04-03 22:35:21 +0000817 while (cntr >= 16) {
818 val = READ_NAND (nandptr);
819 *data_buf++ = val & 0xff;
820 *data_buf++ = val >> 8;
821 val = READ_NAND (nandptr);
822 *data_buf++ = val & 0xff;
823 *data_buf++ = val >> 8;
824 val = READ_NAND (nandptr);
825 *data_buf++ = val & 0xff;
826 *data_buf++ = val >> 8;
827 val = READ_NAND (nandptr);
828 *data_buf++ = val & 0xff;
829 *data_buf++ = val >> 8;
830 val = READ_NAND (nandptr);
831 *data_buf++ = val & 0xff;
832 *data_buf++ = val >> 8;
833 val = READ_NAND (nandptr);
834 *data_buf++ = val & 0xff;
835 *data_buf++ = val >> 8;
836 val = READ_NAND (nandptr);
837 *data_buf++ = val & 0xff;
838 *data_buf++ = val >> 8;
839 val = READ_NAND (nandptr);
840 *data_buf++ = val & 0xff;
841 *data_buf++ = val >> 8;
842 cntr -= 16;
843 }
844
845 while (cntr > 0) {
846 val = READ_NAND (nandptr);
847 *data_buf++ = val & 0xff;
848 *data_buf++ = val >> 8;
849 cntr -= 2;
850 }
851 } else {
852 while (cntr >= 16) {
853 *data_buf++ = READ_NAND (nandptr);
854 *data_buf++ = READ_NAND (nandptr);
855 *data_buf++ = READ_NAND (nandptr);
856 *data_buf++ = READ_NAND (nandptr);
857 *data_buf++ = READ_NAND (nandptr);
858 *data_buf++ = READ_NAND (nandptr);
859 *data_buf++ = READ_NAND (nandptr);
860 *data_buf++ = READ_NAND (nandptr);
861 *data_buf++ = READ_NAND (nandptr);
862 *data_buf++ = READ_NAND (nandptr);
863 *data_buf++ = READ_NAND (nandptr);
864 *data_buf++ = READ_NAND (nandptr);
865 *data_buf++ = READ_NAND (nandptr);
866 *data_buf++ = READ_NAND (nandptr);
867 *data_buf++ = READ_NAND (nandptr);
868 *data_buf++ = READ_NAND (nandptr);
869 cntr -= 16;
870 }
871
872 while (cntr > 0) {
873 *data_buf++ = READ_NAND (nandptr);
874 cntr--;
875 }
wdenk359733b2003-03-31 17:27:09 +0000876 }
877}
wdenkc8434db2003-03-26 06:55:25 +0000878
wdenkc8434db2003-03-26 06:55:25 +0000879/*
880 * NAND read with ECC
881 */
882static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
883 size_t * retlen, u_char *buf, u_char *ecc_code)
884{
885 int col, page;
886 int ecc_status = 0;
887#ifdef CONFIG_MTD_NAND_ECC
888 int j;
889 int ecc_failed = 0;
890 u_char *data_poi;
891 u_char ecc_calc[6];
892#endif
wdenkc8434db2003-03-26 06:55:25 +0000893
894 /* Do not allow reads past end of device */
895 if ((start + len) > nand->totlen) {
wdenk6d3c6d12005-04-03 22:35:21 +0000896 printf ("%s: Attempt read beyond end of device %x %x %x\n",
897 __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
wdenkc8434db2003-03-26 06:55:25 +0000898 *retlen = 0;
899 return -1;
900 }
901
902 /* First we calculate the starting page */
wdenk359733b2003-03-31 17:27:09 +0000903 /*page = shr(start, nand->page_shift);*/
904 page = start >> nand->page_shift;
wdenkc8434db2003-03-26 06:55:25 +0000905
906 /* Get raw starting column */
907 col = start & (nand->oobblock - 1);
908
909 /* Initialize return value */
910 *retlen = 0;
911
912 /* Select the NAND device */
913 NAND_ENABLE_CE(nand); /* set pin low */
914
915 /* Loop until all data read */
916 while (*retlen < len) {
917
wdenkc8434db2003-03-26 06:55:25 +0000918#ifdef CONFIG_MTD_NAND_ECC
wdenkc8434db2003-03-26 06:55:25 +0000919 /* Do we have this page in cache ? */
920 if (nand->cache_page == page)
921 goto readdata;
922 /* Send the read command */
923 NanD_Command(nand, NAND_CMD_READ0);
wdenk6d3c6d12005-04-03 22:35:21 +0000924 if (nand->bus16) {
925 NanD_Address(nand, ADDR_COLUMN_PAGE,
926 (page << nand->page_shift) + (col >> 1));
927 } else {
928 NanD_Address(nand, ADDR_COLUMN_PAGE,
929 (page << nand->page_shift) + col);
930 }
931
wdenkc8434db2003-03-26 06:55:25 +0000932 /* Read in a page + oob data */
wdenkabda5ca2003-05-31 18:35:21 +0000933 NanD_ReadBuf(nand, nand->data_buf, nand->oobblock + nand->oobsize);
wdenkc8434db2003-03-26 06:55:25 +0000934
935 /* copy data into cache, for read out of cache and if ecc fails */
wdenk6d3c6d12005-04-03 22:35:21 +0000936 if (nand->data_cache) {
937 memcpy (nand->data_cache, nand->data_buf,
938 nand->oobblock + nand->oobsize);
939 }
wdenkc8434db2003-03-26 06:55:25 +0000940
941 /* Pick the ECC bytes out of the oob data */
wdenk6d3c6d12005-04-03 22:35:21 +0000942 for (j = 0; j < 6; j++) {
wdenkc8434db2003-03-26 06:55:25 +0000943 ecc_code[j] = nand->data_buf[(nand->oobblock + oob_config.ecc_pos[j])];
wdenk6d3c6d12005-04-03 22:35:21 +0000944 }
wdenkc8434db2003-03-26 06:55:25 +0000945
946 /* Calculate the ECC and verify it */
947 /* If block was not written with ECC, skip ECC */
948 if (oob_config.eccvalid_pos != -1 &&
949 (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
950
951 nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
952 switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
953 case -1:
wdenk359733b2003-03-31 17:27:09 +0000954 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkc8434db2003-03-26 06:55:25 +0000955 ecc_failed++;
956 break;
957 case 1:
958 case 2: /* transfer ECC corrected data to cache */
wdenkabda5ca2003-05-31 18:35:21 +0000959 if (nand->data_cache)
960 memcpy (nand->data_cache, nand->data_buf, 256);
wdenkc8434db2003-03-26 06:55:25 +0000961 break;
962 }
963 }
964
965 if (oob_config.eccvalid_pos != -1 &&
966 nand->oobblock == 512 && (nand->data_buf[nand->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
967
968 nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
969 switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
970 case -1:
wdenk359733b2003-03-31 17:27:09 +0000971 printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
wdenkc8434db2003-03-26 06:55:25 +0000972 ecc_failed++;
973 break;
974 case 1:
975 case 2: /* transfer ECC corrected data to cache */
976 if (nand->data_cache)
977 memcpy (&nand->data_cache[256], &nand->data_buf[256], 256);
978 break;
979 }
980 }
981readdata:
982 /* Read the data from ECC data buffer into return buffer */
983 data_poi = (nand->data_cache) ? nand->data_cache : nand->data_buf;
984 data_poi += col;
985 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenkabda5ca2003-05-31 18:35:21 +0000986 memcpy (buf + *retlen, data_poi, len - *retlen);
wdenkc8434db2003-03-26 06:55:25 +0000987 *retlen = len;
988 } else {
wdenkabda5ca2003-05-31 18:35:21 +0000989 memcpy (buf + *retlen, data_poi, nand->oobblock - col);
wdenkc8434db2003-03-26 06:55:25 +0000990 *retlen += nand->oobblock - col;
991 }
992 /* Set cache page address, invalidate, if ecc_failed */
993 nand->cache_page = (nand->data_cache && !ecc_failed) ? page : -1;
994
995 ecc_status += ecc_failed;
996 ecc_failed = 0;
997
998#else
999 /* Send the read command */
1000 NanD_Command(nand, NAND_CMD_READ0);
wdenk6d3c6d12005-04-03 22:35:21 +00001001 if (nand->bus16) {
1002 NanD_Address(nand, ADDR_COLUMN_PAGE,
1003 (page << nand->page_shift) + (col >> 1));
1004 } else {
1005 NanD_Address(nand, ADDR_COLUMN_PAGE,
1006 (page << nand->page_shift) + col);
1007 }
1008
wdenkc8434db2003-03-26 06:55:25 +00001009 /* Read the data directly into the return buffer */
1010 if ((*retlen + (nand->oobblock - col)) >= len) {
wdenkabda5ca2003-05-31 18:35:21 +00001011 NanD_ReadBuf(nand, buf + *retlen, len - *retlen);
wdenkc8434db2003-03-26 06:55:25 +00001012 *retlen = len;
1013 /* We're done */
1014 continue;
1015 } else {
wdenkabda5ca2003-05-31 18:35:21 +00001016 NanD_ReadBuf(nand, buf + *retlen, nand->oobblock - col);
wdenkc8434db2003-03-26 06:55:25 +00001017 *retlen += nand->oobblock - col;
1018 }
1019#endif
1020 /* For subsequent reads align to page boundary. */
1021 col = 0;
1022 /* Increment page address */
1023 page++;
1024 }
1025
1026 /* De-select the NAND device */
wdenk359733b2003-03-31 17:27:09 +00001027 NAND_DISABLE_CE(nand); /* set pin high */
wdenkc8434db2003-03-26 06:55:25 +00001028
1029 /*
1030 * Return success, if no ECC failures, else -EIO
1031 * fs driver will take care of that, because
1032 * retlen == desired len and result == -EIO
1033 */
1034 return ecc_status ? -1 : 0;
1035}
1036
wdenkc8434db2003-03-26 06:55:25 +00001037/*
1038 * Nand_page_program function is used for write and writev !
1039 */
1040static int nand_write_page (struct nand_chip *nand,
1041 int page, int col, int last, u_char * ecc_code)
1042{
1043
1044 int i;
wdenkc8434db2003-03-26 06:55:25 +00001045 unsigned long nandptr = nand->IO_ADDR;
wdenk6d3c6d12005-04-03 22:35:21 +00001046
wdenke58b0dc2003-07-27 00:21:01 +00001047#ifdef CONFIG_MTD_NAND_ECC
wdenkc8434db2003-03-26 06:55:25 +00001048#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1049 int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
1050#endif
1051#endif
1052 /* pad oob area */
1053 for (i = nand->oobblock; i < nand->oobblock + nand->oobsize; i++)
1054 nand->data_buf[i] = 0xff;
1055
1056#ifdef CONFIG_MTD_NAND_ECC
1057 /* Zero out the ECC array */
1058 for (i = 0; i < 6; i++)
1059 ecc_code[i] = 0x00;
1060
1061 /* Read back previous written data, if col > 0 */
1062 if (col) {
wdenk6d3c6d12005-04-03 22:35:21 +00001063 NanD_Command (nand, NAND_CMD_READ0);
1064 if (nand->bus16) {
1065 NanD_Address (nand, ADDR_COLUMN_PAGE,
1066 (page << nand->page_shift) + (col >> 1));
1067 } else {
1068 NanD_Address (nand, ADDR_COLUMN_PAGE,
1069 (page << nand->page_shift) + col);
1070 }
1071
1072 if (nand->bus16) {
1073 u16 val;
1074
1075 for (i = 0; i < col; i += 2) {
1076 val = READ_NAND (nandptr);
1077 nand->data_buf[i] = val & 0xff;
1078 nand->data_buf[i + 1] = val >> 8;
1079 }
1080 } else {
1081 for (i = 0; i < col; i++)
1082 nand->data_buf[i] = READ_NAND (nandptr);
1083 }
wdenkc8434db2003-03-26 06:55:25 +00001084 }
1085
1086 /* Calculate and write the ECC if we have enough data */
1087 if ((col < nand->eccsize) && (last >= nand->eccsize)) {
1088 nand_calculate_ecc (&nand->data_buf[0], &(ecc_code[0]));
wdenk6d3c6d12005-04-03 22:35:21 +00001089 for (i = 0; i < 3; i++) {
1090 nand->data_buf[(nand->oobblock +
1091 oob_config.ecc_pos[i])] = ecc_code[i];
1092 }
1093 if (oob_config.eccvalid_pos != -1) {
1094 nand->data_buf[nand->oobblock +
1095 oob_config.eccvalid_pos] = 0xf0;
1096 }
wdenkc8434db2003-03-26 06:55:25 +00001097 }
1098
1099 /* Calculate and write the second ECC if we have enough data */
1100 if ((nand->oobblock == 512) && (last == nand->oobblock)) {
1101 nand_calculate_ecc (&nand->data_buf[256], &(ecc_code[3]));
wdenk6d3c6d12005-04-03 22:35:21 +00001102 for (i = 3; i < 6; i++) {
1103 nand->data_buf[(nand->oobblock +
1104 oob_config.ecc_pos[i])] = ecc_code[i];
1105 }
1106 if (oob_config.eccvalid_pos != -1) {
1107 nand->data_buf[nand->oobblock +
1108 oob_config.eccvalid_pos] &= 0x0f;
1109 }
wdenkc8434db2003-03-26 06:55:25 +00001110 }
1111#endif
1112 /* Prepad for partial page programming !!! */
1113 for (i = 0; i < col; i++)
1114 nand->data_buf[i] = 0xff;
1115
1116 /* Postpad for partial page programming !!! oob is already padded */
1117 for (i = last; i < nand->oobblock; i++)
1118 nand->data_buf[i] = 0xff;
1119
1120 /* Send command to begin auto page programming */
wdenk6d3c6d12005-04-03 22:35:21 +00001121 NanD_Command (nand, NAND_CMD_READ0);
1122 NanD_Command (nand, NAND_CMD_SEQIN);
1123 if (nand->bus16) {
1124 NanD_Address (nand, ADDR_COLUMN_PAGE,
1125 (page << nand->page_shift) + (col >> 1));
1126 } else {
1127 NanD_Address (nand, ADDR_COLUMN_PAGE,
1128 (page << nand->page_shift) + col);
1129 }
wdenkc8434db2003-03-26 06:55:25 +00001130
1131 /* Write out complete page of data */
wdenk6d3c6d12005-04-03 22:35:21 +00001132 if (nand->bus16) {
1133 for (i = 0; i < (nand->oobblock + nand->oobsize); i += 2) {
1134 WRITE_NAND (nand->data_buf[i] +
1135 (nand->data_buf[i + 1] << 8),
1136 nand->IO_ADDR);
1137 }
1138 } else {
1139 for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
1140 WRITE_NAND (nand->data_buf[i], nand->IO_ADDR);
1141 }
wdenkc8434db2003-03-26 06:55:25 +00001142
1143 /* Send command to actually program the data */
wdenk6d3c6d12005-04-03 22:35:21 +00001144 NanD_Command (nand, NAND_CMD_PAGEPROG);
1145 NanD_Command (nand, NAND_CMD_STATUS);
wdenke58b0dc2003-07-27 00:21:01 +00001146#ifdef NAND_NO_RB
wdenk6d3c6d12005-04-03 22:35:21 +00001147 {
1148 u_char ret_val;
wdenkc8434db2003-03-26 06:55:25 +00001149
wdenk6d3c6d12005-04-03 22:35:21 +00001150 do {
1151 ret_val = READ_NAND (nandptr); /* wait till ready */
1152 } while ((ret_val & 0x40) != 0x40);
wdenke58b0dc2003-07-27 00:21:01 +00001153 }
1154#endif
wdenkc8434db2003-03-26 06:55:25 +00001155 /* See if device thinks it succeeded */
wdenk6d3c6d12005-04-03 22:35:21 +00001156 if (READ_NAND (nand->IO_ADDR) & 0x01) {
1157 printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__,
1158 page);
wdenkc8434db2003-03-26 06:55:25 +00001159 return -1;
1160 }
1161#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1162 /*
1163 * The NAND device assumes that it is always writing to
1164 * a cleanly erased page. Hence, it performs its internal
1165 * write verification only on bits that transitioned from
1166 * 1 to 0. The device does NOT verify the whole page on a
1167 * byte by byte basis. It is possible that the page was
1168 * not completely erased or the page is becoming unusable
1169 * due to wear. The read with ECC would catch the error
1170 * later when the ECC page check fails, but we would rather
1171 * catch it early in the page write stage. Better to write
1172 * no data than invalid data.
1173 */
1174
1175 /* Send command to read back the page */
1176 if (col < nand->eccsize)
wdenk6d3c6d12005-04-03 22:35:21 +00001177 NanD_Command (nand, NAND_CMD_READ0);
wdenkc8434db2003-03-26 06:55:25 +00001178 else
wdenk6d3c6d12005-04-03 22:35:21 +00001179 NanD_Command (nand, NAND_CMD_READ1);
1180 if (nand->bus16) {
1181 NanD_Address (nand, ADDR_COLUMN_PAGE,
1182 (page << nand->page_shift) + (col >> 1));
1183 } else {
1184 NanD_Address (nand, ADDR_COLUMN_PAGE,
1185 (page << nand->page_shift) + col);
1186 }
wdenkc8434db2003-03-26 06:55:25 +00001187
1188 /* Loop through and verify the data */
wdenk6d3c6d12005-04-03 22:35:21 +00001189 if (nand->bus16) {
1190 for (i = col; i < last; i = +2) {
1191 if ((nand->data_buf[i] +
1192 (nand->data_buf[i + 1] << 8)) != READ_NAND (nand->IO_ADDR)) {
1193 printf ("%s: Failed write verify, page 0x%08x ",
1194 __FUNCTION__, page);
1195 return -1;
1196 }
1197 }
1198 } else {
1199 for (i = col; i < last; i++) {
1200 if (nand->data_buf[i] != READ_NAND (nand->IO_ADDR)) {
1201 printf ("%s: Failed write verify, page 0x%08x ",
1202 __FUNCTION__, page);
1203 return -1;
1204 }
wdenkc8434db2003-03-26 06:55:25 +00001205 }
1206 }
1207
1208#ifdef CONFIG_MTD_NAND_ECC
1209 /*
1210 * We also want to check that the ECC bytes wrote
1211 * correctly for the same reasons stated above.
1212 */
wdenk6d3c6d12005-04-03 22:35:21 +00001213 NanD_Command (nand, NAND_CMD_READOOB);
1214 if (nand->bus16) {
1215 NanD_Address (nand, ADDR_COLUMN_PAGE,
1216 (page << nand->page_shift) + (col >> 1));
1217 } else {
1218 NanD_Address (nand, ADDR_COLUMN_PAGE,
1219 (page << nand->page_shift) + col);
1220 }
1221 if (nand->bus16) {
1222 for (i = 0; i < nand->oobsize; i += 2) {
stroese4d8b3092005-05-03 06:12:20 +00001223 u16 val;
1224
wdenk6d3c6d12005-04-03 22:35:21 +00001225 val = READ_NAND (nand->IO_ADDR);
1226 nand->data_buf[i] = val & 0xff;
1227 nand->data_buf[i + 1] = val >> 8;
1228 }
1229 } else {
1230 for (i = 0; i < nand->oobsize; i++) {
1231 nand->data_buf[i] = READ_NAND (nand->IO_ADDR);
1232 }
1233 }
wdenkc8434db2003-03-26 06:55:25 +00001234 for (i = 0; i < ecc_bytes; i++) {
1235 if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
wdenk359733b2003-03-31 17:27:09 +00001236 printf ("%s: Failed ECC write "
wdenk6d3c6d12005-04-03 22:35:21 +00001237 "verify, page 0x%08x, "
1238 "%6i bytes were succesful\n",
1239 __FUNCTION__, page, i);
wdenkc8434db2003-03-26 06:55:25 +00001240 return -1;
1241 }
1242 }
wdenk6d3c6d12005-04-03 22:35:21 +00001243#endif /* CONFIG_MTD_NAND_ECC */
1244#endif /* CONFIG_MTD_NAND_VERIFY_WRITE */
wdenkc8434db2003-03-26 06:55:25 +00001245 return 0;
1246}
wdenk359733b2003-03-31 17:27:09 +00001247
wdenkc8434db2003-03-26 06:55:25 +00001248static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
1249 size_t * retlen, const u_char * buf, u_char * ecc_code)
1250{
1251 int i, page, col, cnt, ret = 0;
1252
1253 /* Do not allow write past end of device */
1254 if ((to + len) > nand->totlen) {
wdenk359733b2003-03-31 17:27:09 +00001255 printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
wdenkc8434db2003-03-26 06:55:25 +00001256 return -1;
1257 }
1258
1259 /* Shift to get page */
1260 page = ((int) to) >> nand->page_shift;
1261
1262 /* Get the starting column */
1263 col = to & (nand->oobblock - 1);
1264
1265 /* Initialize return length value */
1266 *retlen = 0;
1267
1268 /* Select the NAND device */
wdenke58b0dc2003-07-27 00:21:01 +00001269#ifdef CONFIG_OMAP1510
1270 archflashwp(0,0);
1271#endif
wdenk6d3c6d12005-04-03 22:35:21 +00001272#ifdef CFG_NAND_WP
1273 NAND_WP_OFF();
1274#endif
1275
wdenke58b0dc2003-07-27 00:21:01 +00001276 NAND_ENABLE_CE(nand); /* set pin low */
wdenkc8434db2003-03-26 06:55:25 +00001277
1278 /* Check the WP bit */
wdenk359733b2003-03-31 17:27:09 +00001279 NanD_Command(nand, NAND_CMD_STATUS);
wdenkc8434db2003-03-26 06:55:25 +00001280 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
wdenk359733b2003-03-31 17:27:09 +00001281 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
wdenkc8434db2003-03-26 06:55:25 +00001282 ret = -1;
1283 goto out;
1284 }
1285
1286 /* Loop until all data is written */
1287 while (*retlen < len) {
1288 /* Invalidate cache, if we write to this page */
1289 if (nand->cache_page == page)
1290 nand->cache_page = -1;
1291
1292 /* Write data into buffer */
wdenk6d3c6d12005-04-03 22:35:21 +00001293 if ((col + len) >= nand->oobblock) {
1294 for (i = col, cnt = 0; i < nand->oobblock; i++, cnt++) {
wdenkc8434db2003-03-26 06:55:25 +00001295 nand->data_buf[i] = buf[(*retlen + cnt)];
wdenk6d3c6d12005-04-03 22:35:21 +00001296 }
1297 } else {
1298 for (i = col, cnt = 0; cnt < (len - *retlen); i++, cnt++) {
wdenkc8434db2003-03-26 06:55:25 +00001299 nand->data_buf[i] = buf[(*retlen + cnt)];
wdenk6d3c6d12005-04-03 22:35:21 +00001300 }
1301 }
wdenkc8434db2003-03-26 06:55:25 +00001302 /* We use the same function for write and writev !) */
1303 ret = nand_write_page (nand, page, col, i, ecc_code);
1304 if (ret)
1305 goto out;
1306
1307 /* Next data start at page boundary */
1308 col = 0;
1309
1310 /* Update written bytes count */
1311 *retlen += cnt;
1312
1313 /* Increment page address */
1314 page++;
1315 }
1316
1317 /* Return happy */
1318 *retlen = len;
1319
1320out:
1321 /* De-select the NAND device */
wdenk359733b2003-03-31 17:27:09 +00001322 NAND_DISABLE_CE(nand); /* set pin high */
wdenke58b0dc2003-07-27 00:21:01 +00001323#ifdef CONFIG_OMAP1510
1324 archflashwp(0,1);
1325#endif
wdenk6d3c6d12005-04-03 22:35:21 +00001326#ifdef CFG_NAND_WP
1327 NAND_WP_ON();
1328#endif
1329
wdenkc8434db2003-03-26 06:55:25 +00001330 return ret;
1331}
1332
wdenkabda5ca2003-05-31 18:35:21 +00001333/* read from the 16 bytes of oob data that correspond to a 512 byte
1334 * page or 2 256-byte pages.
wdenkc8434db2003-03-26 06:55:25 +00001335 */
wdenkc8434db2003-03-26 06:55:25 +00001336static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
wdenkabda5ca2003-05-31 18:35:21 +00001337 size_t * retlen, u_char * buf)
wdenkc8434db2003-03-26 06:55:25 +00001338{
wdenkabda5ca2003-05-31 18:35:21 +00001339 int len256 = 0;
wdenkc8434db2003-03-26 06:55:25 +00001340 struct Nand *mychip;
wdenk359733b2003-03-31 17:27:09 +00001341 int ret = 0;
wdenkc8434db2003-03-26 06:55:25 +00001342
wdenkabda5ca2003-05-31 18:35:21 +00001343 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkc8434db2003-03-26 06:55:25 +00001344
1345 /* update address for 2M x 8bit devices. OOB starts on the second */
1346 /* page to maintain compatibility with nand_read_ecc. */
1347 if (nand->page256) {
1348 if (!(ofs & 0x8))
1349 ofs += 0x100;
1350 else
1351 ofs -= 0x8;
1352 }
1353
wdenkabda5ca2003-05-31 18:35:21 +00001354 NAND_ENABLE_CE(nand); /* set pin low */
wdenkc8434db2003-03-26 06:55:25 +00001355 NanD_Command(nand, NAND_CMD_READOOB);
wdenk6d3c6d12005-04-03 22:35:21 +00001356 if (nand->bus16) {
1357 NanD_Address(nand, ADDR_COLUMN_PAGE,
1358 ((ofs >> nand->page_shift) << nand->page_shift) +
1359 ((ofs & (nand->oobblock - 1)) >> 1));
1360 } else {
1361 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1362 }
wdenkc8434db2003-03-26 06:55:25 +00001363
1364 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1365 /* Note: datasheet says it should automaticaly wrap to the */
1366 /* next OOB block, but it didn't work here. mf. */
1367 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1368 len256 = (ofs | 0x7) + 1 - ofs;
1369 NanD_ReadBuf(nand, buf, len256);
1370
1371 NanD_Command(nand, NAND_CMD_READOOB);
1372 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1373 }
1374
1375 NanD_ReadBuf(nand, &buf[len256], len - len256);
1376
1377 *retlen = len;
1378 /* Reading the full OOB data drops us off of the end of the page,
wdenk57b2d802003-06-27 21:31:46 +00001379 * causing the flash device to go into busy mode, so we need
1380 * to wait until ready 11.4.1 and Toshiba TC58256FT nands */
wdenkc8434db2003-03-26 06:55:25 +00001381
wdenke58b0dc2003-07-27 00:21:01 +00001382 ret = NanD_WaitReady(nand, 1);
wdenk57b2d802003-06-27 21:31:46 +00001383 NAND_DISABLE_CE(nand); /* set pin high */
wdenkc8434db2003-03-26 06:55:25 +00001384
1385 return ret;
1386
1387}
wdenkabda5ca2003-05-31 18:35:21 +00001388
1389/* write to the 16 bytes of oob data that correspond to a 512 byte
1390 * page or 2 256-byte pages.
1391 */
wdenkc8434db2003-03-26 06:55:25 +00001392static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
1393 size_t * retlen, const u_char * buf)
1394{
1395 int len256 = 0;
wdenkabda5ca2003-05-31 18:35:21 +00001396 int i;
wdenkc8434db2003-03-26 06:55:25 +00001397 unsigned long nandptr = nand->IO_ADDR;
1398
1399#ifdef PSYCHO_DEBUG
1400 printf("nand_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1401 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1402 buf[8], buf[9], buf[14],buf[15]);
1403#endif
1404
wdenkabda5ca2003-05-31 18:35:21 +00001405 NAND_ENABLE_CE(nand); /* set pin low to enable chip */
1406
wdenkc8434db2003-03-26 06:55:25 +00001407 /* Reset the chip */
1408 NanD_Command(nand, NAND_CMD_RESET);
1409
1410 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1411 NanD_Command(nand, NAND_CMD_READOOB);
wdenk6d3c6d12005-04-03 22:35:21 +00001412 if (nand->bus16) {
1413 NanD_Address(nand, ADDR_COLUMN_PAGE,
1414 ((ofs >> nand->page_shift) << nand->page_shift) +
1415 ((ofs & (nand->oobblock - 1)) >> 1));
1416 } else {
1417 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1418 }
wdenkc8434db2003-03-26 06:55:25 +00001419
1420 /* update address for 2M x 8bit devices. OOB starts on the second */
1421 /* page to maintain compatibility with nand_read_ecc. */
1422 if (nand->page256) {
1423 if (!(ofs & 0x8))
1424 ofs += 0x100;
1425 else
1426 ofs -= 0x8;
1427 }
1428
1429 /* issue the Serial Data In command to initial the Page Program process */
1430 NanD_Command(nand, NAND_CMD_SEQIN);
wdenk6d3c6d12005-04-03 22:35:21 +00001431 if (nand->bus16) {
1432 NanD_Address(nand, ADDR_COLUMN_PAGE,
1433 ((ofs >> nand->page_shift) << nand->page_shift) +
1434 ((ofs & (nand->oobblock - 1)) >> 1));
1435 } else {
1436 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs);
1437 }
wdenkc8434db2003-03-26 06:55:25 +00001438
1439 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1440 /* Note: datasheet says it should automaticaly wrap to the */
1441 /* next OOB block, but it didn't work here. mf. */
1442 if (nand->page256 && ofs + len > (ofs | 0x7) + 1) {
1443 len256 = (ofs | 0x7) + 1 - ofs;
wdenkabda5ca2003-05-31 18:35:21 +00001444 for (i = 0; i < len256; i++)
1445 WRITE_NAND(buf[i], nandptr);
wdenkc8434db2003-03-26 06:55:25 +00001446
1447 NanD_Command(nand, NAND_CMD_PAGEPROG);
1448 NanD_Command(nand, NAND_CMD_STATUS);
wdenke58b0dc2003-07-27 00:21:01 +00001449#ifdef NAND_NO_RB
1450 { u_char ret_val;
wdenk6d3c6d12005-04-03 22:35:21 +00001451 do {
1452 ret_val = READ_NAND(nandptr); /* wait till ready */
1453 } while ((ret_val & 0x40) != 0x40);
wdenke58b0dc2003-07-27 00:21:01 +00001454 }
1455#endif
wdenkc8434db2003-03-26 06:55:25 +00001456 if (READ_NAND(nandptr) & 1) {
1457 puts ("Error programming oob data\n");
1458 /* There was an error */
wdenkabda5ca2003-05-31 18:35:21 +00001459 NAND_DISABLE_CE(nand); /* set pin high */
wdenkc8434db2003-03-26 06:55:25 +00001460 *retlen = 0;
1461 return -1;
1462 }
1463 NanD_Command(nand, NAND_CMD_SEQIN);
1464 NanD_Address(nand, ADDR_COLUMN_PAGE, ofs & (~0x1ff));
1465 }
1466
wdenk6d3c6d12005-04-03 22:35:21 +00001467 if (nand->bus16) {
1468 for (i = len256; i < len; i += 2) {
1469 WRITE_NAND(buf[i] + (buf[i+1] << 8), nandptr);
1470 }
1471 } else {
1472 for (i = len256; i < len; i++)
1473 WRITE_NAND(buf[i], nandptr);
1474 }
wdenkc8434db2003-03-26 06:55:25 +00001475
1476 NanD_Command(nand, NAND_CMD_PAGEPROG);
1477 NanD_Command(nand, NAND_CMD_STATUS);
wdenke58b0dc2003-07-27 00:21:01 +00001478#ifdef NAND_NO_RB
wdenk6d3c6d12005-04-03 22:35:21 +00001479 { u_char ret_val;
1480 do {
1481 ret_val = READ_NAND(nandptr); /* wait till ready */
1482 } while ((ret_val & 0x40) != 0x40);
wdenke58b0dc2003-07-27 00:21:01 +00001483 }
1484#endif
wdenkc8434db2003-03-26 06:55:25 +00001485 if (READ_NAND(nandptr) & 1) {
1486 puts ("Error programming oob data\n");
1487 /* There was an error */
wdenkabda5ca2003-05-31 18:35:21 +00001488 NAND_DISABLE_CE(nand); /* set pin high */
wdenkc8434db2003-03-26 06:55:25 +00001489 *retlen = 0;
1490 return -1;
1491 }
1492
wdenkabda5ca2003-05-31 18:35:21 +00001493 NAND_DISABLE_CE(nand); /* set pin high */
wdenkc8434db2003-03-26 06:55:25 +00001494 *retlen = len;
1495 return 0;
1496
1497}
wdenkc8434db2003-03-26 06:55:25 +00001498
wdenk79b59372004-06-09 14:58:14 +00001499int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean)
wdenkc8434db2003-03-26 06:55:25 +00001500{
wdenkabda5ca2003-05-31 18:35:21 +00001501 /* This is defined as a structure so it will work on any system
1502 * using native endian jffs2 (the default).
1503 */
1504 static struct jffs2_unknown_node clean_marker = {
1505 JFFS2_MAGIC_BITMASK,
1506 JFFS2_NODETYPE_CLEANMARKER,
1507 8 /* 8 bytes in this node */
1508 };
wdenkc8434db2003-03-26 06:55:25 +00001509 unsigned long nandptr;
1510 struct Nand *mychip;
wdenk8dba0502003-03-31 16:34:49 +00001511 int ret = 0;
wdenkc8434db2003-03-26 06:55:25 +00001512
1513 if (ofs & (nand->erasesize-1) || len & (nand->erasesize-1)) {
1514 printf ("Offset and size must be sector aligned, erasesize = %d\n",
wdenk57b2d802003-06-27 21:31:46 +00001515 (int) nand->erasesize);
wdenkc8434db2003-03-26 06:55:25 +00001516 return -1;
1517 }
1518
1519 nandptr = nand->IO_ADDR;
1520
wdenk8dba0502003-03-31 16:34:49 +00001521 /* Select the NAND device */
wdenke58b0dc2003-07-27 00:21:01 +00001522#ifdef CONFIG_OMAP1510
1523 archflashwp(0,0);
1524#endif
wdenk6d3c6d12005-04-03 22:35:21 +00001525#ifdef CFG_NAND_WP
1526 NAND_WP_OFF();
1527#endif
wdenke58b0dc2003-07-27 00:21:01 +00001528 NAND_ENABLE_CE(nand); /* set pin low */
wdenk8dba0502003-03-31 16:34:49 +00001529
1530 /* Check the WP bit */
1531 NanD_Command(nand, NAND_CMD_STATUS);
1532 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1533 printf ("nand_write_ecc: Device is write protected!!!\n");
1534 ret = -1;
1535 goto out;
1536 }
1537
wdenk359733b2003-03-31 17:27:09 +00001538 /* Check the WP bit */
1539 NanD_Command(nand, NAND_CMD_STATUS);
1540 if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
1541 printf ("%s: Device is write protected!!!\n", __FUNCTION__);
1542 ret = -1;
1543 goto out;
1544 }
1545
wdenkc8434db2003-03-26 06:55:25 +00001546 /* FIXME: Do nand in the background. Use timers or schedule_task() */
1547 while(len) {
wdenk359733b2003-03-31 17:27:09 +00001548 /*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
1549 mychip = &nand->chips[ofs >> nand->chipshift];
wdenkc8434db2003-03-26 06:55:25 +00001550
wdenkabda5ca2003-05-31 18:35:21 +00001551 /* always check for bad block first, genuine bad blocks
1552 * should _never_ be erased.
1553 */
1554 if (ALLOW_ERASE_BAD_DEBUG || !check_block(nand, ofs)) {
1555 /* Select the NAND device */
1556 NAND_ENABLE_CE(nand); /* set pin low */
wdenkc8434db2003-03-26 06:55:25 +00001557
wdenkabda5ca2003-05-31 18:35:21 +00001558 NanD_Command(nand, NAND_CMD_ERASE1);
1559 NanD_Address(nand, ADDR_PAGE, ofs);
1560 NanD_Command(nand, NAND_CMD_ERASE2);
wdenkc8434db2003-03-26 06:55:25 +00001561
wdenkabda5ca2003-05-31 18:35:21 +00001562 NanD_Command(nand, NAND_CMD_STATUS);
1563
wdenke58b0dc2003-07-27 00:21:01 +00001564#ifdef NAND_NO_RB
wdenk6d3c6d12005-04-03 22:35:21 +00001565 { u_char ret_val;
1566 do {
1567 ret_val = READ_NAND(nandptr); /* wait till ready */
1568 } while ((ret_val & 0x40) != 0x40);
wdenke58b0dc2003-07-27 00:21:01 +00001569 }
1570#endif
wdenkabda5ca2003-05-31 18:35:21 +00001571 if (READ_NAND(nandptr) & 1) {
1572 printf ("%s: Error erasing at 0x%lx\n",
1573 __FUNCTION__, (long)ofs);
1574 /* There was an error */
1575 ret = -1;
1576 goto out;
1577 }
1578 if (clean) {
1579 int n; /* return value not used */
1580 int p, l;
1581
1582 /* clean marker position and size depend
1583 * on the page size, since 256 byte pages
1584 * only have 8 bytes of oob data
1585 */
1586 if (nand->page256) {
1587 p = NAND_JFFS2_OOB8_FSDAPOS;
1588 l = NAND_JFFS2_OOB8_FSDALEN;
wdenk6d3c6d12005-04-03 22:35:21 +00001589 } else {
wdenkabda5ca2003-05-31 18:35:21 +00001590 p = NAND_JFFS2_OOB16_FSDAPOS;
1591 l = NAND_JFFS2_OOB16_FSDALEN;
1592 }
1593
1594 ret = nand_write_oob(nand, ofs + p, l, &n,
1595 (u_char *)&clean_marker);
1596 /* quit here if write failed */
1597 if (ret)
1598 goto out;
1599 }
wdenkc8434db2003-03-26 06:55:25 +00001600 }
1601 ofs += nand->erasesize;
1602 len -= nand->erasesize;
1603 }
1604
wdenk8dba0502003-03-31 16:34:49 +00001605out:
1606 /* De-select the NAND device */
1607 NAND_DISABLE_CE(nand); /* set pin high */
wdenke58b0dc2003-07-27 00:21:01 +00001608#ifdef CONFIG_OMAP1510
1609 archflashwp(0,1);
1610#endif
wdenk6d3c6d12005-04-03 22:35:21 +00001611#ifdef CFG_NAND_WP
1612 NAND_WP_ON();
1613#endif
1614
wdenk8dba0502003-03-31 16:34:49 +00001615 return ret;
wdenkc8434db2003-03-26 06:55:25 +00001616}
1617
1618static inline int nandcheck(unsigned long potential, unsigned long physadr)
1619{
wdenkc8434db2003-03-26 06:55:25 +00001620 return 0;
1621}
1622
wdenk934c4f82003-09-11 19:48:06 +00001623unsigned long nand_probe(unsigned long physadr)
wdenkc8434db2003-03-26 06:55:25 +00001624{
1625 struct nand_chip *nand = NULL;
1626 int i = 0, ChipID = 1;
1627
1628#ifdef CONFIG_MTD_NAND_ECC_JFFS2
1629 oob_config.ecc_pos[0] = NAND_JFFS2_OOB_ECCPOS0;
1630 oob_config.ecc_pos[1] = NAND_JFFS2_OOB_ECCPOS1;
1631 oob_config.ecc_pos[2] = NAND_JFFS2_OOB_ECCPOS2;
1632 oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
1633 oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
1634 oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
wdenkc8434db2003-03-26 06:55:25 +00001635 oob_config.eccvalid_pos = 4;
1636#else
1637 oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
1638 oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
1639 oob_config.ecc_pos[2] = NAND_NOOB_ECCPOS2;
1640 oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
1641 oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
1642 oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
wdenkc8434db2003-03-26 06:55:25 +00001643 oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
1644#endif
wdenkabda5ca2003-05-31 18:35:21 +00001645 oob_config.badblock_pos = 5;
wdenkc8434db2003-03-26 06:55:25 +00001646
1647 for (i=0; i<CFG_MAX_NAND_DEVICE; i++) {
1648 if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) {
wdenk934c4f82003-09-11 19:48:06 +00001649 nand = &nand_dev_desc[i];
wdenkc8434db2003-03-26 06:55:25 +00001650 break;
1651 }
1652 }
wdenk934c4f82003-09-11 19:48:06 +00001653 if (!nand)
1654 return (0);
wdenkc8434db2003-03-26 06:55:25 +00001655
wdenk359733b2003-03-31 17:27:09 +00001656 memset((char *)nand, 0, sizeof(struct nand_chip));
wdenkc8434db2003-03-26 06:55:25 +00001657
wdenk359733b2003-03-31 17:27:09 +00001658 nand->IO_ADDR = physadr;
wdenkabda5ca2003-05-31 18:35:21 +00001659 nand->cache_page = -1; /* init the cache page */
wdenk359733b2003-03-31 17:27:09 +00001660 NanD_ScanChips(nand);
wdenkabda5ca2003-05-31 18:35:21 +00001661
1662 if (nand->totlen == 0) {
1663 /* no chips found, clean up and quit */
1664 memset((char *)nand, 0, sizeof(struct nand_chip));
1665 nand->ChipID = NAND_ChipID_UNKNOWN;
wdenk934c4f82003-09-11 19:48:06 +00001666 return (0);
wdenkabda5ca2003-05-31 18:35:21 +00001667 }
1668
1669 nand->ChipID = ChipID;
1670 if (curr_device == -1)
1671 curr_device = i;
1672
wdenk359733b2003-03-31 17:27:09 +00001673 nand->data_buf = malloc (nand->oobblock + nand->oobsize);
1674 if (!nand->data_buf) {
1675 puts ("Cannot allocate memory for data structures.\n");
wdenk934c4f82003-09-11 19:48:06 +00001676 return (0);
wdenk359733b2003-03-31 17:27:09 +00001677 }
wdenk934c4f82003-09-11 19:48:06 +00001678
1679 return (nand->totlen);
wdenkc8434db2003-03-26 06:55:25 +00001680}
1681
1682#ifdef CONFIG_MTD_NAND_ECC
1683/*
1684 * Pre-calculated 256-way 1 byte column parity
1685 */
1686static const u_char nand_ecc_precalc_table[] = {
wdenk6d3c6d12005-04-03 22:35:21 +00001687 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
1688 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
1689 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
1690 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1691 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
1692 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1693 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
1694 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1695 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
1696 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1697 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
1698 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1699 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
1700 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1701 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
1702 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1703 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
1704 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
1705 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
1706 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
1707 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
1708 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
1709 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
1710 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
1711 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
1712 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
1713 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
1714 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
1715 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
1716 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
1717 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
1718 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
wdenkc8434db2003-03-26 06:55:25 +00001719};
1720
1721
1722/*
1723 * Creates non-inverted ECC code from line parity
1724 */
1725static void nand_trans_result(u_char reg2, u_char reg3,
1726 u_char *ecc_code)
1727{
1728 u_char a, b, i, tmp1, tmp2;
1729
1730 /* Initialize variables */
1731 a = b = 0x80;
1732 tmp1 = tmp2 = 0;
1733
1734 /* Calculate first ECC byte */
1735 for (i = 0; i < 4; i++) {
1736 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
1737 tmp1 |= b;
1738 b >>= 1;
1739 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
1740 tmp1 |= b;
1741 b >>= 1;
1742 a >>= 1;
1743 }
1744
1745 /* Calculate second ECC byte */
1746 b = 0x80;
1747 for (i = 0; i < 4; i++) {
1748 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
1749 tmp2 |= b;
1750 b >>= 1;
1751 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
1752 tmp2 |= b;
1753 b >>= 1;
1754 a >>= 1;
1755 }
1756
1757 /* Store two of the ECC bytes */
1758 ecc_code[0] = tmp1;
1759 ecc_code[1] = tmp2;
1760}
1761
1762/*
1763 * Calculate 3 byte ECC code for 256 byte block
1764 */
1765static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
1766{
wdenkabda5ca2003-05-31 18:35:21 +00001767 u_char idx, reg1, reg3;
wdenkc8434db2003-03-26 06:55:25 +00001768 int j;
1769
1770 /* Initialize variables */
wdenkabda5ca2003-05-31 18:35:21 +00001771 reg1 = reg3 = 0;
wdenkc8434db2003-03-26 06:55:25 +00001772 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
1773
1774 /* Build up column parity */
1775 for(j = 0; j < 256; j++) {
1776
1777 /* Get CP0 - CP5 from table */
1778 idx = nand_ecc_precalc_table[dat[j]];
wdenkabda5ca2003-05-31 18:35:21 +00001779 reg1 ^= idx;
wdenkc8434db2003-03-26 06:55:25 +00001780
1781 /* All bit XOR = 1 ? */
1782 if (idx & 0x40) {
1783 reg3 ^= (u_char) j;
wdenkc8434db2003-03-26 06:55:25 +00001784 }
1785 }
1786
1787 /* Create non-inverted ECC code from line parity */
wdenkabda5ca2003-05-31 18:35:21 +00001788 nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
wdenkc8434db2003-03-26 06:55:25 +00001789
1790 /* Calculate final ECC code */
1791 ecc_code[0] = ~ecc_code[0];
1792 ecc_code[1] = ~ecc_code[1];
1793 ecc_code[2] = ((~reg1) << 2) | 0x03;
1794}
1795
1796/*
1797 * Detect and correct a 1 bit error for 256 byte block
1798 */
1799static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
1800{
1801 u_char a, b, c, d1, d2, d3, add, bit, i;
1802
1803 /* Do error detection */
1804 d1 = calc_ecc[0] ^ read_ecc[0];
1805 d2 = calc_ecc[1] ^ read_ecc[1];
1806 d3 = calc_ecc[2] ^ read_ecc[2];
1807
1808 if ((d1 | d2 | d3) == 0) {
1809 /* No errors */
1810 return 0;
wdenk6d3c6d12005-04-03 22:35:21 +00001811 } else {
wdenkc8434db2003-03-26 06:55:25 +00001812 a = (d1 ^ (d1 >> 1)) & 0x55;
1813 b = (d2 ^ (d2 >> 1)) & 0x55;
1814 c = (d3 ^ (d3 >> 1)) & 0x54;
1815
1816 /* Found and will correct single bit error in the data */
1817 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
1818 c = 0x80;
1819 add = 0;
1820 a = 0x80;
1821 for (i=0; i<4; i++) {
1822 if (d1 & c)
1823 add |= a;
1824 c >>= 2;
1825 a >>= 1;
1826 }
1827 c = 0x80;
1828 for (i=0; i<4; i++) {
1829 if (d2 & c)
1830 add |= a;
1831 c >>= 2;
1832 a >>= 1;
1833 }
1834 bit = 0;
1835 b = 0x04;
1836 c = 0x80;
1837 for (i=0; i<3; i++) {
1838 if (d3 & c)
1839 bit |= b;
1840 c >>= 2;
1841 b >>= 1;
1842 }
1843 b = 0x01;
1844 a = dat[add];
1845 a ^= (b << bit);
1846 dat[add] = a;
1847 return 1;
1848 }
1849 else {
1850 i = 0;
1851 while (d1) {
1852 if (d1 & 0x01)
1853 ++i;
1854 d1 >>= 1;
1855 }
1856 while (d2) {
1857 if (d2 & 0x01)
1858 ++i;
1859 d2 >>= 1;
1860 }
1861 while (d3) {
1862 if (d3 & 0x01)
1863 ++i;
1864 d3 >>= 1;
1865 }
1866 if (i == 1) {
1867 /* ECC Code Error Correction */
1868 read_ecc[0] = calc_ecc[0];
1869 read_ecc[1] = calc_ecc[1];
1870 read_ecc[2] = calc_ecc[2];
1871 return 2;
1872 }
1873 else {
1874 /* Uncorrectable Error */
1875 return -1;
1876 }
1877 }
1878 }
1879
1880 /* Should never happen */
1881 return -1;
1882}
wdenke58b0dc2003-07-27 00:21:01 +00001883
wdenkc8434db2003-03-26 06:55:25 +00001884#endif
wdenk8886a662004-04-18 19:43:36 +00001885
1886#ifdef CONFIG_JFFS2_NAND
1887
1888int read_jffs2_nand(size_t start, size_t len,
1889 size_t * retlen, u_char * buf, int nanddev)
1890{
1891 return nand_rw(nand_dev_desc + nanddev, NANDRW_READ | NANDRW_JFFS2,
1892 start, len, retlen, buf);
1893}
1894
1895#endif /* CONFIG_JFFS2_NAND */
1896
1897
wdenkc8434db2003-03-26 06:55:25 +00001898#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */