]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - common/cmd_doc.c
usb_scan_devices: fix output with no devices
[karo-tx-uboot.git] / common / cmd_doc.c
index c726957cace50e6f6628ee8be18209469bdec793..e2d4a42d1dc5c71a8ca7fabfef9bdab8d963ff65 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/nftl.h>
-#include <linux/mtd/nand_legacy.h>
-#include <linux/mtd/nand_ids.h>
-
 #include <linux/mtd/doc2000.h>
-#include <linux/mtd/nftl.h>
 
-#ifdef CFG_DOC_SUPPORT_2000
+/*
+ * ! BROKEN !
+ *
+ * TODO: must be implemented and tested by someone with HW
+ */
+#if 0
+#ifdef CONFIG_SYS_DOC_SUPPORT_2000
 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
 #else
 #define DoC_is_2000(doc) (0)
 #endif
 
-#ifdef CFG_DOC_SUPPORT_MILLENNIUM
+#ifdef CONFIG_SYS_DOC_SUPPORT_MILLENNIUM
 #define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
 #else
 #define DoC_is_Millennium(doc) (0)
 #endif
 
-/* CFG_DOC_PASSIVE_PROBE:
+/* CONFIG_SYS_DOC_PASSIVE_PROBE:
    In order to ensure that the BIOS checksum is correct at boot time, and
    hence that the onboard BIOS extension gets executed, the DiskOnChip
    goes into reset mode when it is read sequentially: all registers
@@ -56,7 +48,7 @@
    the machine.
 
    If you have this problem, uncomment the following line:
-#define CFG_DOC_PASSIVE_PROBE
+#define CONFIG_SYS_DOC_PASSIVE_PROBE
 */
 
 #undef DOC_DEBUG
 #undef PSYCHO_DEBUG
 #undef NFTL_DEBUG
 
-static struct DiskOnChip doc_dev_desc[CFG_MAX_DOC_DEVICE];
+static struct DiskOnChip doc_dev_desc[CONFIG_SYS_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[])
@@ -78,7 +96,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
     switch (argc) {
     case 0:
     case 1:
-       printf ("Usage:\n%s\n", cmdtp->usage);
+       cmd_usage(cmdtp);
        return 1;
     case 2:
        if (strcmp(argv[1],"info") == 0) {
@@ -86,7 +104,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
                putc ('\n');
 
-               for (i=0; i<CFG_MAX_DOC_DEVICE; ++i) {
+               for (i=0; i<CONFIG_SYS_MAX_DOC_DEVICE; ++i) {
                        if(doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN)
                                continue; /* list only known devices */
                        printf ("Device %d: ", i);
@@ -95,7 +113,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                return 0;
 
        } else if (strcmp(argv[1],"device") == 0) {
-               if ((curr_device < 0) || (curr_device >= CFG_MAX_DOC_DEVICE)) {
+               if ((curr_device < 0) || (curr_device >= CONFIG_SYS_MAX_DOC_DEVICE)) {
                        puts ("\nno devices available\n");
                        return 1;
                }
@@ -103,14 +121,14 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                doc_print(&doc_dev_desc[curr_device]);
                return 0;
        }
-       printf ("Usage:\n%s\n", cmdtp->usage);
+       cmd_usage(cmdtp);
        return 1;
     case 3:
        if (strcmp(argv[1],"device") == 0) {
                int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
                printf ("\nDevice %d: ", dev);
-               if (dev >= CFG_MAX_DOC_DEVICE) {
+               if (dev >= CONFIG_SYS_MAX_DOC_DEVICE) {
                        puts ("unknown device\n");
                        return 1;
                }
@@ -128,7 +146,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                return 0;
        }
 
-       printf ("Usage:\n%s\n", cmdtp->usage);
+       cmd_usage(cmdtp);
        return 1;
     default:
        /* at least 4 args */
@@ -164,7 +182,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
                return ret;
        } else {
-               printf ("Usage:\n%s\n", cmdtp->usage);
+               cmd_usage(cmdtp);
                rcode = 1;
        }
 
@@ -173,7 +191,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 }
 U_BOOT_CMD(
        doc,    5,      1,      do_doc,
-       "doc     - Disk-On-Chip sub-system\n",
+       "Disk-On-Chip sub-system",
        "info  - show available DOC devices\n"
        "doc device [dev] - show or set current device\n"
        "doc read  addr off size\n"
@@ -193,10 +211,14 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        ulong offset = 0;
        image_header_t *hdr;
        int rcode = 0;
+#if defined(CONFIG_FIT)
+       const void *fit_hdr = NULL;
+#endif
 
+       show_boot_progress (34);
        switch (argc) {
        case 1:
-               addr = CFG_LOAD_ADDR;
+               addr = CONFIG_SYS_LOAD_ADDR;
                boot_device = getenv ("bootdevice");
                break;
        case 2:
@@ -213,25 +235,28 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                offset = simple_strtoul(argv[3], NULL, 16);
                break;
        default:
-               printf ("Usage:\n%s\n", cmdtp->usage);
-               SHOW_BOOT_PROGRESS (-1);
+               cmd_usage(cmdtp);
+               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) ||
+       if ((dev >= CONFIG_SYS_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,
@@ -240,30 +265,55 @@ 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;
+       switch (genimg_get_format ((void *)addr)) {
+       case IMAGE_FORMAT_LEGACY:
+               hdr = (image_header_t *)addr;
 
-       if (hdr->ih_magic == IH_MAGIC) {
+               image_print_contents (hdr);
 
-               print_image_hdr (hdr);
+               cnt = image_get_image_size (hdr);
+               break;
+#if defined(CONFIG_FIT)
+       case IMAGE_FORMAT_FIT:
+               fit_hdr = (const void *)addr;
+               puts ("Fit image detected...\n");
 
-               cnt = (hdr->ih_size + sizeof(image_header_t));
-               cnt -= SECTORSIZE;
-       } else {
-               puts ("\n** Bad Magic Number **\n");
-               SHOW_BOOT_PROGRESS (-1);
+               cnt = fit_get_size (fit_hdr);
+               break;
+#endif
+       default:
+               show_boot_progress (-39);
+               puts ("** Unknown image type\n");
                return 1;
        }
+       show_boot_progress (39);
 
+       cnt -= SECTORSIZE;
        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);
+
+#if defined(CONFIG_FIT)
+       /* This cannot be done earlier, we need complete FIT image in RAM first */
+       if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
+               if (!fit_check_format (fit_hdr)) {
+                       show_boot_progress (-130);
+                       puts ("** Bad FIT image format\n");
+                       return 1;
+               }
+               show_boot_progress (131);
+               fit_print_contents (fit_hdr);
+       }
+#endif
 
        /* Loading ok, update default load address */
 
@@ -287,7 +337,7 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
 U_BOOT_CMD(
        docboot,        4,      1,      do_docboot,
-       "docboot - boot from DOC device\n",
+       "boot from DOC device",
        "loadAddr dev\n"
 );
 
@@ -389,7 +439,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
 
        /* Out-of-line routine to wait for chip response */
        while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-#ifdef CFG_DOC_SHORT_TIMEOUT
+#ifdef CONFIG_SYS_DOC_SHORT_TIMEOUT
                /* it seems that after a certain time the DoC deasserts
                 * the CDSN_CTRL_FR_B although it is not ready...
                 * using a short timout solve this (timer increments every ms) */
@@ -1475,12 +1525,12 @@ static inline int doccheck(unsigned long potential, unsigned long physadr)
 
        /* Routine copied from the Linux DOC driver */
 
-#ifdef CFG_DOCPROBE_55AA
+#ifdef CONFIG_SYS_DOCPROBE_55AA
        /* Check for 0x55 0xAA signature at beginning of window,
           this is no longer true once we remove the IPL (for Millennium */
        if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
                return 0;
-#endif /* CFG_DOCPROBE_55AA */
+#endif /* CONFIG_SYS_DOCPROBE_55AA */
 
 #ifndef DOC_PASSIVE_PROBE
        /* It's not possible to cleanly detect the DiskOnChip - the
@@ -1524,7 +1574,7 @@ static inline int doccheck(unsigned long potential, unsigned long physadr)
                break;
 
        default:
-#ifndef CFG_DOCPROBE_55AA
+#ifndef CONFIG_SYS_DOCPROBE_55AA
 /*
  * if the ID isn't the DoC2000 or DoCMillenium ID, so we can assume
  * the DOC is missing
@@ -1559,7 +1609,7 @@ void doc_probe(unsigned long physadr)
 
        if ((ChipID = doccheck(physadr, physadr))) {
 
-               for (i=0; i<CFG_MAX_DOC_DEVICE; i++) {
+               for (i=0; i<CONFIG_SYS_MAX_DOC_DEVICE; i++) {
                        if (doc_dev_desc[i].ChipID == DOC_ChipID_UNKNOWN) {
                                this = doc_dev_desc + i;
                                break;
@@ -1585,5 +1635,6 @@ void doc_probe(unsigned long physadr)
                puts ("No DiskOnChip found\n");
        }
 }
-
-#endif /* (CONFIG_COMMANDS & CFG_CMD_DOC) */
+#else
+void doc_probe(unsigned long physadr) {}
+#endif