Code cleanup; make several boards compile & link.
[oweals/u-boot.git] / board / emk / common / flash.c
index b2a21382e522338f92f7634c617e2cc72264319f..28fe29d6445bbac983c9a4f5da17904183309c00 100644 (file)
 
 flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
 
-typedef unsigned char FLASH_PORT_WIDTH;
-typedef volatile unsigned char FLASH_PORT_WIDTHV;
-#define        FLASH_ID_MASK   0xFF
+#if defined (CONFIG_TOP860)
+  typedef unsigned short FLASH_PORT_WIDTH;
+  typedef volatile unsigned short FLASH_PORT_WIDTHV;
+  #define      FLASH_ID_MASK   0xFF
+
+  #define FPW  FLASH_PORT_WIDTH
+  #define FPWV FLASH_PORT_WIDTHV
+
+  #define FLASH_CYCLE1 0x0555
+  #define FLASH_CYCLE2 0x02aa
+  #define FLASH_ID1            0
+  #define FLASH_ID2            1
+  #define FLASH_ID3            0x0e
+  #define FLASH_ID4            0x0F
+#endif
+
+#if defined (CONFIG_TOP5200) && !defined (CONFIG_LITE5200)
+  typedef unsigned char FLASH_PORT_WIDTH;
+  typedef volatile unsigned char FLASH_PORT_WIDTHV;
+  #define      FLASH_ID_MASK   0xFF
 
-#define FPW    FLASH_PORT_WIDTH
-#define FPWV   FLASH_PORT_WIDTHV
+  #define FPW  FLASH_PORT_WIDTH
+  #define FPWV FLASH_PORT_WIDTHV
+
+  #define FLASH_CYCLE1 0x0aaa
+  #define FLASH_CYCLE2 0x0555
+  #define FLASH_ID1            0
+  #define FLASH_ID2            2
+  #define FLASH_ID3            0x1c
+  #define FLASH_ID4            0x1E
+#endif
 
-#define FLASH_CYCLE1   0x0aaa
-#define FLASH_CYCLE2   0x0555
+#if defined (CONFIG_TOP5200) && defined (CONFIG_LITE5200)
+  typedef unsigned char FLASH_PORT_WIDTH;
+  typedef volatile unsigned char FLASH_PORT_WIDTHV;
+  #define      FLASH_ID_MASK   0xFF
+
+  #define FPW  FLASH_PORT_WIDTH
+  #define FPWV FLASH_PORT_WIDTHV
+
+  #define FLASH_CYCLE1 0x0555
+  #define FLASH_CYCLE2 0x02aa
+  #define FLASH_ID1            0
+  #define FLASH_ID2            1
+  #define FLASH_ID3            0x0E
+  #define FLASH_ID4            0x0F
+#endif
 
 /*-----------------------------------------------------------------------
  * Functions
@@ -165,6 +203,15 @@ void flash_print_info (flash_info_t *info)
        case FLASH_AM160B:
                fmt = "29LV160%s (16 Mbit, %s)\n";
                break;
+       case FLASH_AMLV640U:
+               fmt = "29LV640M (64 Mbit)\n";
+               break;
+       case FLASH_AMDLV065D:
+               fmt = "29LV065D (64 Mbit)\n";
+               break;
+       case FLASH_AMLV256U:
+               fmt = "29LV256M (256 Mbit)\n";
+               break;
        default:
                fmt = "Unknown Chip Type\n";
                break;
@@ -179,12 +226,33 @@ void flash_print_info (flash_info_t *info)
        printf ("  Sector Start Addresses:");
 
        for (i=0; i<info->sector_count; ++i) {
+               ulong   size;
+               int             erased;
+               ulong   *flash = (unsigned long *) info->start[i];
+
                if ((i % 5) == 0) {
                        printf ("\n   ");
                }
 
-               printf (" %08lX%s", info->start[i],
-                       info->protect[i] ? " (RO)" : "     ");
+               /*
+                * Check if whole sector is erased
+                */
+               size =
+                       (i != (info->sector_count - 1)) ?
+                       (info->start[i + 1] - info->start[i]) >> 2 :
+               (info->start[0] + info->size - info->start[i]) >> 2;
+
+               for (
+                       flash = (unsigned long *) info->start[i], erased = 1;
+                               (flash != (unsigned long *) info->start[i] + size) && erased;
+                                       flash++
+                       )
+                       erased = *flash == ~0x0UL;
+
+               printf (" %08lX %s %s",
+                       info->start[i],
+                       erased ? "E": " ",
+                       info->protect[i] ? "(RO)" : "    ");
        }
 
        printf ("\n");
@@ -200,7 +268,6 @@ void flash_print_info (flash_info_t *info)
 ulong flash_get_size (FPWV *addr, flash_info_t *info)
 {
        int             i;
-       ulong   offset;
 
        /* Write auto select command: read Manufacturer ID */
        /* Write auto select command sequence and test FLASH answer */
@@ -212,7 +279,7 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
         * This works for any bus width and any FLASH device width.
         */
        udelay(100);
-       switch (addr[0] & 0xff) {
+       switch (addr[FLASH_ID1] & 0xff) {
 
        case (uchar)AMD_MANUFACT:
                info->flash_id = FLASH_MAN_AMD;
@@ -225,7 +292,7 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
 #endif
 
        default:
-               printf ("unknown vendor=%x ", addr[0] & 0xff);
+               printf ("unknown vendor=%x ", addr[FLASH_ID1] & 0xff);
                info->flash_id = FLASH_UNKNOWN;
                info->sector_count = 0;
                info->size = 0;
@@ -233,33 +300,70 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
        }
 
        /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
-       if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[2]) {
+       if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[FLASH_ID2]) {
 
        case (FPW)AMD_ID_LV160B:
                info->flash_id += FLASH_AM160B;
                info->sector_count = 35;
                info->size = 0x00200000;
-#ifdef CFG_LOWBOOT
-               offset = 0;
-#else
-               offset = 0x00e00000;
-#endif
-               info->start[0] = (ulong)addr + offset;
-               info->start[1] = (ulong)addr + offset + 0x4000;
-               info->start[2] = (ulong)addr + offset + 0x6000;
-               info->start[3] = (ulong)addr + offset + 0x8000;
+               info->start[0] = (ulong)addr;
+               info->start[1] = (ulong)addr + 0x4000;
+               info->start[2] = (ulong)addr + 0x6000;
+               info->start[3] = (ulong)addr + 0x8000;
                for (i = 4; i < info->sector_count; i++)
                {
-                       info->start[i] = (ulong)addr + offset + 0x10000 * (i-3);
+                       info->start[i] = (ulong)addr + 0x10000 * (i-3);
+               }
+               break;
+
+       case (FPW)AMD_ID_LV065D:
+               info->flash_id += FLASH_AMDLV065D;
+               info->sector_count = 128;
+               info->size = 0x00800000;
+               for (i = 0; i < info->sector_count; i++)
+               {
+                       info->start[i] = (ulong)addr + 0x10000 * i;
                }
                break;
 
+       case (FPW)AMD_ID_MIRROR:
+               /* MIRROR BIT FLASH, read more ID bytes */
+               if ((FPW)addr[FLASH_ID3] == (FPW)AMD_ID_LV640U_2 &&
+                       (FPW)addr[FLASH_ID4] == (FPW)AMD_ID_LV640U_3)
+               {
+                       info->flash_id += FLASH_AMLV640U;
+                       info->sector_count = 128;
+                       info->size = 0x00800000;
+                       for (i = 0; i < info->sector_count; i++)
+                       {
+                               info->start[i] = (ulong)addr + 0x10000 * i;
+                       }
+                       break;
+               }
+               if ((FPW)addr[FLASH_ID3] == (FPW)AMD_ID_LV256U_2 &&
+                       (FPW)addr[FLASH_ID4] == (FPW)AMD_ID_LV256U_3)
+               {
+                       /* attention: only the first 16 MB will be used in u-boot */
+                       info->flash_id += FLASH_AMLV256U;
+                       info->sector_count = 256;
+                       info->size = 0x01000000;
+                       for (i = 0; i < info->sector_count; i++)
+                       {
+                               info->start[i] = (ulong)addr + 0x10000 * i;
+                       }
+                       break;
+               }
+
+               /* fall thru to here ! */
        default:
-               printf ("unknown AMD device=%x ", (FPW)addr[2]);
+               printf ("unknown AMD device=%x %x %x",
+                       (FPW)addr[FLASH_ID2],
+                       (FPW)addr[FLASH_ID3],
+                       (FPW)addr[FLASH_ID4]);
                info->flash_id = FLASH_UNKNOWN;
                info->sector_count = 0;
-               info->size = 0;
-               return (0);                     /* => no or unknown flash */
+               info->size = 0x800000;
+               break;
        }
 
        /* Put FLASH back in read mode */
@@ -290,6 +394,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
 
        switch (info->flash_id & FLASH_TYPEMASK) {
        case FLASH_AM160B:
+       case FLASH_AMLV640U:
                break;
        case FLASH_UNKNOWN:
        default: