source: SVN/rincon/u-boot/common/cmd_doc.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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