]> git.sur5r.net Git - u-boot/blobdiff - common/cmd_doc.c
add some more Blackfin docs
[u-boot] / common / cmd_doc.c
index 37d0fbdfc3105c38223b0217e853b6426974d3ed..3d717c039d444a54c3cd756d8a8c44e0474abbc0 100644 (file)
 #include <command.h>
 #include <malloc.h>
 #include <asm/io.h>
-
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
-# include <status_led.h>
-# define SHOW_BOOT_PROGRESS(arg)       show_boot_progress(arg)
-#else
-# define SHOW_BOOT_PROGRESS(arg)
-#endif
-
-#if (CONFIG_COMMANDS & CFG_CMD_DOC)
-
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ids.h>
-#include <linux/mtd/doc2000.h>
 #include <linux/mtd/nftl.h>
+#include <linux/mtd/doc2000.h>
 
 #ifdef CFG_DOC_SUPPORT_2000
 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
@@ -67,6 +55,32 @@ static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE];
 /* Current DOC Device  */
 static int curr_device = -1;
 
+/* Supported NAND flash devices */
+static struct nand_flash_dev nand_flash_ids[] = {
+       {"Toshiba TC5816BDC",     NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0},
+       {"Toshiba TC5832DC",      NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0},
+       {"Toshiba TH58V128DC",    NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000, 0},
+       {"Toshiba TC58256FT/DC",  NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000, 0},
+       {"Toshiba TH58512FT",     NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000, 0},
+       {"Toshiba TC58V32DC",     NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000, 0},
+       {"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000, 0},
+       {"Toshiba TC58V16BDC",    NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000, 0},
+       {"Toshiba TH58100FT",     NAND_MFR_TOSHIBA, 0x79, 27, 0, 3, 0x4000, 0},
+       {"Samsung KM29N16000",    NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0},
+       {"Samsung unknown 4Mb",   NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0},
+       {"Samsung KM29U128T",     NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000, 0},
+       {"Samsung KM29U256T",     NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000, 0},
+       {"Samsung unknown 64Mb",  NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
+       {"Samsung KM29W32000",    NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000, 0},
+       {"Samsung unknown 4Mb",   NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000, 0},
+       {"Samsung KM29U64000",    NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000, 0},
+       {"Samsung KM29W16000",    NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0},
+       {"Samsung K9F5616Q0C",    NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1},
+       {"Samsung K9K1216Q0C",    NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1},
+       {"Samsung K9F1G08U0M",    NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0},
+       {NULL,}
+};
+
 /* ------------------------------------------------------------------------- */
 
 int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@@ -79,7 +93,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        printf ("Usage:\n%s\n", cmdtp->usage);
        return 1;
     case 2:
-        if (strcmp(argv[1],"info") == 0) {
+       if (strcmp(argv[1],"info") == 0) {
                int i;
 
                putc ('\n');
@@ -142,7 +156,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                        cmd ? "read" : "write", curr_device, off, size);
 
                ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size,
-                            &total, (u_char*)addr);
+                            (size_t *)&total, (u_char*)addr);
 
                printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write",
                        ret ? "ERROR" : "OK");
@@ -169,6 +183,17 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return rcode;
     }
 }
+U_BOOT_CMD(
+       doc,    5,      1,      do_doc,
+       "doc     - Disk-On-Chip sub-system\n",
+       "info  - show available DOC devices\n"
+       "doc device [dev] - show or set current device\n"
+       "doc read  addr off size\n"
+       "doc write addr off size - read/write `size'"
+       " bytes starting at offset `off'\n"
+       "    to/from memory address `addr'\n"
+       "doc erase off size - erase `size' bytes of DOC from offset `off'\n"
+);
 
 int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
@@ -181,6 +206,7 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        image_header_t *hdr;
        int rcode = 0;
 
+       show_boot_progress (34);
        switch (argc) {
        case 1:
                addr = CFG_LOAD_ADDR;
@@ -201,24 +227,27 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                break;
        default:
                printf ("Usage:\n%s\n", cmdtp->usage);
-               SHOW_BOOT_PROGRESS (-1);
+               show_boot_progress (-35);
                return 1;
        }
 
+       show_boot_progress (35);
        if (!boot_device) {
                puts ("\n** No boot device **\n");
-               SHOW_BOOT_PROGRESS (-1);
+               show_boot_progress (-36);
                return 1;
        }
+       show_boot_progress (36);
 
        dev = simple_strtoul(boot_device, &ep, 16);
 
        if ((dev >= CFG_MAX_DOC_DEVICE) ||
            (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) {
                printf ("\n** Device %d not available\n", dev);
-               SHOW_BOOT_PROGRESS (-1);
+               show_boot_progress (-37);
                return 1;
        }
+       show_boot_progress (37);
 
        printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n",
                dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr,
@@ -227,9 +256,10 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        if (doc_rw (doc_dev_desc + dev, 1, offset,
                    SECTORSIZE, NULL, (u_char *)addr)) {
                printf ("** Read error on %d\n", dev);
-               SHOW_BOOT_PROGRESS (-1);
+               show_boot_progress (-38);
                return 1;
        }
+       show_boot_progress (38);
 
        hdr = (image_header_t *)addr;
 
@@ -237,20 +267,22 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
                print_image_hdr (hdr);
 
-               cnt = (hdr->ih_size + sizeof(image_header_t));
+               cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
                cnt -= SECTORSIZE;
        } else {
                puts ("\n** Bad Magic Number **\n");
-               SHOW_BOOT_PROGRESS (-1);
+               show_boot_progress (-39);
                return 1;
        }
+       show_boot_progress (39);
 
        if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
                    NULL, (u_char *)(addr+SECTORSIZE))) {
                printf ("** Read error on %d\n", dev);
-               SHOW_BOOT_PROGRESS (-1);
+               show_boot_progress (-40);
                return 1;
        }
+       show_boot_progress (40);
 
        /* Loading ok, update default load address */
 
@@ -272,6 +304,12 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return rcode;
 }
 
+U_BOOT_CMD(
+       docboot,        4,      1,      do_docboot,
+       "docboot - boot from DOC device\n",
+       "loadAddr dev\n"
+);
+
 int doc_rw (struct DiskOnChip* this, int cmd,
            loff_t from, size_t len,
            size_t * retlen, u_char * buf)
@@ -286,12 +324,12 @@ int doc_rw (struct DiskOnChip* this, int cmd,
 
                if (cmd)
                        ret = doc_read_ecc(this, from, len,
-                                          &n, (u_char*)buf,
-                                          noecc ? NULL : eccbuf);
+                                          (size_t *)&n, (u_char*)buf,
+                                          noecc ? (uchar *)NULL : (uchar *)eccbuf);
                else
                        ret = doc_write_ecc(this, from, len,
-                                           &n, (u_char*)buf,
-                                           noecc ? NULL : eccbuf);
+                                           (size_t *)&n, (u_char*)buf,
+                                           noecc ? (uchar *)NULL : (uchar *)eccbuf);
 
                if (ret)
                        break;
@@ -384,7 +422,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
                }
 #endif
                udelay(1);
-        }
+       }
 
        return 0;
 }
@@ -507,7 +545,7 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
        return DoC_WaitReady(doc);
 }
 
-/* Read a buffer from DoC, taking care of Millennium odditys */
+/* Read a buffer from DoC, taking care of Millennium oddities */
 static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
 {
        volatile int dummy;
@@ -540,7 +578,7 @@ static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
        }
 }
 
-/* Write a buffer to DoC, taking care of Millennium odditys */
+/* Write a buffer to DoC, taking care of Millennium oddities */
 static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
 {
        unsigned long docptr;
@@ -786,7 +824,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
                /* Check for ANAND header first. Then can whinge if it's found but later
                   checks fail */
                if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
-                                       &retlen, buf, NULL))) {
+                                       (size_t *)&retlen, buf, NULL))) {
                        static int warncount = 5;
 
                        if (warncount) {
@@ -811,7 +849,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
 
                /* To be safer with BIOS, also use erase mark as discriminant */
                if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-                               8, &retlen, (char *)&h1) < 0)) {
+                               8, (size_t *)&retlen, (uchar *)&h1) < 0)) {
 #ifdef NFTL_DEBUG
                        printf("ANAND header found at 0x%x, but OOB data read failed\n",
                               block * nftl->EraseSize);
@@ -843,8 +881,13 @@ static int find_boot_record(struct NFTLrecord *nftl)
                memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
 
                /* Do some sanity checks on it */
-               if (mh->UnitSizeFactor != 0xff) {
-                       puts ("Sorry, we don't support UnitSizeFactor "
+               if (mh->UnitSizeFactor == 0) {
+#ifdef NFTL_DEBUG
+                       puts ("UnitSizeFactor 0x00 detected.\n"
+                             "This violates the spec but we think we know what it means...\n");
+#endif
+               } else if (mh->UnitSizeFactor != 0xff) {
+                       printf ("Sorry, we don't support UnitSizeFactor "
                              "of != 1 yet.\n");
                        return -1;
                }
@@ -879,7 +922,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
                                /* read one sector for every SECTORSIZE of blocks */
                                if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize +
                                                       i + SECTORSIZE, SECTORSIZE,
-                                                      &retlen, buf, (char *)&oob)) < 0) {
+                                                      (size_t *)&retlen, buf, (uchar *)&oob)) < 0) {
                                        puts ("Read of bad sector table failed\n");
                                        return -1;
                                }
@@ -932,12 +975,14 @@ static void DoC2k_init(struct DiskOnChip* this)
 
        /* Ident all the chips present. */
        DoC_ScanChips(this);
+       if ((!this->numchips) || (!this->chips))
+               return;
 
        nftl = &this->nftl;
 
        /* Get physical parameters */
        nftl->EraseSize = this->erasesize;
-        nftl->nb_blocks = this->totlen / this->erasesize;
+       nftl->nb_blocks = this->totlen / this->erasesize;
        nftl->mtd = this;
 
        if (find_boot_record(nftl) != 0)
@@ -974,7 +1019,7 @@ int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
                printf("ECC needs a full sector read (adr: %lx size %lx)\n",
                       (long) from, (long) len);
 
-#ifdef PHYCH_DEBUG
+#ifdef PSYCHO_DEBUG
        printf("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len);
 #endif
 
@@ -1053,18 +1098,18 @@ int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
                                syndrome[i] =
                                    ReadDOC(docptr, ECCSyndrome0 + i);
                        }
-                        nb_errors = doc_decode_ecc(buf, syndrome);
+                       nb_errors = doc_decode_ecc(buf, syndrome);
 
 #ifdef ECC_DEBUG
                        printf("Errors corrected: %x\n", nb_errors);
 #endif
-                        if (nb_errors < 0) {
+                       if (nb_errors < 0) {
                                /* We return error, but have actually done the read. Not that
                                   this can be told to user-space, via sys_read(), but at least
                                   MTD-aware stuff can know about it by checking *retlen */
                                printf("ECC Errors at %lx\n", (long)from);
                                ret = DOC_EECC;
-                        }
+                       }
                }
 
 #ifdef PSYCHO_DEBUG
@@ -1078,7 +1123,7 @@ int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len,
        }
 
        /* according to 11.4.1, we need to wait for the busy line
-         * drop if we read to the end of the page.  */
+        * drop if we read to the end of the page.  */
        if(0 == ((from + *retlen) & 0x1ff))
        {
            DoC_WaitReady(this);
@@ -1290,8 +1335,8 @@ int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len,
 
        *retlen = len;
        /* Reading the full OOB data drops us off of the end of the page,
-         * causing the flash device to go into busy mode, so we need
-         * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
+        * causing the flash device to go into busy mode, so we need
+        * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
 
        ret = DoC_WaitReady(this);
 
@@ -1559,5 +1604,3 @@ void doc_probe(unsigned long physadr)
                puts ("No DiskOnChip found\n");
        }
 }
-
-#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */