blob: 37b7325be6a21d58c910e3a8ff4b720574acd91a [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * Driver for Disk-On-Chip 2000 and Millennium
3 * (c) 1999 Machine Vision Holdings, Inc.
4 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
5 *
6 * $Id: doc2000.c,v 1.46 2001/10/02 15:05:13 dwmw2 Exp $
7 */
8
9#include <common.h>
10#include <config.h>
11#include <command.h>
12#include <malloc.h>
13#include <asm/io.h>
14
15#ifdef CONFIG_SHOW_BOOT_PROGRESS
16# include <status_led.h>
17# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
18#else
19# define SHOW_BOOT_PROGRESS(arg)
20#endif
21
22#if (CONFIG_COMMANDS & CFG_CMD_DOC)
23
wdenkac6dbb82003-03-26 11:42:53 +000024#include <linux/mtd/nftl.h>
Bartlomiej Siekaaddb2e12006-03-05 18:57:33 +010025#include <linux/mtd/nand_legacy.h>
wdenkc6097192002-11-03 00:24:07 +000026#include <linux/mtd/nand_ids.h>
Bartlomiej Siekaaddb2e12006-03-05 18:57:33 +010027
wdenkc6097192002-11-03 00:24:07 +000028#include <linux/mtd/doc2000.h>
29#include <linux/mtd/nftl.h>
30
31#ifdef CFG_DOC_SUPPORT_2000
32#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
33#else
34#define DoC_is_2000(doc) (0)
35#endif
36
37#ifdef CFG_DOC_SUPPORT_MILLENNIUM
38#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
39#else
40#define DoC_is_Millennium(doc) (0)
41#endif
42
43/* CFG_DOC_PASSIVE_PROBE:
44 In order to ensure that the BIOS checksum is correct at boot time, and
45 hence that the onboard BIOS extension gets executed, the DiskOnChip
46 goes into reset mode when it is read sequentially: all registers
47 return 0xff until the chip is woken up again by writing to the
48 DOCControl register.
49
50 Unfortunately, this means that the probe for the DiskOnChip is unsafe,
51 because one of the first things it does is write to where it thinks
52 the DOCControl register should be - which may well be shared memory
53 for another device. I've had machines which lock up when this is
54 attempted. Hence the possibility to do a passive probe, which will fail
55 to detect a chip in reset mode, but is at least guaranteed not to lock
56 the machine.
57
58 If you have this problem, uncomment the following line:
59#define CFG_DOC_PASSIVE_PROBE
60*/
61
62#undef DOC_DEBUG
63#undef ECC_DEBUG
64#undef PSYCHO_DEBUG
65#undef NFTL_DEBUG
66
67static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE];
68
69/* Current DOC Device */
70static int curr_device = -1;
71
72/* ------------------------------------------------------------------------- */
73
74int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
75{
76 int rcode = 0;
77
78 switch (argc) {
79 case 0:
80 case 1:
81 printf ("Usage:\n%s\n", cmdtp->usage);
82 return 1;
83 case 2:
wdenk8bde7f72003-06-27 21:31:46 +000084 if (strcmp(argv[1],"info") == 0) {
wdenkc6097192002-11-03 00:24:07 +000085 int i;
86
87 putc ('\n');
88
89 for (i=0; i<CFG_MAX_DOC_DEVICE; ++i) {
90 if(doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN)
91 continue; /* list only known devices */
92 printf ("Device %d: ", i);
93 doc_print(&doc_dev_desc[i]);
94 }
95 return 0;
96
97 } else if (strcmp(argv[1],"device") == 0) {
98 if ((curr_device < 0) || (curr_device >= CFG_MAX_DOC_DEVICE)) {
99 puts ("\nno devices available\n");
100 return 1;
101 }
102 printf ("\nDevice %d: ", curr_device);
103 doc_print(&doc_dev_desc[curr_device]);
104 return 0;
105 }
106 printf ("Usage:\n%s\n", cmdtp->usage);
107 return 1;
108 case 3:
109 if (strcmp(argv[1],"device") == 0) {
110 int dev = (int)simple_strtoul(argv[2], NULL, 10);
111
112 printf ("\nDevice %d: ", dev);
113 if (dev >= CFG_MAX_DOC_DEVICE) {
114 puts ("unknown device\n");
115 return 1;
116 }
117 doc_print(&doc_dev_desc[dev]);
118 /*doc_print (dev);*/
119
120 if (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN) {
121 return 1;
122 }
123
124 curr_device = dev;
125
126 puts ("... is now current device\n");
127
128 return 0;
129 }
130
131 printf ("Usage:\n%s\n", cmdtp->usage);
132 return 1;
133 default:
134 /* at least 4 args */
135
136 if (strcmp(argv[1],"read") == 0 || strcmp(argv[1],"write") == 0) {
137 ulong addr = simple_strtoul(argv[2], NULL, 16);
138 ulong off = simple_strtoul(argv[3], NULL, 16);
139 ulong size = simple_strtoul(argv[4], NULL, 16);
140 int cmd = (strcmp(argv[1],"read") == 0);
141 int ret, total;
142
143 printf ("\nDOC %s: device %d offset %ld, size %ld ... ",
144 cmd ? "read" : "write", curr_device, off, size);
145
146 ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200147 (size_t *)&total, (u_char*)addr);
wdenkc6097192002-11-03 00:24:07 +0000148
149 printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write",
150 ret ? "ERROR" : "OK");
151
152 return ret;
153 } else if (strcmp(argv[1],"erase") == 0) {
154 ulong off = simple_strtoul(argv[2], NULL, 16);
155 ulong size = simple_strtoul(argv[3], NULL, 16);
156 int ret;
157
158 printf ("\nDOC erase: device %d offset %ld, size %ld ... ",
159 curr_device, off, size);
160
161 ret = doc_erase (doc_dev_desc + curr_device, off, size);
162
163 printf("%s\n", ret ? "ERROR" : "OK");
164
165 return ret;
166 } else {
167 printf ("Usage:\n%s\n", cmdtp->usage);
168 rcode = 1;
169 }
170
171 return rcode;
172 }
173}
wdenk0d498392003-07-01 21:06:45 +0000174U_BOOT_CMD(
175 doc, 5, 1, do_doc,
wdenk8bde7f72003-06-27 21:31:46 +0000176 "doc - Disk-On-Chip sub-system\n",
177 "info - show available DOC devices\n"
178 "doc device [dev] - show or set current device\n"
179 "doc read addr off size\n"
180 "doc write addr off size - read/write `size'"
181 " bytes starting at offset `off'\n"
182 " to/from memory address `addr'\n"
183 "doc erase off size - erase `size' bytes of DOC from offset `off'\n"
184);
wdenkc6097192002-11-03 00:24:07 +0000185
186int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
187{
188 char *boot_device = NULL;
189 char *ep;
190 int dev;
191 ulong cnt;
192 ulong addr;
193 ulong offset = 0;
194 image_header_t *hdr;
195 int rcode = 0;
196
197 switch (argc) {
198 case 1:
199 addr = CFG_LOAD_ADDR;
200 boot_device = getenv ("bootdevice");
201 break;
202 case 2:
203 addr = simple_strtoul(argv[1], NULL, 16);
204 boot_device = getenv ("bootdevice");
205 break;
206 case 3:
207 addr = simple_strtoul(argv[1], NULL, 16);
208 boot_device = argv[2];
209 break;
210 case 4:
211 addr = simple_strtoul(argv[1], NULL, 16);
212 boot_device = argv[2];
213 offset = simple_strtoul(argv[3], NULL, 16);
214 break;
215 default:
216 printf ("Usage:\n%s\n", cmdtp->usage);
217 SHOW_BOOT_PROGRESS (-1);
218 return 1;
219 }
220
221 if (!boot_device) {
222 puts ("\n** No boot device **\n");
223 SHOW_BOOT_PROGRESS (-1);
224 return 1;
225 }
226
227 dev = simple_strtoul(boot_device, &ep, 16);
228
229 if ((dev >= CFG_MAX_DOC_DEVICE) ||
230 (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) {
231 printf ("\n** Device %d not available\n", dev);
232 SHOW_BOOT_PROGRESS (-1);
233 return 1;
234 }
235
236 printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n",
237 dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr,
238 offset);
239
240 if (doc_rw (doc_dev_desc + dev, 1, offset,
241 SECTORSIZE, NULL, (u_char *)addr)) {
242 printf ("** Read error on %d\n", dev);
243 SHOW_BOOT_PROGRESS (-1);
244 return 1;
245 }
246
247 hdr = (image_header_t *)addr;
248
249 if (hdr->ih_magic == IH_MAGIC) {
250
251 print_image_hdr (hdr);
252
Wolfgang Denkdc013d42006-03-12 01:59:35 +0100253 cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
wdenkc6097192002-11-03 00:24:07 +0000254 cnt -= SECTORSIZE;
255 } else {
256 puts ("\n** Bad Magic Number **\n");
257 SHOW_BOOT_PROGRESS (-1);
258 return 1;
259 }
260
261 if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
262 NULL, (u_char *)(addr+SECTORSIZE))) {
263 printf ("** Read error on %d\n", dev);
264 SHOW_BOOT_PROGRESS (-1);
265 return 1;
266 }
267
268 /* Loading ok, update default load address */
269
270 load_addr = addr;
271
272 /* Check if we should attempt an auto-start */
273 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
274 char *local_args[2];
275 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
276
277 local_args[0] = argv[0];
278 local_args[1] = NULL;
279
280 printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
281
282 do_bootm (cmdtp, 0, 1, local_args);
283 rcode = 1;
284 }
285 return rcode;
286}
287
wdenk0d498392003-07-01 21:06:45 +0000288U_BOOT_CMD(
289 docboot, 4, 1, do_docboot,
wdenk8bde7f72003-06-27 21:31:46 +0000290 "docboot - boot from DOC device\n",
291 "loadAddr dev\n"
292);
293
wdenkc6097192002-11-03 00:24:07 +0000294int doc_rw (struct DiskOnChip* this, int cmd,
295 loff_t from, size_t len,
296 size_t * retlen, u_char * buf)
297{
298 int noecc, ret = 0, n, total = 0;
299 char eccbuf[6];
300
301 while(len) {
302 /* The ECC will not be calculated correctly if
303 less than 512 is written or read */
304 noecc = (from != (from | 0x1ff) + 1) || (len < 0x200);
305
306 if (cmd)
307 ret = doc_read_ecc(this, from, len,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200308 (size_t *)&n, (u_char*)buf,
309 noecc ? (uchar *)NULL : (uchar *)eccbuf);
wdenkc6097192002-11-03 00:24:07 +0000310 else
311 ret = doc_write_ecc(this, from, len,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200312 (size_t *)&n, (u_char*)buf,
313 noecc ? (uchar *)NULL : (uchar *)eccbuf);
wdenkc6097192002-11-03 00:24:07 +0000314
315 if (ret)
316 break;
317
318 from += n;
319 buf += n;
320 total += n;
321 len -= n;
322 }
323
324 if (retlen)
325 *retlen = total;
326
327 return ret;
328}
329
330void doc_print(struct DiskOnChip *this) {
331 printf("%s at 0x%lX,\n"
332 "\t %d chip%s %s, size %d MB, \n"
333 "\t total size %ld MB, sector size %ld kB\n",
334 this->name, this->physadr, this->numchips,
335 this->numchips>1 ? "s" : "", this->chips_name,
336 1 << (this->chipshift - 20),
337 this->totlen >> 20, this->erasesize >> 10);
338
339 if (this->nftl_found) {
340 struct NFTLrecord *nftl = &this->nftl;
341 unsigned long bin_size, flash_size;
342
343 bin_size = nftl->nb_boot_blocks * this->erasesize;
344 flash_size = (nftl->nb_blocks - nftl->nb_boot_blocks) * this->erasesize;
345
346 printf("\t NFTL boot record:\n"
347 "\t Binary partition: size %ld%s\n"
348 "\t Flash disk partition: size %ld%s, offset 0x%lx\n",
349 bin_size > (1 << 20) ? bin_size >> 20 : bin_size >> 10,
350 bin_size > (1 << 20) ? "MB" : "kB",
351 flash_size > (1 << 20) ? flash_size >> 20 : flash_size >> 10,
352 flash_size > (1 << 20) ? "MB" : "kB", bin_size);
353 } else {
354 puts ("\t No NFTL boot record found.\n");
355 }
356}
357
358/* ------------------------------------------------------------------------- */
359
360/* This function is needed to avoid calls of the __ashrdi3 function. */
361static int shr(int val, int shift) {
362 return val >> shift;
363}
364
365/* Perform the required delay cycles by reading from the appropriate register */
366static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
367{
368 volatile char dummy;
369 int i;
370
371 for (i = 0; i < cycles; i++) {
372 if (DoC_is_Millennium(doc))
373 dummy = ReadDOC(doc->virtadr, NOP);
374 else
375 dummy = ReadDOC(doc->virtadr, DOCStatus);
376 }
377
378}
379
380/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
381static int _DoC_WaitReady(struct DiskOnChip *doc)
382{
383 unsigned long docptr = doc->virtadr;
384 unsigned long start = get_timer(0);
385
386#ifdef PSYCHO_DEBUG
387 puts ("_DoC_WaitReady called for out-of-line wait\n");
388#endif
389
390 /* Out-of-line routine to wait for chip response */
391 while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
392#ifdef CFG_DOC_SHORT_TIMEOUT
393 /* it seems that after a certain time the DoC deasserts
394 * the CDSN_CTRL_FR_B although it is not ready...
395 * using a short timout solve this (timer increments every ms) */
396 if (get_timer(start) > 10) {
397 return DOC_ETIMEOUT;
398 }
399#else
400 if (get_timer(start) > 10 * 1000) {
401 puts ("_DoC_WaitReady timed out.\n");
402 return DOC_ETIMEOUT;
403 }
404#endif
405 udelay(1);
wdenk8bde7f72003-06-27 21:31:46 +0000406 }
wdenkc6097192002-11-03 00:24:07 +0000407
408 return 0;
409}
410
411static int DoC_WaitReady(struct DiskOnChip *doc)
412{
413 unsigned long docptr = doc->virtadr;
414 /* This is inline, to optimise the common case, where it's ready instantly */
415 int ret = 0;
416
417 /* 4 read form NOP register should be issued in prior to the read from CDSNControl
418 see Software Requirement 11.4 item 2. */
419 DoC_Delay(doc, 4);
420
421 if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
422 /* Call the out-of-line routine to wait */
423 ret = _DoC_WaitReady(doc);
424
425 /* issue 2 read from NOP register after reading from CDSNControl register
426 see Software Requirement 11.4 item 2. */
427 DoC_Delay(doc, 2);
428
429 return ret;
430}
431
432/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
433 bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
434 required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
435
436static inline int DoC_Command(struct DiskOnChip *doc, unsigned char command,
437 unsigned char xtraflags)
438{
439 unsigned long docptr = doc->virtadr;
440
441 if (DoC_is_2000(doc))
442 xtraflags |= CDSN_CTRL_FLASH_IO;
443
444 /* Assert the CLE (Command Latch Enable) line to the flash chip */
445 WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
446 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
447
448 if (DoC_is_Millennium(doc))
449 WriteDOC(command, docptr, CDSNSlowIO);
450
451 /* Send the command */
452 WriteDOC_(command, docptr, doc->ioreg);
453
454 /* Lower the CLE line */
455 WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
456 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
457
458 /* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
459 return DoC_WaitReady(doc);
460}
461
462/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
463 bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
464 required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
465
466static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
467 unsigned char xtraflags1, unsigned char xtraflags2)
468{
469 unsigned long docptr;
470 int i;
471
472 docptr = doc->virtadr;
473
474 if (DoC_is_2000(doc))
475 xtraflags1 |= CDSN_CTRL_FLASH_IO;
476
477 /* Assert the ALE (Address Latch Enable) line to the flash chip */
478 WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
479
480 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
481
482 /* Send the address */
483 /* Devices with 256-byte page are addressed as:
484 Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
485 * there is no device on the market with page256
486 and more than 24 bits.
487 Devices with 512-byte page are addressed as:
488 Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
489 * 25-31 is sent only if the chip support it.
490 * bit 8 changes the read command to be sent
491 (NAND_CMD_READ0 or NAND_CMD_READ1).
492 */
493
494 if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
495 if (DoC_is_Millennium(doc))
496 WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
497 WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
498 }
499
500 if (doc->page256) {
501 ofs = ofs >> 8;
502 } else {
503 ofs = ofs >> 9;
504 }
505
506 if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
507 for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
508 if (DoC_is_Millennium(doc))
509 WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
510 WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
511 }
512 }
513
514 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
515
516 /* FIXME: The SlowIO's for millennium could be replaced by
517 a single WritePipeTerm here. mf. */
518
519 /* Lower the ALE line */
520 WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
521 CDSNControl);
522
523 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
524
525 /* Wait for the chip to respond - Software requirement 11.4.1 */
526 return DoC_WaitReady(doc);
527}
528
wdenk7152b1d2003-09-05 23:19:14 +0000529/* Read a buffer from DoC, taking care of Millennium oddities */
wdenkc6097192002-11-03 00:24:07 +0000530static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
531{
532 volatile int dummy;
533 int modulus = 0xffff;
534 unsigned long docptr;
535 int i;
536
537 docptr = doc->virtadr;
538
539 if (len <= 0)
540 return;
541
542 if (DoC_is_Millennium(doc)) {
543 /* Read the data via the internal pipeline through CDSN IO register,
544 see Pipelined Read Operations 11.3 */
545 dummy = ReadDOC(docptr, ReadPipeInit);
546
547 /* Millennium should use the LastDataRead register - Pipeline Reads */
548 len--;
549
550 /* This is needed for correctly ECC calculation */
551 modulus = 0xff;
552 }
553
554 for (i = 0; i < len; i++)
555 buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
556
557 if (DoC_is_Millennium(doc)) {
558 buf[i] = ReadDOC(docptr, LastDataRead);
559 }
560}
561
wdenk7152b1d2003-09-05 23:19:14 +0000562/* Write a buffer to DoC, taking care of Millennium oddities */
wdenkc6097192002-11-03 00:24:07 +0000563static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
564{
565 unsigned long docptr;
566 int i;
567
568 docptr = doc->virtadr;
569
570 if (len <= 0)
571 return;
572
573 for (i = 0; i < len; i++)
574 WriteDOC_(buf[i], docptr, doc->ioreg + i);
575
576 if (DoC_is_Millennium(doc)) {
577 WriteDOC(0x00, docptr, WritePipeTerm);
578 }
579}
580
581
582/* DoC_SelectChip: Select a given flash chip within the current floor */
583
584static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
585{
586 unsigned long docptr = doc->virtadr;
587
588 /* Software requirement 11.4.4 before writing DeviceSelect */
589 /* Deassert the CE line to eliminate glitches on the FCE# outputs */
590 WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
591 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
592
593 /* Select the individual flash chip requested */
594 WriteDOC(chip, docptr, CDSNDeviceSelect);
595 DoC_Delay(doc, 4);
596
597 /* Reassert the CE line */
598 WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
599 CDSNControl);
600 DoC_Delay(doc, 4); /* Software requirement 11.4.3 for Millennium */
601
602 /* Wait for it to be ready */
603 return DoC_WaitReady(doc);
604}
605
606/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
607
608static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
609{
610 unsigned long docptr = doc->virtadr;
611
612 /* Select the floor (bank) of chips required */
613 WriteDOC(floor, docptr, FloorSelect);
614
615 /* Wait for the chip to be ready */
616 return DoC_WaitReady(doc);
617}
618
619/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
620
621static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
622{
623 int mfr, id, i;
624 volatile char dummy;
625
626 /* Page in the required floor/chip */
627 DoC_SelectFloor(doc, floor);
628 DoC_SelectChip(doc, chip);
629
630 /* Reset the chip */
631 if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
632#ifdef DOC_DEBUG
633 printf("DoC_Command (reset) for %d,%d returned true\n",
634 floor, chip);
635#endif
636 return 0;
637 }
638
639
640 /* Read the NAND chip ID: 1. Send ReadID command */
641 if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
642#ifdef DOC_DEBUG
643 printf("DoC_Command (ReadID) for %d,%d returned true\n",
644 floor, chip);
645#endif
646 return 0;
647 }
648
649 /* Read the NAND chip ID: 2. Send address byte zero */
650 DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
651
652 /* Read the manufacturer and device id codes from the device */
653
654 /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
655 dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
656 DoC_Delay(doc, 2);
657 mfr = ReadDOC_(doc->virtadr, doc->ioreg);
658
659 /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
660 dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
661 DoC_Delay(doc, 2);
662 id = ReadDOC_(doc->virtadr, doc->ioreg);
663
664 /* No response - return failure */
665 if (mfr == 0xff || mfr == 0)
666 return 0;
667
668 /* Check it's the same as the first chip we identified.
669 * M-Systems say that any given DiskOnChip device should only
670 * contain _one_ type of flash part, although that's not a
671 * hardware restriction. */
672 if (doc->mfr) {
673 if (doc->mfr == mfr && doc->id == id)
674 return 1; /* This is another the same the first */
675 else
676 printf("Flash chip at floor %d, chip %d is different:\n",
677 floor, chip);
678 }
679
680 /* Print and store the manufacturer and ID codes. */
681 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
682 if (mfr == nand_flash_ids[i].manufacture_id &&
683 id == nand_flash_ids[i].model_id) {
684#ifdef DOC_DEBUG
685 printf("Flash chip found: Manufacturer ID: %2.2X, "
686 "Chip ID: %2.2X (%s)\n", mfr, id,
687 nand_flash_ids[i].name);
688#endif
689 if (!doc->mfr) {
690 doc->mfr = mfr;
691 doc->id = id;
692 doc->chipshift =
693 nand_flash_ids[i].chipshift;
694 doc->page256 = nand_flash_ids[i].page256;
695 doc->pageadrlen =
696 nand_flash_ids[i].pageadrlen;
697 doc->erasesize =
698 nand_flash_ids[i].erasesize;
699 doc->chips_name =
700 nand_flash_ids[i].name;
701 return 1;
702 }
703 return 0;
704 }
705 }
706
707
708#ifdef DOC_DEBUG
709 /* We haven't fully identified the chip. Print as much as we know. */
710 printf("Unknown flash chip found: %2.2X %2.2X\n",
711 id, mfr);
712#endif
713
714 return 0;
715}
716
717/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
718
719static void DoC_ScanChips(struct DiskOnChip *this)
720{
721 int floor, chip;
722 int numchips[MAX_FLOORS];
723 int maxchips = MAX_CHIPS;
724 int ret = 1;
725
726 this->numchips = 0;
727 this->mfr = 0;
728 this->id = 0;
729
730 if (DoC_is_Millennium(this))
731 maxchips = MAX_CHIPS_MIL;
732
733 /* For each floor, find the number of valid chips it contains */
734 for (floor = 0; floor < MAX_FLOORS; floor++) {
735 ret = 1;
736 numchips[floor] = 0;
737 for (chip = 0; chip < maxchips && ret != 0; chip++) {
738
739 ret = DoC_IdentChip(this, floor, chip);
740 if (ret) {
741 numchips[floor]++;
742 this->numchips++;
743 }
744 }
745 }
746
747 /* If there are none at all that we recognise, bail */
748 if (!this->numchips) {
749 puts ("No flash chips recognised.\n");
750 return;
751 }
752
753 /* Allocate an array to hold the information for each chip */
754 this->chips = malloc(sizeof(struct Nand) * this->numchips);
755 if (!this->chips) {
756 puts ("No memory for allocating chip info structures\n");
757 return;
758 }
759
760 ret = 0;
761
762 /* Fill out the chip array with {floor, chipno} for each
763 * detected chip in the device. */
764 for (floor = 0; floor < MAX_FLOORS; floor++) {
765 for (chip = 0; chip < numchips[floor]; chip++) {
766 this->chips[ret].floor = floor;
767 this->chips[ret].chip = chip;
768 this->chips[ret].curadr = 0;
769 this->chips[ret].curmode = 0x50;
770 ret++;
771 }
772 }
773
774 /* Calculate and print the total size of the device */
775 this->totlen = this->numchips * (1 << this->chipshift);
776
777#ifdef DOC_DEBUG
778 printf("%d flash chips found. Total DiskOnChip size: %ld MB\n",
779 this->numchips, this->totlen >> 20);
780#endif
781}
782
783/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
784 * various device information of the NFTL partition and Bad Unit Table. Update
785 * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
786 * is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
787 */
788static int find_boot_record(struct NFTLrecord *nftl)
789{
790 struct nftl_uci1 h1;
791 struct nftl_oob oob;
792 unsigned int block, boot_record_count = 0;
793 int retlen;
794 u8 buf[SECTORSIZE];
795 struct NFTLMediaHeader *mh = &nftl->MediaHdr;
796 unsigned int i;
797
798 nftl->MediaUnit = BLOCK_NIL;
799 nftl->SpareMediaUnit = BLOCK_NIL;
800
801 /* search for a valid boot record */
802 for (block = 0; block < nftl->nb_blocks; block++) {
803 int ret;
804
805 /* Check for ANAND header first. Then can whinge if it's found but later
806 checks fail */
807 if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200808 (size_t *)&retlen, buf, NULL))) {
wdenkc6097192002-11-03 00:24:07 +0000809 static int warncount = 5;
810
811 if (warncount) {
812 printf("Block read at 0x%x failed\n", block * nftl->EraseSize);
813 if (!--warncount)
814 puts ("Further failures for this block will not be printed\n");
815 }
816 continue;
817 }
818
819 if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
820 /* ANAND\0 not found. Continue */
821#ifdef PSYCHO_DEBUG
822 printf("ANAND header not found at 0x%x\n", block * nftl->EraseSize);
823#endif
824 continue;
825 }
826
827#ifdef NFTL_DEBUG
828 printf("ANAND header found at 0x%x\n", block * nftl->EraseSize);
829#endif
830
831 /* To be safer with BIOS, also use erase mark as discriminant */
832 if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200833 8, (size_t *)&retlen, (uchar *)&h1) < 0)) {
wdenkc6097192002-11-03 00:24:07 +0000834#ifdef NFTL_DEBUG
835 printf("ANAND header found at 0x%x, but OOB data read failed\n",
836 block * nftl->EraseSize);
837#endif
838 continue;
839 }
840
841 /* OK, we like it. */
842
843 if (boot_record_count) {
844 /* We've already processed one. So we just check if
845 this one is the same as the first one we found */
846 if (memcmp(mh, buf, sizeof(struct NFTLMediaHeader))) {
847#ifdef NFTL_DEBUG
848 printf("NFTL Media Headers at 0x%x and 0x%x disagree.\n",
849 nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
850#endif
851 /* if (debug) Print both side by side */
852 return -1;
853 }
854 if (boot_record_count == 1)
855 nftl->SpareMediaUnit = block;
856
857 boot_record_count++;
858 continue;
859 }
860
861 /* This is the first we've seen. Copy the media header structure into place */
862 memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
863
864 /* Do some sanity checks on it */
wdenk7205e402003-09-10 22:30:53 +0000865 if (mh->UnitSizeFactor == 0) {
866#ifdef NFTL_DEBUG
867 puts ("UnitSizeFactor 0x00 detected.\n"
868 "This violates the spec but we think we know what it means...\n");
869#endif
870 } else if (mh->UnitSizeFactor != 0xff) {
871 printf ("Sorry, we don't support UnitSizeFactor "
wdenkc6097192002-11-03 00:24:07 +0000872 "of != 1 yet.\n");
873 return -1;
874 }
875
876 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
877 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
878 printf ("NFTL Media Header sanity check failed:\n"
879 "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
880 nftl->nb_boot_blocks, nftl->nb_blocks);
881 return -1;
882 }
883
884 nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
885 if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
886 printf ("NFTL Media Header sanity check failed:\n"
887 "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
888 nftl->numvunits,
889 nftl->nb_blocks,
890 nftl->nb_boot_blocks);
891 return -1;
892 }
893
894 nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
895
896 /* If we're not using the last sectors in the device for some reason,
897 reduce nb_blocks accordingly so we forget they're there */
898 nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN);
899
900 /* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
901 for (i = 0; i < nftl->nb_blocks; i++) {
902 if ((i & (SECTORSIZE - 1)) == 0) {
903 /* read one sector for every SECTORSIZE of blocks */
904 if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize +
905 i + SECTORSIZE, SECTORSIZE,
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200906 (size_t *)&retlen, buf, (uchar *)&oob)) < 0) {
wdenkc6097192002-11-03 00:24:07 +0000907 puts ("Read of bad sector table failed\n");
908 return -1;
909 }
910 }
911 /* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
912 if (buf[i & (SECTORSIZE - 1)] != 0xff)
913 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
914 }
915
916 nftl->MediaUnit = block;
917 boot_record_count++;
918
919 } /* foreach (block) */
920
921 return boot_record_count?0:-1;
922}
923
924/* This routine is made available to other mtd code via
925 * inter_module_register. It must only be accessed through
926 * inter_module_get which will bump the use count of this module. The
927 * addresses passed back in mtd are valid as long as the use count of
928 * this module is non-zero, i.e. between inter_module_get and
929 * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
930 */
931static void DoC2k_init(struct DiskOnChip* this)
932{
933 struct NFTLrecord *nftl;
934
935 switch (this->ChipID) {
936 case DOC_ChipID_Doc2k:
937 this->name = "DiskOnChip 2000";
938 this->ioreg = DoC_2k_CDSN_IO;
939 break;
940 case DOC_ChipID_DocMil:
941 this->name = "DiskOnChip Millennium";
942 this->ioreg = DoC_Mil_CDSN_IO;
943 break;
944 }
945
946#ifdef DOC_DEBUG
947 printf("%s found at address 0x%lX\n", this->name,
948 this->physadr);
949#endif
950
951 this->totlen = 0;
952 this->numchips = 0;
953
954 this->curfloor = -1;
955 this->curchip = -1;
956
957 /* Ident all the chips present. */
958 DoC_ScanChips(this);
wdenk7205e402003-09-10 22:30:53 +0000959 if ((!this->numchips) || (!this->chips))
960 return;
wdenkc6097192002-11-03 00:24:07 +0000961
962 nftl = &this->nftl;
963
964 /* Get physical parameters */
965 nftl->EraseSize = this->erasesize;
wdenk8bde7f72003-06-27 21:31:46 +0000966 nftl->nb_blocks = this->totlen / this->erasesize;
wdenkc6097192002-11-03 00:24:07 +0000967 nftl->mtd = this;
968
969 if (find_boot_record(nftl) != 0)
970 this->nftl_found = 0;
971 else
972 this->nftl_found = 1;
973
974 printf("%s @ 0x%lX, %ld MB\n", this->name, this->physadr, this->totlen >> 20);
975}
976
977int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
978 size_t * retlen, u_char * buf, u_char * eccbuf)
979{
980 unsigned long docptr;
981 struct Nand *mychip;
982 unsigned char syndrome[6];
983 volatile char dummy;
984 int i, len256 = 0, ret=0;
985
986 docptr = this->virtadr;
987
988 /* Don't allow read past end of device */
989 if (from >= this->totlen) {
990 puts ("Out of flash\n");
991 return DOC_EINVAL;
992 }
993
994 /* Don't allow a single read to cross a 512-byte block boundary */
995 if (from + len > ((from | 0x1ff) + 1))
996 len = ((from | 0x1ff) + 1) - from;
997
998 /* The ECC will not be calculated correctly if less than 512 is read */
999 if (len != 0x200 && eccbuf)
1000 printf("ECC needs a full sector read (adr: %lx size %lx)\n",
1001 (long) from, (long) len);
1002
wdenk7152b1d2003-09-05 23:19:14 +00001003#ifdef PSYCHO_DEBUG
wdenkc6097192002-11-03 00:24:07 +00001004 printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len);
1005#endif
1006
1007 /* Find the chip which is to be used and select it */
1008 mychip = &this->chips[shr(from, this->chipshift)];
1009
1010 if (this->curfloor != mychip->floor) {
1011 DoC_SelectFloor(this, mychip->floor);
1012 DoC_SelectChip(this, mychip->chip);
1013 } else if (this->curchip != mychip->chip) {
1014 DoC_SelectChip(this, mychip->chip);
1015 }
1016
1017 this->curfloor = mychip->floor;
1018 this->curchip = mychip->chip;
1019
1020 DoC_Command(this,
1021 (!this->page256
1022 && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
1023 CDSN_CTRL_WP);
1024 DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
1025 CDSN_CTRL_ECC_IO);
1026
1027 if (eccbuf) {
1028 /* Prime the ECC engine */
1029 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1030 WriteDOC(DOC_ECC_EN, docptr, ECCConf);
1031 } else {
1032 /* disable the ECC engine */
1033 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1034 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1035 }
1036
1037 /* treat crossing 256-byte sector for 2M x 8bits devices */
1038 if (this->page256 && from + len > (from | 0xff) + 1) {
1039 len256 = (from | 0xff) + 1 - from;
1040 DoC_ReadBuf(this, buf, len256);
1041
1042 DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
1043 DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
1044 CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
1045 }
1046
1047 DoC_ReadBuf(this, &buf[len256], len - len256);
1048
1049 /* Let the caller know we completed it */
1050 *retlen = len;
1051
1052 if (eccbuf) {
1053 /* Read the ECC data through the DiskOnChip ECC logic */
1054 /* Note: this will work even with 2M x 8bit devices as */
1055 /* they have 8 bytes of OOB per 256 page. mf. */
1056 DoC_ReadBuf(this, eccbuf, 6);
1057
1058 /* Flush the pipeline */
1059 if (DoC_is_Millennium(this)) {
1060 dummy = ReadDOC(docptr, ECCConf);
1061 dummy = ReadDOC(docptr, ECCConf);
1062 i = ReadDOC(docptr, ECCConf);
1063 } else {
1064 dummy = ReadDOC(docptr, 2k_ECCStatus);
1065 dummy = ReadDOC(docptr, 2k_ECCStatus);
1066 i = ReadDOC(docptr, 2k_ECCStatus);
1067 }
1068
1069 /* Check the ECC Status */
1070 if (i & 0x80) {
1071 int nb_errors;
1072 /* There was an ECC error */
1073#ifdef ECC_DEBUG
1074 printf("DiskOnChip ECC Error: Read at %lx\n", (long)from);
1075#endif
1076 /* Read the ECC syndrom through the DiskOnChip ECC logic.
1077 These syndrome will be all ZERO when there is no error */
1078 for (i = 0; i < 6; i++) {
1079 syndrome[i] =
1080 ReadDOC(docptr, ECCSyndrome0 + i);
1081 }
wdenk8bde7f72003-06-27 21:31:46 +00001082 nb_errors = doc_decode_ecc(buf, syndrome);
wdenkc6097192002-11-03 00:24:07 +00001083
1084#ifdef ECC_DEBUG
1085 printf("Errors corrected: %x\n", nb_errors);
1086#endif
wdenk8bde7f72003-06-27 21:31:46 +00001087 if (nb_errors < 0) {
wdenkc6097192002-11-03 00:24:07 +00001088 /* We return error, but have actually done the read. Not that
1089 this can be told to user-space, via sys_read(), but at least
1090 MTD-aware stuff can know about it by checking *retlen */
1091 printf("ECC Errors at %lx\n", (long)from);
1092 ret = DOC_EECC;
wdenk8bde7f72003-06-27 21:31:46 +00001093 }
wdenkc6097192002-11-03 00:24:07 +00001094 }
1095
1096#ifdef PSYCHO_DEBUG
1097 printf("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
1098 (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
1099 eccbuf[3], eccbuf[4], eccbuf[5]);
1100#endif
1101
1102 /* disable the ECC engine */
1103 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
1104 }
1105
1106 /* according to 11.4.1, we need to wait for the busy line
wdenk8bde7f72003-06-27 21:31:46 +00001107 * drop if we read to the end of the page. */
wdenkc6097192002-11-03 00:24:07 +00001108 if(0 == ((from + *retlen) & 0x1ff))
1109 {
1110 DoC_WaitReady(this);
1111 }
1112
1113 return ret;
1114}
1115
1116int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len,
1117 size_t * retlen, const u_char * buf,
1118 u_char * eccbuf)
1119{
1120 int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
1121 unsigned long docptr;
1122 volatile char dummy;
1123 int len256 = 0;
1124 struct Nand *mychip;
1125
1126 docptr = this->virtadr;
1127
1128 /* Don't allow write past end of device */
1129 if (to >= this->totlen) {
1130 puts ("Out of flash\n");
1131 return DOC_EINVAL;
1132 }
1133
1134 /* Don't allow a single write to cross a 512-byte block boundary */
1135 if (to + len > ((to | 0x1ff) + 1))
1136 len = ((to | 0x1ff) + 1) - to;
1137
1138 /* The ECC will not be calculated correctly if less than 512 is written */
1139 if (len != 0x200 && eccbuf)
1140 printf("ECC needs a full sector write (adr: %lx size %lx)\n",
1141 (long) to, (long) len);
1142
1143 /* printf("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
1144
1145 /* Find the chip which is to be used and select it */
1146 mychip = &this->chips[shr(to, this->chipshift)];
1147
1148 if (this->curfloor != mychip->floor) {
1149 DoC_SelectFloor(this, mychip->floor);
1150 DoC_SelectChip(this, mychip->chip);
1151 } else if (this->curchip != mychip->chip) {
1152 DoC_SelectChip(this, mychip->chip);
1153 }
1154
1155 this->curfloor = mychip->floor;
1156 this->curchip = mychip->chip;
1157
1158 /* Set device to main plane of flash */
1159 DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
1160 DoC_Command(this,
1161 (!this->page256
1162 && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
1163 CDSN_CTRL_WP);
1164
1165 DoC_Command(this, NAND_CMD_SEQIN, 0);
1166 DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
1167
1168 if (eccbuf) {
1169 /* Prime the ECC engine */
1170 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1171 WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
1172 } else {
1173 /* disable the ECC engine */
1174 WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
1175 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1176 }
1177
1178 /* treat crossing 256-byte sector for 2M x 8bits devices */
1179 if (this->page256 && to + len > (to | 0xff) + 1) {
1180 len256 = (to | 0xff) + 1 - to;
1181 DoC_WriteBuf(this, buf, len256);
1182
1183 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1184
1185 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1186 /* There's an implicit DoC_WaitReady() in DoC_Command */
1187
1188 dummy = ReadDOC(docptr, CDSNSlowIO);
1189 DoC_Delay(this, 2);
1190
1191 if (ReadDOC_(docptr, this->ioreg) & 1) {
1192 puts ("Error programming flash\n");
1193 /* Error in programming */
1194 *retlen = 0;
1195 return DOC_EIO;
1196 }
1197
1198 DoC_Command(this, NAND_CMD_SEQIN, 0);
1199 DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
1200 CDSN_CTRL_ECC_IO);
1201 }
1202
1203 DoC_WriteBuf(this, &buf[len256], len - len256);
1204
1205 if (eccbuf) {
1206 WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
1207 CDSNControl);
1208
1209 if (DoC_is_Millennium(this)) {
1210 WriteDOC(0, docptr, NOP);
1211 WriteDOC(0, docptr, NOP);
1212 WriteDOC(0, docptr, NOP);
1213 } else {
1214 WriteDOC_(0, docptr, this->ioreg);
1215 WriteDOC_(0, docptr, this->ioreg);
1216 WriteDOC_(0, docptr, this->ioreg);
1217 }
1218
1219 /* Read the ECC data through the DiskOnChip ECC logic */
1220 for (di = 0; di < 6; di++) {
1221 eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
1222 }
1223
1224 /* Reset the ECC engine */
1225 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1226
1227#ifdef PSYCHO_DEBUG
1228 printf
1229 ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
1230 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
1231 eccbuf[4], eccbuf[5]);
1232#endif
1233 }
1234
1235 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1236
1237 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1238 /* There's an implicit DoC_WaitReady() in DoC_Command */
1239
1240 dummy = ReadDOC(docptr, CDSNSlowIO);
1241 DoC_Delay(this, 2);
1242
1243 if (ReadDOC_(docptr, this->ioreg) & 1) {
1244 puts ("Error programming flash\n");
1245 /* Error in programming */
1246 *retlen = 0;
1247 return DOC_EIO;
1248 }
1249
1250 /* Let the caller know we completed it */
1251 *retlen = len;
1252
1253 if (eccbuf) {
1254 unsigned char x[8];
1255 size_t dummy;
1256 int ret;
1257
1258 /* Write the ECC data to flash */
1259 for (di=0; di<6; di++)
1260 x[di] = eccbuf[di];
1261
1262 x[6]=0x55;
1263 x[7]=0x55;
1264
1265 ret = doc_write_oob(this, to, 8, &dummy, x);
1266 return ret;
1267 }
1268 return 0;
1269}
1270
1271int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
1272 size_t * retlen, u_char * buf)
1273{
1274 int len256 = 0, ret;
1275 unsigned long docptr;
1276 struct Nand *mychip;
1277
1278 docptr = this->virtadr;
1279
1280 mychip = &this->chips[shr(ofs, this->chipshift)];
1281
1282 if (this->curfloor != mychip->floor) {
1283 DoC_SelectFloor(this, mychip->floor);
1284 DoC_SelectChip(this, mychip->chip);
1285 } else if (this->curchip != mychip->chip) {
1286 DoC_SelectChip(this, mychip->chip);
1287 }
1288 this->curfloor = mychip->floor;
1289 this->curchip = mychip->chip;
1290
1291 /* update address for 2M x 8bit devices. OOB starts on the second */
1292 /* page to maintain compatibility with doc_read_ecc. */
1293 if (this->page256) {
1294 if (!(ofs & 0x8))
1295 ofs += 0x100;
1296 else
1297 ofs -= 0x8;
1298 }
1299
1300 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1301 DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
1302
1303 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1304 /* Note: datasheet says it should automaticaly wrap to the */
1305 /* next OOB block, but it didn't work here. mf. */
1306 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1307 len256 = (ofs | 0x7) + 1 - ofs;
1308 DoC_ReadBuf(this, buf, len256);
1309
1310 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1311 DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
1312 CDSN_CTRL_WP, 0);
1313 }
1314
1315 DoC_ReadBuf(this, &buf[len256], len - len256);
1316
1317 *retlen = len;
1318 /* Reading the full OOB data drops us off of the end of the page,
wdenk8bde7f72003-06-27 21:31:46 +00001319 * causing the flash device to go into busy mode, so we need
1320 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
wdenkc6097192002-11-03 00:24:07 +00001321
1322 ret = DoC_WaitReady(this);
1323
1324 return ret;
1325
1326}
1327
1328int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
1329 size_t * retlen, const u_char * buf)
1330{
1331 int len256 = 0;
1332 unsigned long docptr = this->virtadr;
1333 struct Nand *mychip = &this->chips[shr(ofs, this->chipshift)];
1334 volatile int dummy;
1335
1336#ifdef PSYCHO_DEBUG
1337 printf("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",
1338 (long)ofs, len, buf[0], buf[1], buf[2], buf[3],
1339 buf[8], buf[9], buf[14],buf[15]);
1340#endif
1341
1342 /* Find the chip which is to be used and select it */
1343 if (this->curfloor != mychip->floor) {
1344 DoC_SelectFloor(this, mychip->floor);
1345 DoC_SelectChip(this, mychip->chip);
1346 } else if (this->curchip != mychip->chip) {
1347 DoC_SelectChip(this, mychip->chip);
1348 }
1349 this->curfloor = mychip->floor;
1350 this->curchip = mychip->chip;
1351
1352 /* disable the ECC engine */
1353 WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
1354 WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
1355
1356 /* Reset the chip, see Software Requirement 11.4 item 1. */
1357 DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
1358
1359 /* issue the Read2 command to set the pointer to the Spare Data Area. */
1360 DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
1361
1362 /* update address for 2M x 8bit devices. OOB starts on the second */
1363 /* page to maintain compatibility with doc_read_ecc. */
1364 if (this->page256) {
1365 if (!(ofs & 0x8))
1366 ofs += 0x100;
1367 else
1368 ofs -= 0x8;
1369 }
1370
1371 /* issue the Serial Data In command to initial the Page Program process */
1372 DoC_Command(this, NAND_CMD_SEQIN, 0);
1373 DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
1374
1375 /* treat crossing 8-byte OOB data for 2M x 8bit devices */
1376 /* Note: datasheet says it should automaticaly wrap to the */
1377 /* next OOB block, but it didn't work here. mf. */
1378 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1379 len256 = (ofs | 0x7) + 1 - ofs;
1380 DoC_WriteBuf(this, buf, len256);
1381
1382 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1383 DoC_Command(this, NAND_CMD_STATUS, 0);
1384 /* DoC_WaitReady() is implicit in DoC_Command */
1385
1386 dummy = ReadDOC(docptr, CDSNSlowIO);
1387 DoC_Delay(this, 2);
1388
1389 if (ReadDOC_(docptr, this->ioreg) & 1) {
1390 puts ("Error programming oob data\n");
1391 /* There was an error */
1392 *retlen = 0;
1393 return DOC_EIO;
1394 }
1395 DoC_Command(this, NAND_CMD_SEQIN, 0);
1396 DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
1397 }
1398
1399 DoC_WriteBuf(this, &buf[len256], len - len256);
1400
1401 DoC_Command(this, NAND_CMD_PAGEPROG, 0);
1402 DoC_Command(this, NAND_CMD_STATUS, 0);
1403 /* DoC_WaitReady() is implicit in DoC_Command */
1404
1405 dummy = ReadDOC(docptr, CDSNSlowIO);
1406 DoC_Delay(this, 2);
1407
1408 if (ReadDOC_(docptr, this->ioreg) & 1) {
1409 puts ("Error programming oob data\n");
1410 /* There was an error */
1411 *retlen = 0;
1412 return DOC_EIO;
1413 }
1414
1415 *retlen = len;
1416 return 0;
1417
1418}
1419
1420int doc_erase(struct DiskOnChip* this, loff_t ofs, size_t len)
1421{
1422 volatile int dummy;
1423 unsigned long docptr;
1424 struct Nand *mychip;
1425
1426 if (ofs & (this->erasesize-1) || len & (this->erasesize-1)) {
1427 puts ("Offset and size must be sector aligned\n");
1428 return DOC_EINVAL;
1429 }
1430
1431 docptr = this->virtadr;
1432
1433 /* FIXME: Do this in the background. Use timers or schedule_task() */
1434 while(len) {
1435 mychip = &this->chips[shr(ofs, this->chipshift)];
1436
1437 if (this->curfloor != mychip->floor) {
1438 DoC_SelectFloor(this, mychip->floor);
1439 DoC_SelectChip(this, mychip->chip);
1440 } else if (this->curchip != mychip->chip) {
1441 DoC_SelectChip(this, mychip->chip);
1442 }
1443 this->curfloor = mychip->floor;
1444 this->curchip = mychip->chip;
1445
1446 DoC_Command(this, NAND_CMD_ERASE1, 0);
1447 DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
1448 DoC_Command(this, NAND_CMD_ERASE2, 0);
1449
1450 DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
1451
1452 dummy = ReadDOC(docptr, CDSNSlowIO);
1453 DoC_Delay(this, 2);
1454
1455 if (ReadDOC_(docptr, this->ioreg) & 1) {
1456 printf("Error erasing at 0x%lx\n", (long)ofs);
1457 /* There was an error */
1458 goto callback;
1459 }
1460 ofs += this->erasesize;
1461 len -= this->erasesize;
1462 }
1463
1464 callback:
1465 return 0;
1466}
1467
1468static inline int doccheck(unsigned long potential, unsigned long physadr)
1469{
1470 unsigned long window=potential;
1471 unsigned char tmp, ChipID;
1472#ifndef DOC_PASSIVE_PROBE
1473 unsigned char tmp2;
1474#endif
1475
1476 /* Routine copied from the Linux DOC driver */
1477
1478#ifdef CFG_DOCPROBE_55AA
1479 /* Check for 0x55 0xAA signature at beginning of window,
1480 this is no longer true once we remove the IPL (for Millennium */
1481 if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
1482 return 0;
1483#endif /* CFG_DOCPROBE_55AA */
1484
1485#ifndef DOC_PASSIVE_PROBE
1486 /* It's not possible to cleanly detect the DiskOnChip - the
1487 * bootup procedure will put the device into reset mode, and
1488 * it's not possible to talk to it without actually writing
1489 * to the DOCControl register. So we store the current contents
1490 * of the DOCControl register's location, in case we later decide
1491 * that it's not a DiskOnChip, and want to put it back how we
1492 * found it.
1493 */
1494 tmp2 = ReadDOC(window, DOCControl);
1495
1496 /* Reset the DiskOnChip ASIC */
1497 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1498 window, DOCControl);
1499 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1500 window, DOCControl);
1501
1502 /* Enable the DiskOnChip ASIC */
1503 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1504 window, DOCControl);
1505 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1506 window, DOCControl);
1507#endif /* !DOC_PASSIVE_PROBE */
1508
1509 ChipID = ReadDOC(window, ChipID);
1510
1511 switch (ChipID) {
1512 case DOC_ChipID_Doc2k:
1513 /* Check the TOGGLE bit in the ECC register */
1514 tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
1515 if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
1516 return ChipID;
1517 break;
1518
1519 case DOC_ChipID_DocMil:
1520 /* Check the TOGGLE bit in the ECC register */
1521 tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
1522 if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
1523 return ChipID;
1524 break;
1525
1526 default:
1527#ifndef CFG_DOCPROBE_55AA
1528/*
1529 * if the ID isn't the DoC2000 or DoCMillenium ID, so we can assume
1530 * the DOC is missing
1531 */
1532# if 0
1533 printf("Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
1534 ChipID, physadr);
1535# endif
1536#endif
1537#ifndef DOC_PASSIVE_PROBE
1538 /* Put back the contents of the DOCControl register, in case it's not
1539 * actually a DiskOnChip.
1540 */
1541 WriteDOC(tmp2, window, DOCControl);
1542#endif
1543 return 0;
1544 }
1545
1546 puts ("DiskOnChip failed TOGGLE test, dropping.\n");
1547
1548#ifndef DOC_PASSIVE_PROBE
1549 /* Put back the contents of the DOCControl register: it's not a DiskOnChip */
1550 WriteDOC(tmp2, window, DOCControl);
1551#endif
1552 return 0;
1553}
1554
1555void doc_probe(unsigned long physadr)
1556{
1557 struct DiskOnChip *this = NULL;
1558 int i=0, ChipID;
1559
1560 if ((ChipID = doccheck(physadr, physadr))) {
1561
1562 for (i=0; i<CFG_MAX_DOC_DEVICE; i++) {
1563 if (doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) {
1564 this = doc_dev_desc + i;
1565 break;
1566 }
1567 }
1568
1569 if (!this) {
1570 puts ("Cannot allocate memory for data structures.\n");
1571 return;
1572 }
1573
1574 if (curr_device == -1)
1575 curr_device = i;
1576
1577 memset((char *)this, 0, sizeof(struct DiskOnChip));
1578
1579 this->virtadr = physadr;
1580 this->physadr = physadr;
1581 this->ChipID = ChipID;
1582
1583 DoC2k_init(this);
1584 } else {
1585 puts ("No DiskOnChip found\n");
1586 }
1587}
1588
1589#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */