]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - board/emk/common/flash.c
gic: fixed compilation error in GICv2 wait for interrupt macro
[karo-tx-uboot.git] / board / emk / common / flash.c
index b2a21382e522338f92f7634c617e2cc72264319f..ae5777c796febbf4e80aaa84f75d23d70156e339 100644 (file)
@@ -5,38 +5,60 @@
  * (C) Copyright 2003
  * Reinhard Meyer, EMK Elektronik GmbH, r.meyer@emk-elektronik.de
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 
-flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+flash_info_t   flash_info[CONFIG_SYS_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 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 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
@@ -44,7 +66,7 @@ typedef volatile unsigned char FLASH_PORT_WIDTHV;
 static ulong flash_get_size(FPWV *addr, flash_info_t *info);
 static void flash_reset(flash_info_t *info);
 static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
-static flash_info_t *flash_get_info(ulong base);
+flash_info_t *flash_get_info(ulong base);
 
 /*-----------------------------------------------------------------------
  * flash_init()
@@ -57,7 +79,7 @@ unsigned long flash_init (void)
        int i = 0;
        extern void flash_preinit(void);
        extern void flash_afterinit(uint, ulong, ulong);
-       ulong flashbase = CFG_FLASH_BASE;
+       ulong flashbase = CONFIG_SYS_FLASH_BASE;
 
        flash_preinit();
 
@@ -67,20 +89,20 @@ unsigned long flash_init (void)
                        flash_get_size((FPW *)flashbase, &flash_info[i]);
        size += flash_info[i].size;
 
-#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
        /* monitor protection ON by default */
        flash_protect(FLAG_PROTECT_SET,
-                     CFG_MONITOR_BASE,
-                     CFG_MONITOR_BASE+monitor_flash_len-1,
-                     flash_get_info(CFG_MONITOR_BASE));
+                     CONFIG_SYS_MONITOR_BASE,
+                     CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
+                     flash_get_info(CONFIG_SYS_MONITOR_BASE));
 #endif
 
-#ifdef CFG_ENV_IS_IN_FLASH
+#ifdef CONFIG_ENV_IS_IN_FLASH
        /* ENV protection ON by default */
        flash_protect(FLAG_PROTECT_SET,
-                     CFG_ENV_ADDR,
-                     CFG_ENV_ADDR+CFG_ENV_SIZE-1,
-                     flash_get_info(CFG_ENV_ADDR));
+                     CONFIG_ENV_ADDR,
+                     CONFIG_ENV_ADDR+CONFIG_ENV_SIZE-1,
+                     flash_get_info(CONFIG_ENV_ADDR));
 #endif
 
 
@@ -104,19 +126,19 @@ static void flash_reset(flash_info_t *info)
 /*-----------------------------------------------------------------------
  */
 
-static flash_info_t *flash_get_info(ulong base)
+flash_info_t *flash_get_info(ulong base)
 {
        int i;
        flash_info_t * info;
 
-       for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
+       for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i ++) {
                info = & flash_info[i];
                if (info->size &&
                        info->start[0] <= base && base <= info->start[0] + info->size - 1)
                        break;
        }
 
-       return i == CFG_MAX_FLASH_BANKS ? 0 : info;
+       return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info;
 }
 
 /*-----------------------------------------------------------------------
@@ -127,7 +149,7 @@ void flash_print_info (flash_info_t *info)
        int i;
        uchar *boottype;
        uchar *bootletter;
-       uchar *fmt;
+       char *fmt;
        uchar botbootletter[] = "B";
        uchar topbootletter[] = "T";
        uchar botboottype[] = "bottom boot sector";
@@ -165,6 +187,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 +210,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 +252,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 +263,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 +276,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 +284,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 +378,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:
@@ -354,7 +443,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
                udelay (1000);
 
                while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
-                       if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                       if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
                                printf ("Timeout\n");
 
                                if (intel) {
@@ -368,14 +457,14 @@ int       flash_erase (flash_info_t *info, int s_first, int s_last)
                        }
 
                        /* show that we're waiting */
-                       if ((get_timer(last)) > CFG_HZ) {/* every second */
+                       if ((get_timer(last)) > CONFIG_SYS_HZ) {/* every second */
                                putc ('.');
                                last = get_timer(0);
                        }
                }
 
                /* show that we're waiting */
-               if ((get_timer(last)) > CFG_HZ) {       /* every second */
+               if ((get_timer(last)) > CONFIG_SYS_HZ) {        /* every second */
                        putc ('.');
                        last = get_timer(0);
                }
@@ -476,7 +565,7 @@ static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
 
        /* data polling for D7 */
        while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
-               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+               if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
                        *dest = (FPW)0x00F000F0;        /* reset bank */
                        res = 1;
                }