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