Patch by Yuli Barcohen, 09 Jun 2004:
authorwdenk <wdenk>
Wed, 9 Jun 2004 21:54:22 +0000 (21:54 +0000)
committerwdenk <wdenk>
Wed, 9 Jun 2004 21:54:22 +0000 (21:54 +0000)
Add support for 8MB flash SIMM and JFFS2 file system on
Motorola FADS board and its derivatives (MPC86xADS, MPC885ADS).

CHANGELOG
board/fads/fads.h
board/fads/flash.c
board/fads/u-boot.lds

index aa5893d..e24867c 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,10 @@ Changes since U-Boot 1.1.1:
 ======================================================================
 
 * Patch by Yuli Barcohen, 09 Jun 2004:
+  Add support for 8MB flash SIMM and JFFS2 file system on
+  Motorola FADS board and its derivatives (MPC86xADS, MPC885ADS).
+
+* Patch by Yuli Barcohen, 09 Jun 2004:
   Add support for Analogue&Micro Adder87x and the older AdderII board.
 
 * Patch by Ming-Len Wu, 09 Jun 2004:
index d4e9f02..9aed226 100644 (file)
@@ -91,6 +91,7 @@
 #define CONFIG_COMMANDS        (CONFIG_CMD_DFL   \
                         | CFG_CMD_DHCP   \
                         | CFG_CMD_IMMAP  \
+                        | CFG_CMD_JFFS2  \
                         | CFG_CMD_MII    \
                         | CFG_CMD_PCMCIA \
                         | CFG_CMD_PING   \
  * the maximum mapped by the Linux kernel during initialization.
  */
 #define        CFG_BOOTMAPSZ           (8 << 20)       /* Initial Memory map for Linux */
+
+#define CFG_MONITOR_BASE       TEXT_BASE
+#define        CFG_MONITOR_LEN         (256 << 10)     /* Reserve 256 KB for monitor   */
+
+#ifdef CONFIG_BZIP2
+#define        CFG_MALLOC_LEN          (2500 << 10)    /* Reserve ~2.5 MB for malloc() */
+#else
+#define        CFG_MALLOC_LEN          (384 << 10)     /* Reserve 384 kB for malloc()  */
+#endif /* CONFIG_BZIP2 */
+
 /*-----------------------------------------------------------------------
  * Flash organization
  */
-#define CFG_FLASH_BASE         TEXT_BASE
-#define CFG_FLASH_SIZE         ((uint)(8 * 1024 * 1024))       /* max 8Mbyte */
+#define CFG_FLASH_BASE         CFG_MONITOR_BASE
+#define CFG_FLASH_SIZE         ((uint)(8 * 1024 * 1024))       /* max 8Mbyte   */
 
-#define CFG_MAX_FLASH_BANKS    1       /* max number of memory banks           */
-#define CFG_MAX_FLASH_SECT     16      /* max number of sectors on one chip    */
+#define CFG_MAX_FLASH_BANKS    4       /* max number of memory banks           */
+#define CFG_MAX_FLASH_SECT           /* max number of sectors on one chip    */
 
 #define CFG_FLASH_ERASE_TOUT   120000  /* Timeout for Flash Erase (in ms)      */
 #define CFG_FLASH_WRITE_TOUT   500     /* Timeout for Flash Write (in ms)      */
 #define CFG_ENV_OFFSET         CFG_ENV_SECT_SIZE
 #define        CFG_ENV_SIZE            0x4000  /* Total Size of Environment            */
 
-#define CFG_MONITOR_BASE       CFG_FLASH_BASE
-#define        CFG_MONITOR_LEN         (256 << 10)     /* Reserve 256 KB for monitor   */
+#define        CFG_DIRECT_FLASH_TFTP
 
-#ifdef CONFIG_BZIP2
-#define        CFG_MALLOC_LEN          (2500 << 10)    /* Reserve ~2.5 MB for malloc() */
-#else
-#define        CFG_MALLOC_LEN          (384 << 10)     /* Reserve 384 kB for malloc()  */
-#endif /* CONFIG_BZIP2 */
+#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
+#define CFG_JFFS2_FIRST_BANK   0
+#define CFG_JFFS2_NUM_BANKS    CFG_MAX_FLASH_BANKS
+#define CFG_JFFS2_FIRST_SECTOR  4
+#define CFG_JFFS2_SORT_FRAGMENTS
+#endif /* CFG_CMD_JFFS2 */
 
 /*-----------------------------------------------------------------------
  * Cache Configuration
 #define BCSR1_PCCVCCON          BCSR1_PCCVCC0
 
 #define BCSR2_FLASH_PD_MASK      ((uint)0xF0000000)
+#define BCSR2_FLASH_PD_SHIFT     28
 #define BCSR2_DRAM_PD_MASK       ((uint)0x07800000)
 #define BCSR2_DRAM_PD_SHIFT      23
 #define BCSR2_EXTTOLI_MASK       ((uint)0x00780000)
index d2a46b2..f0fb621 100644 (file)
@@ -24,7 +24,7 @@
 #include <common.h>
 #include <mpc8xx.h>
 
-flash_info_t flash_info[CFG_MAX_FLASH_BANKS];  /* info for FLASH chips        */
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];  /* info for FLASH chips */
 
 #if defined(CFG_ENV_IS_IN_FLASH)
 # ifndef  CFG_ENV_ADDR
@@ -38,124 +38,103 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];     /* info for FLASH chips        */
 # endif
 #endif
 
+#define QUAD_ID(id)    ((((ulong)(id) & 0xFF) << 24) | \
+                        (((ulong)(id) & 0xFF) << 16) | \
+                        (((ulong)(id) & 0xFF) << 8)  | \
+                        (((ulong)(id) & 0xFF) << 0)    \
+                       )
+
 /*-----------------------------------------------------------------------
  * Functions
  */
 static ulong flash_get_size (vu_long * addr, flash_info_t * info);
 static int write_word (flash_info_t * info, ulong dest, ulong data);
-static void flash_get_offsets (ulong base, flash_info_t * info);
 
 /*-----------------------------------------------------------------------
  */
-
 unsigned long flash_init (void)
 {
        volatile immap_t *immap = (immap_t *) CFG_IMMR;
        volatile memctl8xx_t *memctl = &immap->im_memctl;
-       unsigned long total_size;
-       unsigned long size_b0, size_b1;
+       vu_long *bcsr = (vu_long *)BCSR_ADDR;
+       unsigned long pd_size, total_size, bsize, or_am;
        int i;
 
        /* Init: no FLASHes known */
        for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
                flash_info[i].flash_id = FLASH_UNKNOWN;
+               flash_info[i].size = 0;
+               flash_info[i].sector_count = 0;
+               flash_info[i].start[0] = 0xFFFFFFFF; /* For TFTP */
        }
 
-       total_size = 0;
-       size_b0 = 0xffffffff;
+       switch ((bcsr[2] & BCSR2_FLASH_PD_MASK) >> BCSR2_FLASH_PD_SHIFT) {
+       case 2:
+       case 4:
+       case 6:
+               pd_size = 0x800000;
+               or_am = 0xFF800000;
+               break;
 
-       for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
-               size_b1 =
-                       flash_get_size ((vu_long *) (CFG_FLASH_BASE +
-                                                    total_size),
-                                       &flash_info[i]);
+       case 5:
+       case 7:
+               pd_size = 0x400000;
+               or_am = 0xFFC00000;
+               break;
 
-               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
-                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", i, size_b1, size_b1 >> 20);
-               }
+       case 8:
+               pd_size = 0x200000;
+               or_am = 0xFFE00000;
+               break;
 
-               /* Is this really needed ? - LP */
-               if (size_b1 > size_b0) {
-                       printf ("## ERROR: Bank %d (0x%08lx = %ld MB) > Bank %d (0x%08lx = %ld MB)\n", i, size_b1, size_b1 >> 20, i - 1, size_b0, size_b0 >> 20);
-                       goto out_error;
-               }
-               size_b0 = size_b1;
-               total_size += size_b1;
+       default:
+               pd_size = 0;
+               or_am = 0xFFE00000;
+               printf("## Unsupported flash detected by BCSR: 0x%08X\n", bcsr[2]);
        }
 
-       /* Compute the Address Mask */
-       for (i = 0; (total_size >> i) != 0; ++i) {
+       total_size = 0;
+       for (i = 0; i < CFG_MAX_FLASH_BANKS && total_size < pd_size; ++i) {
+               bsize = flash_get_size((vu_long *)(CFG_FLASH_BASE + total_size),
+                                      &flash_info[i]);
+
+               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+                               i, bsize, bsize >> 20);
+               }
+
+               total_size += bsize;
        }
-       i--;
 
-       if (total_size != (1 << i)) {
-               printf ("## WARNING: Total FLASH size (0x%08lx = %ld MB) is not a power of 2\n", total_size, total_size >> 20);
+       if (total_size != pd_size) {
+               printf("## Detected flash size %lu conflicts with PD data %lu\n",
+                      total_size, pd_size);
        }
 
        /* Remap FLASH according to real size */
-       memctl->memc_or0 =
-               ((((unsigned long) ~0) << i) & OR_AM_MSK) |
-               CFG_OR_TIMING_FLASH;
-       memctl->memc_br0 = CFG_BR0_PRELIM;
-
-       total_size = 0;
+       memctl->memc_or0 = or_am | CFG_OR_TIMING_FLASH;
 
        for (i = 0; i < CFG_MAX_FLASH_BANKS && flash_info[i].size != 0; ++i) {
-               /* Re-do sizing to get full correct info */
-               /* Why ? - LP */
-               size_b1 =
-                       flash_get_size ((vu_long *) (CFG_FLASH_BASE +
-                                                    total_size),
-                                       &flash_info[i]);
-
-               /* This is done by flash_get_size - LP */
-               /* flash_get_offsets (CFG_FLASH_BASE + total_size, &flash_info[i]); */
-
 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
                /* monitor protection ON by default */
-               flash_protect (FLAG_PROTECT_SET,
-                              CFG_MONITOR_BASE,
-                              CFG_MONITOR_BASE + monitor_flash_len - 1,
-                              &flash_info[i]);
+               if (CFG_MONITOR_BASE >= flash_info[i].start[0])
+                       flash_protect (FLAG_PROTECT_SET,
+                                      CFG_MONITOR_BASE,
+                                      CFG_MONITOR_BASE + monitor_flash_len - 1,
+                                      &flash_info[i]);
 #endif
 
 #ifdef CFG_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_info[i]);
+               if (CFG_ENV_ADDR >= flash_info[i].start[0])
+                       flash_protect (FLAG_PROTECT_SET,
+                                      CFG_ENV_ADDR,
+                                      CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+                                      &flash_info[i]);
 #endif
-
-               total_size += size_b1;
        }
 
-       return (total_size);
-
-      out_error:
-       for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
-               flash_info[i].flash_id = FLASH_UNKNOWN;
-               flash_info[i].sector_count = -1;
-               flash_info[i].size = 0;
-       }
-
-       return (0);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void flash_get_offsets (ulong base, flash_info_t * info)
-{
-       int i;
-
-       /* set up sector start address table */
-       if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040
-           || (info->flash_id & FLASH_TYPEMASK) == FLASH_AM080) {
-               /* set sector offsets for uniform sector type   */
-               for (i = 0; i < info->sector_count; i++) {
-                       info->start[i] = base + (i * 0x00040000);
-               }
-       }
+       return total_size;
 }
 
 /*-----------------------------------------------------------------------
@@ -235,48 +214,26 @@ void flash_print_info (flash_info_t * info)
        }
 
        printf ("\n");
-       return;
 }
 
 /*-----------------------------------------------------------------------
+ * The following code can not run from flash!
  */
-
-
-/*-----------------------------------------------------------------------
- */
-
-/*
- * The following code cannot be run from FLASH!
- */
-
 static ulong flash_get_size (vu_long * addr, flash_info_t * info)
 {
        short i;
 
-#if 0
-       ulong base = (ulong) addr;
-#endif
-       uchar value;
-
        /* Write auto select command: read Manufacturer ID */
-#if 0
-       addr[0x0555] = 0x00AA00AA;
-       addr[0x02AA] = 0x00550055;
-       addr[0x0555] = 0x00900090;
-#else
        addr[0x0555] = 0xAAAAAAAA;
        addr[0x02AA] = 0x55555555;
        addr[0x0555] = 0x90909090;
-#endif
-
-       value = addr[0];
 
-       switch (value + (value << 16)) {
-       case AMD_MANUFACT:
+       switch (addr[0]) {
+       case QUAD_ID(AMD_MANUFACT):
                info->flash_id = FLASH_MAN_AMD;
                break;
 
-       case FUJ_MANUFACT:
+       case QUAD_ID(FUJ_MANUFACT):
                info->flash_id = FLASH_MAN_FUJ;
                break;
 
@@ -287,21 +244,20 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
                break;
        }
 
-       value = addr[1];        /* device ID            */
-
-       switch (value) {
-       case AMD_ID_F040B:
+       switch (addr[1]) {      /* device ID            */
+       case QUAD_ID(AMD_ID_F040B):
+       case QUAD_ID(AMD_ID_LV040B):
                info->flash_id += FLASH_AM040;
                info->sector_count = 8;
                info->size = 0x00200000;
                break;          /* => 2 MB              */
 
-       case AMD_ID_F080B:
+       case QUAD_ID(AMD_ID_F080B):
                info->flash_id += FLASH_AM080;
                info->sector_count = 16;
                info->size = 0x00400000;
                break;          /* => 4 MB              */
-
+#if 0
        case AMD_ID_LV400T:
                info->flash_id += FLASH_AM400T;
                info->sector_count = 11;
@@ -337,7 +293,7 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
                info->sector_count = 35;
                info->size = 0x00400000;
                break;          /* => 4 MB              */
-#if 0                          /* enable when device IDs are available */
+
        case AMD_ID_LV320T:
                info->flash_id += FLASH_AM320T;
                info->sector_count = 67;
@@ -349,11 +305,10 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
                info->sector_count = 67;
                info->size = 0x00800000;
                break;          /* => 8 MB              */
-#endif
+#endif /* 0 */
        default:
                info->flash_id = FLASH_UNKNOWN;
                return (0);     /* => no or unknown flash */
-
        }
 
 #if 0
@@ -378,7 +333,9 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
                }
        }
 #else
-       flash_get_offsets ((ulong) addr, info);
+       /* set sector offsets for uniform sector type */
+       for (i = 0; i < info->sector_count; i++)
+               info->start[i] = (ulong)addr + (i * 0x00040000);
 #endif
 
        /* check for protected sectors */
@@ -389,25 +346,16 @@ static ulong flash_get_size (vu_long * addr, flash_info_t * info)
                info->protect[i] = addr[2] & 1;
        }
 
-       /*
-        * Prevent writes to uninitialized FLASH.
-        */
        if (info->flash_id != FLASH_UNKNOWN) {
                addr = (volatile unsigned long *) info->start[0];
-#if 0
-               *addr = 0x00F000F0;     /* reset bank */
-#else
                *addr = 0xF0F0F0F0;     /* reset bank */
-#endif
        }
 
        return (info->size);
 }
 
-
 /*-----------------------------------------------------------------------
  */
-
 int flash_erase (flash_info_t * info, int s_first, int s_last)
 {
        vu_long *addr = (vu_long *) (info->start[0]);
@@ -420,13 +368,13 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
                } else {
                        printf ("- no sectors to erase\n");
                }
-               return 1;
+               return ERR_INVAL;
        }
 
        if ((info->flash_id == FLASH_UNKNOWN) ||
            (info->flash_id > FLASH_AMD_COMP)) {
                printf ("Can't erase unknown flash type - aborted\n");
-               return 1;
+               return ERR_UNKNOWN_FLASH_TYPE;
        }
 
        prot = 0;
@@ -447,29 +395,17 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
        /* Disable interrupts which might cause a timeout here */
        flag = disable_interrupts ();
 
-#if 0
-       addr[0x0555] = 0x00AA00AA;
-       addr[0x02AA] = 0x00550055;
-       addr[0x0555] = 0x00800080;
-       addr[0x0555] = 0x00AA00AA;
-       addr[0x02AA] = 0x00550055;
-#else
        addr[0x0555] = 0xAAAAAAAA;
        addr[0x02AA] = 0x55555555;
        addr[0x0555] = 0x80808080;
        addr[0x0555] = 0xAAAAAAAA;
        addr[0x02AA] = 0x55555555;
-#endif
 
        /* Start erase on unprotected sectors */
        for (sect = s_first; sect <= s_last; sect++) {
                if (info->protect[sect] == 0) { /* not protected */
                        addr = (vu_long *) (info->start[sect]);
-#if 0
-                       addr[0] = 0x00300030;
-#else
                        addr[0] = 0x30303030;
-#endif
                        l_sect = sect;
                }
        }
@@ -490,15 +426,11 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
        start = get_timer (0);
        last = start;
        addr = (vu_long *) (info->start[l_sect]);
-#if 0
-       while ((addr[0] & 0x00800080) != 0x00800080)
-#else
        while ((addr[0] & 0xFFFFFFFF) != 0xFFFFFFFF)
-#endif
        {
                if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
                        printf ("Timeout\n");
-                       return 1;
+                       return ERR_TIMOUT;
                }
                /* show that we're waiting */
                if ((now - last) > 1000) {      /* every second */
@@ -510,13 +442,10 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
       DONE:
        /* reset to read mode */
        addr = (volatile unsigned long *) info->start[0];
-#if 0
-       addr[0] = 0x00F000F0;   /* reset bank */
-#else
        addr[0] = 0xF0F0F0F0;   /* reset bank */
-#endif
 
        printf (" done\n");
+
        return 0;
 }
 
@@ -526,7 +455,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
  * 1 - write timeout
  * 2 - Flash not erased
  */
-
 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 {
        ulong cp, wp, data;
@@ -605,20 +533,14 @@ static int write_word (flash_info_t * info, ulong dest, ulong data)
 
        /* Check if Flash is (sufficiently) erased */
        if ((*((vu_long *) dest) & data) != data) {
-               return (2);
+               return ERR_NOT_ERASED;
        }
        /* Disable interrupts which might cause a timeout here */
        flag = disable_interrupts ();
 
-#if 0
-       addr[0x0555] = 0x00AA00AA;
-       addr[0x02AA] = 0x00550055;
-       addr[0x0555] = 0x00A000A0;
-#else
        addr[0x0555] = 0xAAAAAAAA;
        addr[0x02AA] = 0x55555555;
        addr[0x0555] = 0xA0A0A0A0;
-#endif
 
        *((vu_long *) dest) = data;
 
@@ -628,18 +550,11 @@ static int write_word (flash_info_t * info, ulong dest, ulong data)
 
        /* data polling for D7 */
        start = get_timer (0);
-#if 0
-       while ((*((vu_long *) dest) & 0x00800080) != (data & 0x00800080))
-#else
        while ((*((vu_long *) dest) & 0x80808080) != (data & 0x80808080))
-#endif
        {
                if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
-                       return (1);
+                       return ERR_TIMOUT;
                }
        }
        return (0);
 }
-
-/*-----------------------------------------------------------------------
- */
index 5fe5e22..b8f463a 100644 (file)
@@ -52,7 +52,7 @@ SECTIONS
   {
     cpu/mpc8xx/start.o         (.text)
 
-    . = DEFINED(env_offset) ? env_offset : .;
+    /*. = DEFINED(env_offset) ? env_offset : .;*/
     common/environment.o       (.ppcenv)
 
     *(.text)