Initial revision
authorwdenk <wdenk>
Sun, 3 Nov 2002 00:38:21 +0000 (00:38 +0000)
committerwdenk <wdenk>
Sun, 3 Nov 2002 00:38:21 +0000 (00:38 +0000)
124 files changed:
board/RPXlite/flash.c [new file with mode: 0644]
board/cogent/lcd.c [new file with mode: 0644]
board/cogent/lcd.h [new file with mode: 0644]
board/cray/L1/flash.c [new file with mode: 0644]
board/cray/L1/init.S [new file with mode: 0644]
board/dnp1110/config.mk [new file with mode: 0644]
board/dnp1110/memsetup.S [new file with mode: 0644]
board/ebony/flash.c [new file with mode: 0644]
board/eltec/mhpc/config.mk [new file with mode: 0644]
board/eric/flash.c [new file with mode: 0644]
board/eric/init.S [new file with mode: 0644]
board/esd/ar405/flash.c [new file with mode: 0644]
board/esd/canbt/flash.c [new file with mode: 0644]
board/esd/cpciiser4/flash.c [new file with mode: 0644]
board/esd/dasa_sim/eeprom.c [new file with mode: 0644]
board/evb64260/ecctest.c [new file with mode: 0644]
board/evb64260/eth.h [new file with mode: 0644]
board/evb64260/mpsc.c [new file with mode: 0644]
board/evb64260/zuma_pbb.c [new file with mode: 0644]
board/evb64260/zuma_pbb_mbox.c [new file with mode: 0644]
board/fads/fads.c [new file with mode: 0644]
board/genietv/genietv.c [new file with mode: 0644]
board/lart/config.mk [new file with mode: 0644]
board/lart/memsetup.S [new file with mode: 0644]
board/lubbock/memsetup.S [new file with mode: 0644]
board/mbx8xx/config.mk [new file with mode: 0644]
board/ml2/flash.c [new file with mode: 0644]
board/ml2/init.S [new file with mode: 0644]
board/ml2/ml2.c [new file with mode: 0644]
board/mousse/README [new file with mode: 0644]
board/mousse/mousse.h [new file with mode: 0644]
board/mvs1/README [new file with mode: 0644]
board/mvs1/mvs1.c [new file with mode: 0644]
board/ppmc8260/ppmc8260.c [new file with mode: 0644]
board/ppmc8260/strataflash.c [new file with mode: 0644]
board/rpxsuper/rpxsuper.c [new file with mode: 0644]
board/rsdproto/config.mk [new file with mode: 0644]
board/rsdproto/rsdproto.c [new file with mode: 0644]
board/sacsng/sacsng.c [new file with mode: 0644]
board/sandpoint/flash.c [new file with mode: 0644]
board/sbc8260/flash.c [new file with mode: 0644]
board/sbc8260/sbc8260.c [new file with mode: 0644]
board/shannon/config.mk [new file with mode: 0644]
board/shannon/memsetup.S [new file with mode: 0644]
board/siemens/IAD210/config.mk [new file with mode: 0644]
board/smdk2400/config.mk [new file with mode: 0644]
board/smdk2400/memsetup.S [new file with mode: 0644]
board/smdk2410/config.mk [new file with mode: 0644]
board/trab/config.mk [new file with mode: 0644]
board/trab/memsetup.S [new file with mode: 0644]
board/utx8245/flash.c [new file with mode: 0644]
board/walnut405/flash.c [new file with mode: 0644]
board/walnut405/init.S [new file with mode: 0644]
common/cmd_boot.c [new file with mode: 0644]
common/hush.c [new file with mode: 0644]
cpu/74xx_7xx/cache.S [new file with mode: 0644]
cpu/arm720t/start.S [new file with mode: 0644]
cpu/arm920t/start.S [new file with mode: 0644]
cpu/mpc8260/ether_scc.c [new file with mode: 0644]
cpu/ppc4xx/kgdb.S [new file with mode: 0644]
cpu/ppc4xx/resetvec.S [new file with mode: 0644]
cpu/ppc4xx/serial.c [new file with mode: 0644]
cpu/ppc4xx/spd_sdram.c [new file with mode: 0644]
cpu/sa1100/serial.c [new file with mode: 0644]
cpu/sa1100/start.S [new file with mode: 0644]
disk/part_dos.c [new file with mode: 0644]
disk/part_mac.c [new file with mode: 0644]
disk/part_mac.h [new file with mode: 0644]
doc/README.PIP405 [new file with mode: 0644]
doc/README.RPXlite [new file with mode: 0644]
doc/README.Sandpoint8240 [new file with mode: 0644]
drivers/3c589.c [new file with mode: 0644]
drivers/bcm570x_autoneg.c [new file with mode: 0644]
drivers/cs8900.h [new file with mode: 0644]
drivers/natsemi.c [new file with mode: 0644]
drivers/nicext.h [new file with mode: 0644]
drivers/ns8382x.c [new file with mode: 0644]
drivers/smc91111.c [new file with mode: 0644]
drivers/smc91111.h [new file with mode: 0644]
fs/jffs2/compr_rtime.c [new file with mode: 0644]
fs/jffs2/compr_rubin.c [new file with mode: 0644]
fs/jffs2/compr_zlib.c [new file with mode: 0644]
fs/jffs2/jffs2_1pass.c [new file with mode: 0644]
include/asm-ppc/pnp.h [new file with mode: 0644]
include/ata.h [new file with mode: 0644]
include/commproc.h [new file with mode: 0644]
include/configs/ML2.h [new file with mode: 0644]
include/configs/MOUSSE.h [new file with mode: 0644]
include/configs/csb226.h [new file with mode: 0644]
include/configs/gw8260.h [new file with mode: 0644]
include/configs/ppmc8260.h [new file with mode: 0644]
include/configs/sacsng.h [new file with mode: 0644]
include/configs/sbc8260.h [new file with mode: 0644]
include/galileo/pci.h [new file with mode: 0644]
include/jffs2/jffs2.h [new file with mode: 0644]
include/jffs2/load_kernel.h [new file with mode: 0644]
include/lcd.h [new file with mode: 0644]
include/pci_ids.h [new file with mode: 0644]
include/video_ad7177.h [new file with mode: 0644]
include/video_logo.h [new file with mode: 0644]
lib_ppc/board.c [new file with mode: 0644]
lib_ppc/extable.c [new file with mode: 0644]
net/tftp.c [new file with mode: 0644]
rtc/ds1302.c [new file with mode: 0644]
rtc/pcf8563.c [new file with mode: 0644]
tools/bddb/README [new file with mode: 0644]
tools/bddb/brlog.php [new file with mode: 0644]
tools/bddb/browse.php [new file with mode: 0644]
tools/bddb/config.php [new file with mode: 0644]
tools/bddb/create_tables.sql [new file with mode: 0644]
tools/bddb/defs.php [new file with mode: 0644]
tools/bddb/dodelete.php [new file with mode: 0644]
tools/bddb/dodellog.php [new file with mode: 0644]
tools/bddb/doedit.php [new file with mode: 0644]
tools/bddb/doedlog.php [new file with mode: 0644]
tools/bddb/donew.php [new file with mode: 0644]
tools/bddb/donewlog.php [new file with mode: 0644]
tools/bddb/edit.php [new file with mode: 0644]
tools/bddb/edlog.php [new file with mode: 0644]
tools/bddb/execute.php [new file with mode: 0644]
tools/bddb/index.php [new file with mode: 0644]
tools/bddb/new.php [new file with mode: 0644]
tools/bddb/newlog.php [new file with mode: 0644]
tools/easylogo/easylogo.c [new file with mode: 0644]

diff --git a/board/RPXlite/flash.c b/board/RPXlite/flash.c
new file mode 100644 (file)
index 0000000..78c1838
--- /dev/null
@@ -0,0 +1,524 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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
+ */
+
+/*
+ * Yoo. Jonghoon, IPone, yooth@ipone.co.kr
+ * U-Boot port on RPXlite board
+ *
+ * Some of flash control words are modified. (from 2x16bit device
+ * to 4x8bit device)
+ * RPXLite board I tested has only 4 AM29LV800BB devices. Other devices
+ * are not tested.
+ *
+ * (?) Does an RPXLite board which
+ *     does not use AM29LV800 flash memory exist ?
+ *     I don't know...
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+/*-----------------------------------------------------------------------
+ * 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 size_b0 ;
+       int i;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+/*
+       size_b0 = flash_get_size((vu_long *)FLASH_BASE_DEBUG, &flash_info[0]);
+
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+*/
+       /* Remap FLASH according to real size */
+/*%%%
+       memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
+       memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
+%%%*/
+       /* Re-do sizing to get full correct info */
+
+       size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
+       flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+       /* monitor protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_MONITOR_BASE,
+                     CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+                     &flash_info[0]);
+#endif
+
+       flash_info[0].size = size_b0;
+
+       return (size_b0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       /* set up sector start address table */
+       if (info->flash_id & FLASH_BTYPE) {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00010000;
+               info->start[2] = base + 0x00018000;
+               info->start[3] = base + 0x00020000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i-3) * 0x00040000) ;
+               }
+       } else {
+               /* set sector offsets for top boot block type           */
+               i = info->sector_count - 1;
+               info->start[i--] = base + info->size - 0x00010000;
+               info->start[i--] = base + info->size - 0x00018000;
+               info->start[i--] = base + info->size - 0x00020000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00040000;
+               }
+       }
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+                               break;
+       default:                printf ("Unknown Chip Type\n");
+                               break;
+       }
+
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     "
+               );
+       }
+       printf ("\n");
+       return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+       short i;
+       ulong value;
+       ulong base = (ulong)addr;
+
+       /* Write auto select command: read Manufacturer ID */
+       addr[0xAAA] = 0x00AA00AA ;
+       addr[0x555] = 0x00550055 ;
+       addr[0xAAA] = 0x00900090 ;
+
+       value = addr[0] ;
+
+       switch (value & 0x00FF00FF) {
+       case AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+       case FUJ_MANUFACT:
+               info->flash_id = FLASH_MAN_FUJ;
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* no or unknown flash  */
+       }
+
+       value = addr[2] ;               /* device ID            */
+
+       switch (value & 0x00FF00FF) {
+       case (AMD_ID_LV400T & 0x00FF00FF):
+               info->flash_id += FLASH_AM400T;
+               info->sector_count = 11;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (AMD_ID_LV400B & 0x00FF00FF):
+               info->flash_id += FLASH_AM400B;
+               info->sector_count = 11;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (AMD_ID_LV800T & 0x00FF00FF):
+               info->flash_id += FLASH_AM800T;
+               info->sector_count = 19;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (AMD_ID_LV800B & 0x00FF00FF):
+               info->flash_id += FLASH_AM800B;
+               info->sector_count = 19;
+               info->size = 0x00400000;        /*%%% Size doubled by yooth */
+               break;                          /* => 4 MB              */
+
+       case (AMD_ID_LV160T & 0x00FF00FF):
+               info->flash_id += FLASH_AM160T;
+               info->sector_count = 35;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (AMD_ID_LV160B & 0x00FF00FF):
+               info->flash_id += FLASH_AM160B;
+               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;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+
+       case AMD_ID_LV320B:
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 67;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+#endif
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               return (0);                     /* => no or unknown flash */
+
+       }
+       /*%%% sector start address modified */
+       /* set up sector start address table */
+       if (info->flash_id & FLASH_BTYPE) {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00010000;
+               info->start[2] = base + 0x00018000;
+               info->start[3] = base + 0x00020000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i-3) * 0x00040000) ;
+               }
+       } else {
+               /* set sector offsets for top boot block type           */
+               i = info->sector_count - 1;
+               info->start[i--] = base + info->size - 0x00010000;
+               info->start[i--] = base + info->size - 0x00018000;
+               info->start[i--] = base + info->size - 0x00020000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00040000;
+               }
+       }
+
+       /* check for protected sectors */
+       for (i = 0; i < info->sector_count; i++) {
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+               addr = (volatile unsigned long *)(info->start[i]);
+               info->protect[i] = addr[4] & 1 ;
+       }
+
+       /*
+        * Prevent writes to uninitialized FLASH.
+        */
+       if (info->flash_id != FLASH_UNKNOWN) {
+               addr = (volatile unsigned long *)info->start[0];
+
+               *addr = 0xF0F0F0F0;     /* reset bank */
+       }
+
+       return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       vu_long *addr = (vu_long*)(info->start[0]);
+       int flag, prot, sect, l_sect;
+       ulong start, now, last;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       if ((info->flash_id == FLASH_UNKNOWN) ||
+           (info->flash_id > FLASH_AMD_COMP)) {
+               printf ("Can't erase unknown flash type %08lx - aborted\n",
+                       info->flash_id);
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       l_sect = -1;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       addr[0xAAA] = 0xAAAAAAAA;
+       addr[0x555] = 0x55555555;
+       addr[0xAAA] = 0x80808080;
+       addr[0xAAA] = 0xAAAAAAAA;
+       addr[0x555] = 0x55555555;
+
+       /* 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]) ;
+                       addr[0] = 0x30303030 ;
+                       l_sect = sect;
+               }
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* wait at least 80us - let's wait 1 ms */
+       udelay (1000);
+
+       /*
+        * We wait for the last triggered sector
+        */
+       if (l_sect < 0)
+               goto DONE;
+
+       start = get_timer (0);
+       last  = start;
+       addr = (vu_long *)(info->start[l_sect]);
+       while ((addr[0] & 0x80808080) != 0x80808080) {
+               if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                       printf ("Timeout\n");
+                       return 1;
+               }
+               /* show that we're waiting */
+               if ((now - last) > 1000) {      /* every second */
+                       putc ('.');
+                       last = now;
+               }
+       }
+
+DONE:
+       /* reset to read mode */
+       addr = (vu_long *)info->start[0];
+       addr[0] = 0xF0F0F0F0;   /* reset bank */
+
+       printf (" done\n");
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong cp, wp, data;
+       int i, l, rc;
+
+       wp = (addr & ~3);       /* get lower word aligned address */
+
+       /*
+        * handle unaligned start bytes
+        */
+       if ((l = addr - wp) != 0) {
+               data = 0;
+               for (i=0, cp=wp; i<l; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+               for (; i<4 && cnt>0; ++i) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+                       ++cp;
+               }
+               for (; cnt==0 && i<4; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp += 4;
+       }
+
+       /*
+        * handle word aligned part
+        */
+       while (cnt >= 4) {
+               data = 0;
+               for (i=0; i<4; ++i) {
+                       data = (data << 8) | *src++;
+               }
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp  += 4;
+               cnt -= 4;
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       data = 0;
+       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i<4; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *)cp);
+       }
+
+       return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+       vu_long *addr = (vu_long *)(info->start[0]);
+       ulong start;
+       int flag;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((vu_long *)dest) & data) != data) {
+               return (2);
+       }
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       addr[0xAAA] = 0xAAAAAAAA;
+       addr[0x555] = 0x55555555;
+       addr[0xAAA] = 0xA0A0A0A0;
+
+       *((vu_long *)dest) = data;
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* data polling for D7 */
+       start = get_timer (0);
+       while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       return (1);
+               }
+       }
+       return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/cogent/lcd.c b/board/cogent/lcd.c
new file mode 100644 (file)
index 0000000..941ea65
--- /dev/null
@@ -0,0 +1,231 @@
+/* most of this is taken from the file */
+/* hal/powerpc/cogent/current/src/hal_diag.c in the */
+/* Cygnus eCos source. Here is the copyright notice: */
+/* */
+/*============================================================================= */
+/* */
+/*      hal_diag.c */
+/* */
+/*      HAL diagnostic output code */
+/* */
+/*============================================================================= */
+/*####COPYRIGHTBEGIN#### */
+/* */
+/* ------------------------------------------- */
+/* The contents of this file are subject to the Cygnus eCos Public License */
+/* Version 1.0 (the "License"); you may not use this file except in */
+/* compliance with the License.  You may obtain a copy of the License at */
+/* http://sourceware.cygnus.com/ecos */
+/* */
+/* Software distributed under the License is distributed on an "AS IS" */
+/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the */
+/* License for the specific language governing rights and limitations under */
+/* the License. */
+/* */
+/* The Original Code is eCos - Embedded Cygnus Operating System, released */
+/* September 30, 1998. */
+/* */
+/* The Initial Developer of the Original Code is Cygnus.  Portions created */
+/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved. */
+/* ------------------------------------------- */
+/* */
+/*####COPYRIGHTEND#### */
+/*============================================================================= */
+/*#####DESCRIPTIONBEGIN#### */
+/* */
+/* Author(s):    nickg, jskov */
+/* Contributors: nickg, jskov */
+/* Date:         1999-03-23 */
+/* Purpose:      HAL diagnostic output */
+/* Description:  Implementations of HAL diagnostic output support. */
+/* */
+/*####DESCRIPTIONEND#### */
+/* */
+/*============================================================================= */
+
+/*----------------------------------------------------------------------------- */
+/* Cogent board specific LCD code */
+
+#include <common.h>
+#include <stdarg.h>
+#include <board/cogent/lcd.h>
+
+static char lines[2][LCD_LINE_LENGTH+1];
+static int curline;
+static int linepos;
+static int heartbeat_active;
+/* make the next two strings exactly LCD_LINE_LENGTH (16) chars long */
+/* pad to the right with spaces if necessary */
+static char init_line0[LCD_LINE_LENGTH+1] = "U-Boot Cogent  ";
+static char init_line1[LCD_LINE_LENGTH+1] = "mjj, 11 Aug 2000";
+
+static inline unsigned char
+lcd_read_status(cma_mb_lcd *clp)
+{
+    /* read the Busy Status Register */
+    return (cma_mb_reg_read(&clp->lcd_bsr));
+}
+
+static inline void
+lcd_wait_not_busy(cma_mb_lcd *clp)
+{
+    /*
+     * wait for not busy
+     * Note: It seems that the LCD isn't quite ready to process commands
+     * when it clears the BUSY flag. Reading the status address an extra
+     * time seems to give it enough breathing room.
+     */
+
+    while (lcd_read_status(clp) & LCD_STAT_BUSY)
+       ;
+
+    (void)lcd_read_status(clp);
+}
+
+static inline void
+lcd_write_command(cma_mb_lcd *clp, unsigned char cmd)
+{
+    lcd_wait_not_busy(clp);
+
+    /* write the Command Register */
+    cma_mb_reg_write(&clp->lcd_cmd, cmd);
+}
+
+static inline void
+lcd_write_data(cma_mb_lcd *clp, unsigned char data)
+{
+    lcd_wait_not_busy(clp);
+
+    /* write the Current Character Register */
+    cma_mb_reg_write(&clp->lcd_ccr, data);
+}
+
+static inline void
+lcd_dis(int addr, char *string)
+{
+    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
+    int pos, linelen;
+
+    linelen = LCD_LINE_LENGTH;
+    if (heartbeat_active && addr == LCD_LINE0)
+       linelen--;
+
+    lcd_write_command(clp, LCD_CMD_ADD + addr);
+    for (pos = 0; *string != '\0' && pos < linelen; pos++)
+        lcd_write_data(clp, *string++);
+}
+
+void
+lcd_init(void)
+{
+    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
+    int i;
+
+    /* configure the lcd for 8 bits/char, 2 lines and 5x7 dot matrix */
+    lcd_write_command(clp, LCD_CMD_MODE);
+
+    /* turn the LCD display on */
+    lcd_write_command(clp, LCD_CMD_DON);
+
+    curline = 0;
+    linepos = 0;
+
+    for (i = 0; i < LCD_LINE_LENGTH; i++) {
+        lines[0][i] = init_line0[i];
+       lines[1][i] = init_line1[i];
+    }
+
+    lines[0][LCD_LINE_LENGTH] = lines[1][LCD_LINE_LENGTH] = 0;
+
+    lcd_dis(LCD_LINE0, lines[0]);
+    lcd_dis(LCD_LINE1, lines[1]);
+
+    printf("HD44780 2 line x %d char display\n", LCD_LINE_LENGTH);
+}
+
+void
+lcd_write_char(const char c)
+{
+    int i, linelen;
+
+    /* ignore CR */
+    if (c == '\r')
+       return;
+
+    linelen = LCD_LINE_LENGTH;
+    if (heartbeat_active && curline == 0)
+       linelen--;
+
+    if (c == '\n') {
+        lcd_dis(LCD_LINE0, &lines[curline^1][0]);
+        lcd_dis(LCD_LINE1, &lines[curline][0]);
+
+        /* Do a line feed */
+        curline ^= 1;
+       linelen = LCD_LINE_LENGTH;
+       if (heartbeat_active && curline == 0)
+           linelen--;
+        linepos = 0;
+
+        for (i = 0; i < linelen; i++)
+            lines[curline][i] = ' ';
+
+        return;
+    }
+
+    /* Only allow to be output if there is room on the LCD line */
+    if (linepos < linelen)
+        lines[curline][linepos++] = c;
+}
+
+void
+lcd_flush(void)
+{
+    lcd_dis(LCD_LINE1, &lines[curline][0]);
+}
+
+void
+lcd_write_string(const char *s)
+{
+    char *p;
+
+    for (p = (char *)s; *p != '\0'; p++)
+       lcd_write_char(*p);
+}
+
+void
+lcd_printf(const char *fmt, ...)
+{
+    va_list args;
+    char buf[CFG_PBSIZE];
+
+    va_start(args, fmt);
+    (void)vsprintf(buf, fmt, args);
+    va_end(args);
+
+    lcd_write_string(buf);
+}
+
+void
+lcd_heartbeat(void)
+{
+    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
+#if 0
+    static char rotchars[] = { '|', '/', '-', '\\' };
+#else
+    /* HD44780 Rom Code A00 has no backslash */
+    static char rotchars[] = { '|', '/', '-', '\315' };
+#endif
+    static int rotator_index = 0;
+
+    heartbeat_active = 1;
+
+    /* write the address */
+    lcd_write_command(clp, LCD_CMD_ADD + LCD_LINE0 + (LCD_LINE_LENGTH - 1));
+
+    /* write the next char in the sequence */
+    lcd_write_data(clp, rotchars[rotator_index]);
+
+    if (++rotator_index >= (sizeof rotchars / sizeof rotchars[0]))
+       rotator_index = 0;
+}
diff --git a/board/cogent/lcd.h b/board/cogent/lcd.h
new file mode 100644 (file)
index 0000000..1056eea
--- /dev/null
@@ -0,0 +1,84 @@
+/* most of this is taken from the file */
+/* hal/powerpc/cogent/current/src/hal_diag.c in the */
+/* Cygnus eCos source. Here is the copyright notice: */
+/* */
+/*============================================================================= */
+/* */
+/*      hal_diag.c */
+/* */
+/*      HAL diagnostic output code */
+/* */
+/*============================================================================= */
+/*####COPYRIGHTBEGIN#### */
+/* */
+/* ------------------------------------------- */
+/* The contents of this file are subject to the Cygnus eCos Public License */
+/* Version 1.0 (the "License"); you may not use this file except in */
+/* compliance with the License.  You may obtain a copy of the License at */
+/* http://sourceware.cygnus.com/ecos */
+/* */
+/* Software distributed under the License is distributed on an "AS IS" */
+/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the */
+/* License for the specific language governing rights and limitations under */
+/* the License. */
+/* */
+/* The Original Code is eCos - Embedded Cygnus Operating System, released */
+/* September 30, 1998. */
+/* */
+/* The Initial Developer of the Original Code is Cygnus.  Portions created */
+/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved. */
+/* ------------------------------------------- */
+/* */
+/*####COPYRIGHTEND#### */
+/*============================================================================= */
+/*#####DESCRIPTIONBEGIN#### */
+/* */
+/* Author(s):    nickg, jskov */
+/* Contributors: nickg, jskov */
+/* Date:         1999-03-23 */
+/* Purpose:      HAL diagnostic output */
+/* Description:  Implementations of HAL diagnostic output support. */
+/* */
+/*####DESCRIPTIONEND#### */
+/* */
+/*============================================================================= */
+
+/* FEMA 162B 16 character x 2 line LCD */
+
+/* status register bit definitions */
+#define LCD_STAT_BUSY  0x80    /* 1 = display busy */
+#define LCD_STAT_ADD   0x7F    /* bits 0-6 return current display address */
+
+/* command register definitions */
+#define LCD_CMD_RST    0x01    /* clear entire display and reset display addr */
+#define LCD_CMD_HOME   0x02    /* reset display address and reset any shifting */
+#define LCD_CMD_ECL    0x04    /* move cursor left one pos on next data write */
+#define LCD_CMD_ESL    0x05    /* shift display left one pos on next data write */
+#define LCD_CMD_ECR    0x06    /* move cursor right one pos on next data write */
+#define LCD_CMD_ESR    0x07    /* shift disp right one pos on next data write */
+#define LCD_CMD_DOFF   0x08    /* display off, cursor off, blinking off */
+#define LCD_CMD_BL     0x09    /* blink character at current cursor position */
+#define LCD_CMD_CUR    0x0A    /* enable cursor on */
+#define LCD_CMD_DON    0x0C    /* turn display on */
+#define LCD_CMD_CL     0x10    /* move cursor left one position */
+#define LCD_CMD_SL     0x14    /* shift display left one position */
+#define LCD_CMD_CR     0x18    /* move cursor right one position */
+#define LCD_CMD_SR     0x1C    /* shift display right one position */
+#define LCD_CMD_MODE   0x38    /* sets 8 bits, 2 lines, 5x7 characters */
+#define LCD_CMD_ACG    0x40    /* bits 0-5 sets character generator address */
+#define LCD_CMD_ADD    0x80    /* bits 0-6 sets display data addr to line 1 + */
+
+/* LCD status values */
+#define LCD_OK         0x00
+#define LCD_ERR        0x01
+
+#define LCD_LINE0      0x00
+#define LCD_LINE1      0x40
+
+#define LCD_LINE_LENGTH        16
+
+extern void lcd_init(void);
+extern void lcd_write_char(const char);
+extern void lcd_flush(void);
+extern void lcd_write_string(const char *);
+extern void lcd_printf(const char *, ...);
diff --git a/board/cray/L1/flash.c b/board/cray/L1/flash.c
new file mode 100644 (file)
index 0000000..6d66905
--- /dev/null
@@ -0,0 +1,471 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+/*
+ * Modified July 20, 2001
+ * Strip down to support ONLY the AMD29F032B.
+ * Dave Updegraff - Cray, Inc. dave@cray.com
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/* The flash chip we use... */
+#define AMD_ID_F032B   0x41    /* 29F032B ID  32 Mbit,64 64Kx8 sectors */
+#define FLASH_AM320B    0x0009
+
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+/*-----------------------------------------------------------------------
+ * 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);
+
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       unsigned long size_b0, size_b1;
+       int i;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+
+       size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+
+       /* Only one bank */
+       if (CFG_MAX_FLASH_BANKS == 1)
+         {
+           /* Setup offsets */
+           flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
+
+#if 0
+           /* Monitor protection ON by default */
+           (void)flash_protect(FLAG_PROTECT_SET,
+                               FLASH_BASE0_PRELIM,
+                               FLASH_BASE0_PRELIM+CFG_MONITOR_LEN-1,
+                               &flash_info[0]);
+#endif
+           size_b1 = 0 ;
+           flash_info[0].size = size_b0;
+         }
+
+       return (size_b0 + size_b1);
+}
+
+
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       /* set up sector start address table */
+       for (i = 0; i < info->sector_count; i++)
+               info->start[i] = base + (i * 0x00010000);
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+        int k;
+        int size;
+        int erased;
+        volatile unsigned long *flash;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM320B:printf ("AM29F032B (32 Mbit 64x64KB uniform sectors)\n");
+                               break;
+       default:                printf ("Unknown Chip Type\n");
+                               break;
+       }
+
+       printf ("  Size: %ld KB in %d Sectors\n",
+               info->size >> 10, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+                /*
+                 * Check if whole sector is erased
+                 */
+                if (i != (info->sector_count-1))
+                  size = info->start[i+1] - info->start[i];
+                else
+                  size = info->start[0] + info->size - info->start[i];
+                erased = 1;
+                flash = (volatile unsigned long *)info->start[i];
+                size = size >> 2;        /* divide by 4 for longword access */
+                for (k=0; k<size; k++)
+                  {
+                    if (*flash++ != 0xffffffff)
+                      {
+                        erased = 0;
+                        break;
+                      }
+                  }
+
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+
+               printf (" %08lX%s%s",
+                       info->start[i],
+                       erased ? " E" : "  ",
+                       info->protect[i] ? "RO " : "   "
+               );
+       }
+       printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+       short i;
+       FLASH_WORD_SIZE value;
+       ulong base = (ulong)addr;
+        volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+       /* Write auto select command: read Manufacturer ID */
+       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+       addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+
+       value = addr2[0];
+
+       switch (value) {
+       case (FLASH_WORD_SIZE)AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* no or unknown flash  */
+       }
+
+       value = addr2[1];                       /* device ID            */
+
+       switch (value) {
+       case (FLASH_WORD_SIZE)AMD_ID_F032B:
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 64;
+               info->size = 0x0400000; /* => 4 MB */
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               return (0);                     /* => no or unknown flash */
+
+       }
+
+       /* set up sector start address table */
+       for (i = 0; i < info->sector_count; i++)
+               info->start[i] = base + (i * 0x00010000);
+
+       /* check for protected sectors */
+       for (i = 0; i < info->sector_count; i++) {
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+               addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+        info->protect[i] = addr2[2] & 1;
+       }
+
+       /*
+        * Prevent writes to uninitialized FLASH.
+        */
+       if (info->flash_id != FLASH_UNKNOWN) {
+               addr2 = (FLASH_WORD_SIZE *)info->start[0];
+               *addr2 = (FLASH_WORD_SIZE)0x00F000F0;   /* reset bank */
+       }
+
+       return (info->size);
+}
+
+int wait_for_DQ7(flash_info_t *info, int sect)
+{
+       ulong start, now, last;
+       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+       start = get_timer (0);
+    last  = start;
+    while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+        if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+            printf ("Timeout\n");
+            return -1;
+        }
+        /* show that we're waiting */
+        if ((now - last) > 1000) {  /* every second */
+            putc ('.');
+            last = now;
+        }
+    }
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+       volatile FLASH_WORD_SIZE *addr2;
+       int flag, prot, sect, l_sect;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("Can't erase unknown flash type - aborted\n");
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       l_sect = -1;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                   addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
+                   printf("Erasing sector %p\n", addr2);
+
+                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                       addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                       addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                       addr2[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */
+                   l_sect = sect;
+                   /*
+                    * Wait for each sector to complete, it's more
+                    * reliable.  According to AMD Spec, you must
+                    * issue all erase commands within a specified
+                    * timeout.  This has been seen to fail, especially
+                    * if printf()s are included (for debug)!!
+                    */
+                   wait_for_DQ7(info, sect);
+               }
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* wait at least 80us - let's wait 1 ms */
+       udelay (1000);
+
+       /* reset to read mode */
+       addr = (FLASH_WORD_SIZE *)info->start[0];
+       addr[0] = (FLASH_WORD_SIZE)0x00F000F0;  /* reset bank */
+
+       printf (" done\n");
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong cp, wp, data;
+       int i, l, rc;
+
+       wp = (addr & ~3);       /* get lower word aligned address */
+
+       /*
+        * handle unaligned start bytes
+        */
+       if ((l = addr - wp) != 0) {
+               data = 0;
+               for (i=0, cp=wp; i<l; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+               for (; i<4 && cnt>0; ++i) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+                       ++cp;
+               }
+               for (; cnt==0 && i<4; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp += 4;
+       }
+
+       /*
+        * handle word aligned part
+        */
+       while (cnt >= 4) {
+               data = 0;
+               for (i=0; i<4; ++i) {
+                       data = (data << 8) | *src++;
+               }
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp  += 4;
+               cnt -= 4;
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       data = 0;
+       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i<4; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *)cp);
+       }
+
+       return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+        volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
+        volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
+        volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
+       ulong start;
+       int flag;
+        int i;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((volatile FLASH_WORD_SIZE *)dest) &
+             (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
+               return (2);
+       }
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+        for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
+          {
+            addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+            addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+            addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
+
+            dest2[i] = data2[i];
+
+            /* re-enable interrupts if necessary */
+            if (flag)
+              enable_interrupts();
+
+            /* data polling for D7 */
+            start = get_timer (0);
+            while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
+                   (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
+              if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                return (1);
+              }
+            }
+          }
+
+       return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/cray/L1/init.S b/board/cray/L1/init.S
new file mode 100644 (file)
index 0000000..acc5205
--- /dev/null
@@ -0,0 +1,147 @@
+/*------------------------------------------------------------------------------+ */
+/* */
+/*       This source code has been made available to you by IBM on an AS-IS */
+/*       basis.  Anyone receiving this source is licensed under IBM */
+/*       copyrights to use it in any way he or she deems fit, including */
+/*       copying it, modifying it, compiling it, and redistributing it either */
+/*       with or without modifications.  No license under IBM patents or */
+/*       patent applications is to be implied by the copyright license. */
+/* */
+/*       Any user of this software should understand that IBM cannot provide */
+/*       technical support for this software and will not be responsible for */
+/*       any consequences resulting from the use of this software. */
+/* */
+/*       Any person who transfers this source code or any derivative work */
+/*       must include the IBM copyright notice, this paragraph, and the */
+/*       preceding two paragraphs in the transferred software. */
+/* */
+/*       COPYRIGHT   I B M   CORPORATION 1995 */
+/*       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M */
+/*------------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------- */
+/* Function:     ext_bus_cntlr_init */
+/* Description:  Initializes the External Bus Controller for the external */
+/*             peripherals. IMPORTANT: For pass1 this code must run from */
+/*             cache since you can not reliably change a peripheral banks */
+/*             timing register (pbxap) while running code from that bank. */
+/*             For ex., since we are running from ROM on bank 0, we can NOT */
+/*             execute the code that modifies bank 0 timings from ROM, so */
+/*             we run it from cache. */
+/*     Bank 0 - Flash and SRAM */
+/*     Bank 1 - NVRAM/RTC */
+/*     Bank 2 - Keyboard/Mouse controller */
+/*     Bank 3 - IR controller */
+/*     Bank 4 - not used */
+/*     Bank 5 - not used */
+/*     Bank 6 - not used */
+/*     Bank 7 - FPGA registers */
+/*-----------------------------------------------------------------------------#include <config.h> */
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1      /* avoid reading Linux autoconf.h file  */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/* CRAY - L1: only nominally a 'walnut', since ext.Bus.Cntlr is all empty */
+/*     except for #1 which we use for DMA'ing to IOCA-like things, so the */
+/*     control registers to set that up are determined by what we've */
+/*     empirically discovered work there. */
+
+       .globl  ext_bus_cntlr_init
+ext_bus_cntlr_init:
+        mflr    r4                      /* save link register */
+        bl      ..getAddr
+..getAddr:
+        mflr    r3                      /* get address of ..getAddr */
+        mtlr    r4                      /* restore link register */
+        addi    r4,0,14                 /* set ctr to 10; used to prefetch */
+        mtctr   r4                      /* 10 cache lines to fit this function */
+                                        /* in cache (gives us 8x10=80 instrctns) */
+..ebcloop:
+        icbt    r0,r3                   /* prefetch cache line for addr in r3 */
+        addi    r3,r3,32               /* move to next cache line */
+        bdnz    ..ebcloop               /* continue for 10 cache lines */
+
+        /*------------------------------------------------------------------- */
+        /* Delay to ensure all accesses to ROM are complete before changing */
+           /* bank 0 timings. 200usec should be enough. */
+        /*   200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+        /*------------------------------------------------------------------- */
+       addis   r3,0,0x0
+        ori     r3,r3,0xA000          /* ensure 200usec have passed since reset */
+        mtctr   r3
+..spinlp:
+        bdnz    ..spinlp                /* spin loop */
+
+
+        /*---------------------------------------------------------------------- */
+        /* Peripheral Bank 0 (Flash) initialization */
+        /*---------------------------------------------------------------------- */
+               /* 0x7F8FFE80 slowest boot */
+        addi    r4,0,pb0ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,0x9B01
+        ori     r4,r4,0x5480
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb0cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,0xFFC5           /* BAS=0xFFC,BS=0x4(4MB),BU=0x3(R/W), */
+        ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */
+        mtdcr   ebccfgd,r4
+
+        blr
+
+        /*---------------------------------------------------------------------- */
+        /* Peripheral Bank 1 (NVRAM/RTC) initialization */
+               /* CRAY:the L1 has NOT this bank, it is tied to SV2/IOCA/etc/ instead */
+               /* and we do DMA on it.  The ConfigurationRegister part is threfore */
+               /* almost arbitrary, except that our linux driver needs to know the */
+               /* address, but it can query, it.. */
+               /* */
+               /* The AccessParameter is CRITICAL, */
+               /* thouch, since it needs to agree with the electrical timings on the */
+               /* IOCA parallel interface.  That value is: 0x0185,4380 */
+               /* BurstModeEnable                      BME=0 */
+               /* TransferWait                         TWT=3 */
+               /* ChipSelectOnTiming           CSN=1 */
+               /* OutputEnableOnTimimg         OEN=1 */
+               /* WriteByteEnableOnTiming      WBN=1 */
+               /* WriteByteEnableOffTiming     WBF=0 */
+               /* TransferHold                         TH=1 */
+               /* ReadyEnable                          RE=1 */
+               /* SampleOnReady                        SOR=1 */
+               /* ByteEnableMode                       BEM=0 */
+               /* ParityEnable                         PEN=0 */
+               /* all reserved bits=0 */
+        /*---------------------------------------------------------------------- */
+        /*---------------------------------------------------------------------- */
+        addi    r4,0,pb1ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,0x0185            /* hiword */
+        ori     r4,r4,0x4380   /* loword */
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb1cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,0xF001           /* BAS=0xF00,BS=0x0(1MB),BU=0x3(R/W), */
+        ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */
+        mtdcr   ebccfgd,r4
+
+        blr
+
+/*----------------------------------------------------------------------------- */
+/* Function:   sdram_init */
+/* Description:        Configures SDRAM memory banks. */
+/*                             NOTE: for CrayL1 we have ECC memory, so enable it. */
+/*....now done in C in L1.c:init_sdram for readability. */
+/*----------------------------------------------------------------------------- */
+        .globl  sdram_init
+
+sdram_init:
+ blr
diff --git a/board/dnp1110/config.mk b/board/dnp1110/config.mk
new file mode 100644 (file)
index 0000000..72ba595
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# DNP/1110 board with SA1100 cpu
+#
+# http://www.dilnetpc.com
+#
+
+#
+# DILNETPC has 1 banks of 32 MB DRAM
+#
+# c000'0000
+#
+# Linux-Kernel is expected to be at c000'8000, entry c000'8000
+#
+# we load ourself to c1f0'0000, the upper 1 MB of the first (only) bank
+#
+
+TEXT_BASE = 0xc1f00000
diff --git a/board/dnp1110/memsetup.S b/board/dnp1110/memsetup.S
new file mode 100644 (file)
index 0000000..bebd697
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * 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
+ */
+
+
+
+#include <config.h>
+#include <version.h>
+
+
+/* some parameters for the board */
+
+MEM_BASE:      .long   0xa0000000
+MEM_START:     .long   0xc0000000
+
+#define        MDCNFG  0x00
+#define MDCAS0 0x04
+#define MDCAS1 0x08
+#define MDCAS2 0x0c
+#define MSC0   0x10
+#define MSC1   0x14
+#define MECR   0x18
+
+mdcas0:                .long   0xc71c703f
+mdcas1:                .long   0xffc71c71
+mdcas2:                .long   0xffffffff
+/* mdcnfg:             .long   0x0bb2bcbf */
+mdcnfg:                .long   0x0334b22f      @ alt
+/* mcs0:               .long   0xfff8fff8 */
+msc0:          .long   0xad8c4888      @ alt
+mecr:          .long   0x00060006
+/* mecr:               .long   0x994a994a      @ alt */
+
+/* setting up the memory */
+
+.globl memsetup
+memsetup:
+       ldr     r0, MEM_BASE
+
+       /* Setup the flash memory */
+       ldr     r1, msc0
+       str     r1, [r0, #MSC0]
+
+       /* Set up the DRAM */
+
+       /* MDCAS0 */
+       ldr     r1, mdcas0
+       str     r1, [r0, #MDCAS0]
+
+       /* MDCAS1 */
+       ldr     r1, mdcas1
+       str     r1, [r0, #MDCAS1]
+
+       /* MDCAS2 */
+       ldr     r1, mdcas2
+       str     r1, [r0, #MDCAS2]
+
+       /* MDCNFG */
+       ldr     r1, mdcnfg
+       str     r1, [r0, #MDCNFG]
+
+       /* Set up PCMCIA space */
+       ldr     r1, mecr
+       str     r1, [r0, #MECR]
+
+       /* Load something to activate bank */
+       ldr     r1, MEM_START
+
+.rept  8
+       ldr     r0, [r1]
+.endr
+
+       /* everything is fine now */
+       mov     pc, lr
+
diff --git a/board/ebony/flash.c b/board/ebony/flash.c
new file mode 100644 (file)
index 0000000..6efd566
--- /dev/null
@@ -0,0 +1,736 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
+ * Add support for Am29F016D and dynamic switch setting.
+ *
+ * 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
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+#define     BOOT_SMALL_FLASH        32              /* 00100000 */
+#define     FLASH_ONBD_N            2               /* 00000010 */
+#define     FLASH_SRAM_SEL          1               /* 00000001 */
+
+#define     BOOT_SMALL_FLASH_VAL    4
+#define     FLASH_ONBD_N_VAL        2
+#define     FLASH_SRAM_SEL_VAL      1
+
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+static  unsigned    long    flash_addr_table[8][CFG_MAX_FLASH_BANKS] = {
+        {0xffc00000, 0xffe00000, 0xff880000},   /* 0:000: configuraton 3 */
+        {0xffc00000, 0xffe00000, 0xff800000},   /* 1:001: configuraton 4 */
+        {0xffc00000, 0xffe00000, 0x00000000},   /* 2:010: configuraton 7 */
+        {0xffc00000, 0xffe00000, 0x00000000},   /* 3:011: configuraton 8 */
+        {0xff800000, 0xffa00000, 0xfff80000},   /* 4:100: configuraton 1 */
+        {0xff800000, 0xffa00000, 0xfff00000},   /* 5:101: configuraton 2 */
+        {0xffc00000, 0xffe00000, 0x00000000},   /* 6:110: configuraton 5 */
+        {0xffc00000, 0xffe00000, 0x00000000}    /* 7:111: configuraton 6 */
+};
+
+/*-----------------------------------------------------------------------
+ * 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);
+#if 0
+static void flash_get_offsets (ulong base, flash_info_t *info);
+#endif
+
+#ifdef CONFIG_ADCIOP
+#define ADDR0           0x0aa9
+#define ADDR1           0x0556
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+#ifdef CONFIG_CPCI405
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned short
+#endif
+
+#ifdef CONFIG_WALNUT405
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+#ifdef CONFIG_EBONY
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void) {
+       unsigned long total_b = 0;
+       unsigned long size_b[CFG_MAX_FLASH_BANKS];
+       unsigned char * fpga_base = (unsigned char *)CFG_FPGA_BASE;
+       unsigned char switch_status;
+       unsigned short index = 0;
+       int i;
+
+
+       /* read FPGA base register FPGA_REG0 */
+       switch_status = *fpga_base;
+
+       /* check the bitmap of switch status */
+       if (switch_status & BOOT_SMALL_FLASH) {
+               index += BOOT_SMALL_FLASH_VAL;
+       }
+       if (switch_status & FLASH_ONBD_N) {
+               index += FLASH_ONBD_N_VAL;
+       }
+       if (switch_status & FLASH_SRAM_SEL) {
+               index += FLASH_SRAM_SEL_VAL;
+       }
+
+    DEBUGF("\n");
+       DEBUGF("FLASH: Index: %d\n", index);
+
+       /* Init: no FLASHes known */
+       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;
+
+               /* check whether the address is 0 */
+               if (flash_addr_table[index][i] == 0) {
+                       continue;
+               }
+
+               /* call flash_get_size() to initialize sector address */
+               size_b[i] = flash_get_size(
+                       (vu_long *)flash_addr_table[index][i], &flash_info[i]);
+               flash_info[i].size = size_b[i];
+               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+                               i, size_b[i], size_b[i]<<20);
+                       flash_info[i].sector_count = -1;
+                       flash_info[i].size = 0;
+               }
+
+               total_b += flash_info[i].size;
+       }
+
+       return total_b;
+}
+
+
+
+/*-----------------------------------------------------------------------
+ */
+#if 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_VENDMASK) == FLASH_MAN_SST) ||
+           (info->flash_id  == FLASH_AM040) ||
+           (info->flash_id  == FLASH_AMD016)) {
+               for (i = 0; i < info->sector_count; i++)
+                       info->start[i] = base + (i * 0x00010000);
+       } else {
+               if (info->flash_id & FLASH_BTYPE) {
+                       /* set sector offsets for bottom boot block type        */
+                       info->start[0] = base + 0x00000000;
+                       info->start[1] = base + 0x00004000;
+                       info->start[2] = base + 0x00006000;
+                       info->start[3] = base + 0x00008000;
+                       for (i = 4; i < info->sector_count; i++) {
+                               info->start[i] = base + (i * 0x00010000) - 0x00030000;
+                       }
+               } else {
+                       /* set sector offsets for top boot block type           */
+                       i = info->sector_count - 1;
+                       info->start[i--] = base + info->size - 0x00004000;
+                       info->start[i--] = base + info->size - 0x00006000;
+                       info->start[i--] = base + info->size - 0x00008000;
+                       for (; i >= 0; i--) {
+                               info->start[i] = base + i * 0x00010000;
+                       }
+               }
+       }
+}
+#endif /* 0 */
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+        int k;
+        int size;
+        int erased;
+        volatile unsigned long *flash;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       case FLASH_MAN_SST:     printf ("SST ");                break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AMD016:      printf ("AM29F016D (16 Mbit, uniform sector size)\n");
+               break;
+       case FLASH_AM040:       printf ("AM29F040 (512 Kbit, uniform sector size)\n");
+               break;
+       case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+               break;
+       case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+               break;
+       case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+               break;
+       case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+               break;
+       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+               break;
+       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+               break;
+       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+               break;
+       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+               break;
+       case FLASH_SST800A:     printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+               break;
+       case FLASH_SST160A:     printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+               break;
+       default:                printf ("Unknown Chip Type\n");
+               break;
+       }
+
+       printf ("  Size: %ld KB in %d Sectors\n",
+               info->size >> 10, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+                /*
+                 * Check if whole sector is erased
+                 */
+                if (i != (info->sector_count-1))
+                       size = info->start[i+1] - info->start[i];
+                else
+                       size = info->start[0] + info->size - info->start[i];
+                erased = 1;
+                flash = (volatile unsigned long *)info->start[i];
+                size = size >> 2;        /* divide by 4 for longword access */
+                for (k=0; k<size; k++)
+               {
+                       if (*flash++ != 0xffffffff)
+                       {
+                               erased = 0;
+                               break;
+                       }
+               }
+
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+                       printf (" %08lX%s%s",
+                               info->start[i],
+                               erased ? " E" : "  ",
+                               info->protect[i] ? "RO " : "   "
+                               );
+                       }
+               printf ("\n");
+               return;
+       }
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+       static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+               {
+                       short i;
+                       FLASH_WORD_SIZE value;
+                       ulong base = (ulong)addr;
+                       volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+            DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr );
+
+                       /* Write auto select command: read Manufacturer ID */
+            udelay(10000);
+                       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+            udelay(1000);
+                       addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+            udelay(1000);
+                       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+            udelay(1000);
+
+#ifdef CONFIG_ADCIOP
+                       value = addr2[2];
+#else
+                       value = addr2[0];
+#endif
+
+                       DEBUGF("FLASH MANUFACT: %x\n", value);
+
+                       switch (value) {
+                       case (FLASH_WORD_SIZE)AMD_MANUFACT:
+                               info->flash_id = FLASH_MAN_AMD;
+                               break;
+                       case (FLASH_WORD_SIZE)FUJ_MANUFACT:
+                               info->flash_id = FLASH_MAN_FUJ;
+                               break;
+                       case (FLASH_WORD_SIZE)SST_MANUFACT:
+                               info->flash_id = FLASH_MAN_SST;
+                               break;
+                       default:
+                               info->flash_id = FLASH_UNKNOWN;
+                               info->sector_count = 0;
+                               info->size = 0;
+                               return (0);                     /* no or unknown flash  */
+                       }
+
+#ifdef CONFIG_ADCIOP
+                       value = addr2[0];                       /* device ID            */
+                       debug ("\ndev_code=%x\n", value);
+#else
+                       value = addr2[1];                       /* device ID            */
+#endif
+
+                       DEBUGF("\nFLASH DEVICEID: %x\n", value);
+
+                       switch (value) {
+                       case (FLASH_WORD_SIZE)AMD_ID_F016D:
+                               info->flash_id += FLASH_AMD016;
+                               info->sector_count = 32;
+                               info->size = 0x00200000;
+                               break;                          /* => 2 MB              */
+                       case (FLASH_WORD_SIZE)AMD_ID_F040B:
+                               info->flash_id += FLASH_AM040;
+                               info->sector_count = 8;
+                               info->size = 0x0080000; /* => 512 ko */
+                               break;
+                       case (FLASH_WORD_SIZE)AMD_ID_LV400T:
+                               info->flash_id += FLASH_AM400T;
+                               info->sector_count = 11;
+                               info->size = 0x00080000;
+                               break;                          /* => 0.5 MB            */
+
+                       case (FLASH_WORD_SIZE)AMD_ID_LV400B:
+                               info->flash_id += FLASH_AM400B;
+                               info->sector_count = 11;
+                               info->size = 0x00080000;
+                               break;                          /* => 0.5 MB            */
+
+                       case (FLASH_WORD_SIZE)AMD_ID_LV800T:
+                               info->flash_id += FLASH_AM800T;
+                               info->sector_count = 19;
+                               info->size = 0x00100000;
+                               break;                          /* => 1 MB              */
+
+                       case (FLASH_WORD_SIZE)AMD_ID_LV800B:
+                               info->flash_id += FLASH_AM800B;
+                               info->sector_count = 19;
+                               info->size = 0x00100000;
+                               break;                          /* => 1 MB              */
+
+                       case (FLASH_WORD_SIZE)AMD_ID_LV160T:
+                               info->flash_id += FLASH_AM160T;
+                               info->sector_count = 35;
+                               info->size = 0x00200000;
+                               break;                          /* => 2 MB              */
+
+                       case (FLASH_WORD_SIZE)AMD_ID_LV160B:
+                               info->flash_id += FLASH_AM160B;
+                               info->sector_count = 35;
+                               info->size = 0x00200000;
+                               break;                          /* => 2 MB              */
+#if 0  /* enable when device IDs are available */
+                       case (FLASH_WORD_SIZE)AMD_ID_LV320T:
+                               info->flash_id += FLASH_AM320T;
+                               info->sector_count = 67;
+                               info->size = 0x00400000;
+                               break;                          /* => 4 MB              */
+
+                       case (FLASH_WORD_SIZE)AMD_ID_LV320B:
+                               info->flash_id += FLASH_AM320B;
+                               info->sector_count = 67;
+                               info->size = 0x00400000;
+                               break;                          /* => 4 MB              */
+#endif
+                       case (FLASH_WORD_SIZE)SST_ID_xF800A:
+                               info->flash_id += FLASH_SST800A;
+                               info->sector_count = 16;
+                               info->size = 0x00100000;
+                               break;                          /* => 1 MB              */
+
+                       case (FLASH_WORD_SIZE)SST_ID_xF160A:
+                               info->flash_id += FLASH_SST160A;
+                               info->sector_count = 32;
+                               info->size = 0x00200000;
+                               break;                          /* => 2 MB              */
+
+                       default:
+                               info->flash_id = FLASH_UNKNOWN;
+                               return (0);                     /* => no or unknown flash */
+
+                       }
+
+                       /* set up sector start address table */
+                       if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+                           (info->flash_id  == FLASH_AM040) ||
+                           (info->flash_id  == FLASH_AMD016)) {
+                               for (i = 0; i < info->sector_count; i++)
+                                       info->start[i] = base + (i * 0x00010000);
+                       } else {
+                               if (info->flash_id & FLASH_BTYPE) {
+                                       /* set sector offsets for bottom boot block type        */
+                                       info->start[0] = base + 0x00000000;
+                                       info->start[1] = base + 0x00004000;
+                                       info->start[2] = base + 0x00006000;
+                                       info->start[3] = base + 0x00008000;
+                                       for (i = 4; i < info->sector_count; i++) {
+                                               info->start[i] = base + (i * 0x00010000) - 0x00030000;
+                                       }
+                               } else {
+                                       /* set sector offsets for top boot block type           */
+                                       i = info->sector_count - 1;
+                                       info->start[i--] = base + info->size - 0x00004000;
+                                       info->start[i--] = base + info->size - 0x00006000;
+                                       info->start[i--] = base + info->size - 0x00008000;
+                                       for (; i >= 0; i--) {
+                                               info->start[i] = base + i * 0x00010000;
+                                       }
+                               }
+                       }
+
+                       /* check for protected sectors */
+                       for (i = 0; i < info->sector_count; i++) {
+                               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+                               /* D0 = 1 if protected */
+#ifdef CONFIG_ADCIOP
+                               addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+                               info->protect[i] = addr2[4] & 1;
+#else
+                               addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+                               if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
+                                       info->protect[i] = 0;
+                               else
+                                       info->protect[i] = addr2[2] & 1;
+#endif
+                       }
+
+                       /*
+                        * Prevent writes to uninitialized FLASH.
+                        */
+                       if (info->flash_id != FLASH_UNKNOWN) {
+#if 0 /* test-only */
+#ifdef CONFIG_ADCIOP
+                               addr2 = (volatile unsigned char *)info->start[0];
+                               addr2[ADDR0] = 0xAA;
+                               addr2[ADDR1] = 0x55;
+                               addr2[ADDR0] = 0xF0;  /* reset bank */
+#else
+                               addr2 = (FLASH_WORD_SIZE *)info->start[0];
+                               *addr2 = (FLASH_WORD_SIZE)0x00F000F0;   /* reset bank */
+#endif
+#else /* test-only */
+                               addr2 = (FLASH_WORD_SIZE *)info->start[0];
+                               *addr2 = (FLASH_WORD_SIZE)0x00F000F0;   /* reset bank */
+#endif /* test-only */
+                       }
+
+                       return (info->size);
+               }
+
+       int wait_for_DQ7(flash_info_t *info, int sect)
+               {
+                       ulong start, now, last;
+                       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+                       start = get_timer (0);
+                       last  = start;
+                       while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+                               if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                                       printf ("Timeout\n");
+                                       return -1;
+                               }
+                               /* show that we're waiting */
+                               if ((now - last) > 1000) {  /* every second */
+                                       putc ('.');
+                                       last = now;
+                               }
+                       }
+                       return 0;
+               }
+
+/*-----------------------------------------------------------------------
+ */
+
+       int     flash_erase (flash_info_t *info, int s_first, int s_last)
+               {
+                       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+                       volatile FLASH_WORD_SIZE *addr2;
+                       int flag, prot, sect, l_sect;
+                       int i;
+
+                       if ((s_first < 0) || (s_first > s_last)) {
+                               if (info->flash_id == FLASH_UNKNOWN) {
+                                       printf ("- missing\n");
+                               } else {
+                                       printf ("- no sectors to erase\n");
+                               }
+                               return 1;
+                       }
+
+                       if (info->flash_id == FLASH_UNKNOWN) {
+                               printf ("Can't erase unknown flash type - aborted\n");
+                               return 1;
+                       }
+
+                       prot = 0;
+                       for (sect=s_first; sect<=s_last; ++sect) {
+                               if (info->protect[sect]) {
+                                       prot++;
+                               }
+                       }
+
+                       if (prot) {
+                               printf ("- Warning: %d protected sectors will not be erased!\n",
+                                       prot);
+                       } else {
+                               printf ("\n");
+                       }
+
+                       l_sect = -1;
+
+                       /* Disable interrupts which might cause a timeout here */
+                       flag = disable_interrupts();
+
+                       /* Start erase on unprotected sectors */
+                       for (sect = s_first; sect<=s_last; sect++) {
+                               if (info->protect[sect] == 0) { /* not protected */
+                                       addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
+                                       printf("Erasing sector %p\n", addr2);
+
+                                       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
+                                               addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                                               addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                                               addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+                                               addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                                               addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                                               addr2[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */
+                                               for (i=0; i<50; i++)
+                                                       udelay(1000);  /* wait 1 ms */
+                                       } else {
+                                               addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                                               addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                                               addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+                                               addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                                               addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                                               addr2[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */
+                                       }
+                                       l_sect = sect;
+                                       /*
+                                        * Wait for each sector to complete, it's more
+                                        * reliable.  According to AMD Spec, you must
+                                        * issue all erase commands within a specified
+                                        * timeout.  This has been seen to fail, especially
+                                        * if printf()s are included (for debug)!!
+                                        */
+                                       wait_for_DQ7(info, sect);
+                               }
+                       }
+
+                       /* re-enable interrupts if necessary */
+                       if (flag)
+                               enable_interrupts();
+
+                       /* wait at least 80us - let's wait 1 ms */
+                       udelay (1000);
+
+#if 0
+                       /*
+                        * We wait for the last triggered sector
+                        */
+                       if (l_sect < 0)
+                               goto DONE;
+                       wait_for_DQ7(info, l_sect);
+
+               DONE:
+#endif
+                       /* reset to read mode */
+                       addr = (FLASH_WORD_SIZE *)info->start[0];
+                       addr[0] = (FLASH_WORD_SIZE)0x00F000F0;  /* reset bank */
+
+                       printf (" done\n");
+                       return 0;
+               }
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+       int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+               {
+                       ulong cp, wp, data;
+                       int i, l, rc;
+
+                       wp = (addr & ~3);       /* get lower word aligned address */
+
+                       /*
+                        * handle unaligned start bytes
+                        */
+                       if ((l = addr - wp) != 0) {
+                               data = 0;
+                               for (i=0, cp=wp; i<l; ++i, ++cp) {
+                                       data = (data << 8) | (*(uchar *)cp);
+                               }
+                               for (; i<4 && cnt>0; ++i) {
+                                       data = (data << 8) | *src++;
+                                       --cnt;
+                                       ++cp;
+                               }
+                               for (; cnt==0 && i<4; ++i, ++cp) {
+                                       data = (data << 8) | (*(uchar *)cp);
+                               }
+
+                               if ((rc = write_word(info, wp, data)) != 0) {
+                                       return (rc);
+                               }
+                               wp += 4;
+                       }
+
+                       /*
+                        * handle word aligned part
+                        */
+                       while (cnt >= 4) {
+                               data = 0;
+                               for (i=0; i<4; ++i) {
+                                       data = (data << 8) | *src++;
+                               }
+                               if ((rc = write_word(info, wp, data)) != 0) {
+                                       return (rc);
+                               }
+                               wp  += 4;
+                               cnt -= 4;
+                       }
+
+                       if (cnt == 0) {
+                               return (0);
+                       }
+
+                       /*
+                        * handle unaligned tail bytes
+                        */
+                       data = 0;
+                       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+                               data = (data << 8) | *src++;
+                               --cnt;
+                       }
+                       for (; i<4; ++i, ++cp) {
+                               data = (data << 8) | (*(uchar *)cp);
+                       }
+
+                       return (write_word(info, wp, data));
+               }
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+       static int write_word (flash_info_t * info, ulong dest, ulong data)
+               {
+                       volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]);
+                       volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
+                       volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
+                       ulong start;
+                       int i;
+
+                       /* Check if Flash is (sufficiently) erased */
+                       if ((*((volatile FLASH_WORD_SIZE *) dest) &
+                            (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
+                               return (2);
+                       }
+
+                       for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
+                               int flag;
+
+                               /* Disable interrupts which might cause a timeout here */
+                               flag = disable_interrupts ();
+
+                               addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
+                               addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
+                               addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
+
+                               dest2[i] = data2[i];
+
+                               /* re-enable interrupts if necessary */
+                               if (flag)
+                                       enable_interrupts ();
+
+                               /* data polling for D7 */
+                               start = get_timer (0);
+                               while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
+                                      (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
+
+                                       if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+                                               return (1);
+                                       }
+                               }
+                       }
+
+                       return (0);
+               }
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/eltec/mhpc/config.mk b/board/eltec/mhpc/config.mk
new file mode 100644 (file)
index 0000000..607ebbc
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000
+# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+# Marius Groeger <mgroeger@sysgo.de>
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.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
+#
+
+#
+# MHPC boards
+#
+
+TEXT_BASE = 0xfe000000
+/*TEXT_BASE  = 0x00200000 */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/board/eric/flash.c b/board/eric/flash.c
new file mode 100644 (file)
index 0000000..c3f6e15
--- /dev/null
@@ -0,0 +1,1130 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+
+#ifdef CFG_FLASH_16BIT
+#define FLASH_WORD_SIZE        unsigned short
+#define        FLASH_ID_MASK   0xFFFF
+#else
+#define FLASH_WORD_SIZE unsigned long
+#define        FLASH_ID_MASK   0xFFFFFFFF
+#endif
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+/* stolen from esteem192e/flash.c */
+ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
+
+#ifndef CFG_FLASH_16BIT
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+#else
+static int write_short (flash_info_t *info, ulong dest, ushort data);
+#endif
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       unsigned long size_b0, size_b1;
+       int i;
+        uint pbcr;
+        unsigned long base_b0, base_b1;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+
+       size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+
+       /* Only one bank */
+       if (CFG_MAX_FLASH_BANKS == 1)
+         {
+           /* Setup offsets */
+           flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
+
+           /* Monitor protection ON by default */
+#if 0      /* sand: */
+           (void)flash_protect(FLAG_PROTECT_SET,
+                               FLASH_BASE0_PRELIM-CFG_MONITOR_LEN+size_b0,
+                               FLASH_BASE0_PRELIM-1+size_b0,
+                               &flash_info[0]);
+#else
+           (void)flash_protect(FLAG_PROTECT_SET,
+                               CFG_MONITOR_BASE,
+                               CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+                               &flash_info[0]);
+#endif
+           size_b1 = 0 ;
+           flash_info[0].size = size_b0;
+         }
+
+       /* 2 banks */
+       else
+         {
+           size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE1_PRELIM, &flash_info[1]);
+
+           /* Re-do sizing to get full correct info */
+
+           if (size_b1)
+             {
+               mtdcr(ebccfga, pb0cr);
+               pbcr = mfdcr(ebccfgd);
+               mtdcr(ebccfga, pb0cr);
+               base_b1 = -size_b1;
+               pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
+               mtdcr(ebccfgd, pbcr);
+               /*          printf("pb1cr = %x\n", pbcr); */
+             }
+
+           if (size_b0)
+             {
+               mtdcr(ebccfga, pb1cr);
+               pbcr = mfdcr(ebccfgd);
+               mtdcr(ebccfga, pb1cr);
+               base_b0 = base_b1 - size_b0;
+               pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+               mtdcr(ebccfgd, pbcr);
+               /*            printf("pb0cr = %x\n", pbcr); */
+             }
+
+           size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
+
+           flash_get_offsets (base_b0, &flash_info[0]);
+
+           /* monitor protection ON by default */
+#if 0      /* sand: */
+           (void)flash_protect(FLAG_PROTECT_SET,
+                               FLASH_BASE0_PRELIM-CFG_MONITOR_LEN+size_b0,
+                               FLASH_BASE0_PRELIM-1+size_b0,
+                               &flash_info[0]);
+#else
+           (void)flash_protect(FLAG_PROTECT_SET,
+                               CFG_MONITOR_BASE,
+                               CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+                               &flash_info[0]);
+#endif
+
+           if (size_b1) {
+             /* Re-do sizing to get full correct info */
+             size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
+
+             flash_get_offsets (base_b1, &flash_info[1]);
+
+             /* monitor protection ON by default */
+             (void)flash_protect(FLAG_PROTECT_SET,
+                                 base_b1+size_b1-CFG_MONITOR_LEN,
+                                 base_b1+size_b1-1,
+                                 &flash_info[1]);
+             /* monitor protection OFF by default (one is enough) */
+             (void)flash_protect(FLAG_PROTECT_CLEAR,
+                                 base_b0+size_b0-CFG_MONITOR_LEN,
+                                 base_b0+size_b0-1,
+                                 &flash_info[0]);
+           } else {
+             flash_info[1].flash_id = FLASH_UNKNOWN;
+             flash_info[1].sector_count = -1;
+           }
+
+           flash_info[0].size = size_b0;
+           flash_info[1].size = size_b1;
+         }/* else 2 banks */
+       return (size_b0 + size_b1);
+}
+
+
+
+/*-----------------------------------------------------------------------
+ */
+
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       /* set up sector start adress table */
+       if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F320J3A ||
+           (info->flash_id & FLASH_TYPEMASK) == FLASH_28F640J3A ||
+           (info->flash_id & FLASH_TYPEMASK) == FLASH_28F128J3A) {
+           for (i = 0; i < info->sector_count; i++) {
+               info->start[i] = base + (i * info->size/info->sector_count);
+           }
+       } else if (info->flash_id & FLASH_BTYPE) {
+             if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+
+#ifndef CFG_FLASH_16BIT
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00004000;
+               info->start[2] = base + 0x00008000;
+               info->start[3] = base + 0x0000C000;
+               info->start[4] = base + 0x00010000;
+               info->start[5] = base + 0x00014000;
+               info->start[6] = base + 0x00018000;
+               info->start[7] = base + 0x0001C000;
+               for (i = 8; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * 0x00020000) - 0x000E0000;
+               }
+               }
+             else {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00008000;
+               info->start[2] = base + 0x0000C000;
+               info->start[3] = base + 0x00010000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * 0x00020000) - 0x00060000;
+               }
+              }
+#else
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00002000;
+               info->start[2] = base + 0x00004000;
+               info->start[3] = base + 0x00006000;
+               info->start[4] = base + 0x00008000;
+               info->start[5] = base + 0x0000A000;
+               info->start[6] = base + 0x0000C000;
+               info->start[7] = base + 0x0000E000;
+               for (i = 8; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * 0x00010000) - 0x00070000;
+               }
+              }
+             else {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00004000;
+               info->start[2] = base + 0x00006000;
+               info->start[3] = base + 0x00008000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * 0x00010000) - 0x00030000;
+               }
+              }
+#endif
+       } else {
+               /* set sector offsets for top boot block type           */
+               i = info->sector_count - 1;
+             if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+
+#ifndef CFG_FLASH_16BIT
+               info->start[i--] = base + info->size - 0x00004000;
+               info->start[i--] = base + info->size - 0x00008000;
+               info->start[i--] = base + info->size - 0x0000C000;
+               info->start[i--] = base + info->size - 0x00010000;
+               info->start[i--] = base + info->size - 0x00014000;
+               info->start[i--] = base + info->size - 0x00018000;
+               info->start[i--] = base + info->size - 0x0001C000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00020000;
+               }
+
+               } else {
+
+               info->start[i--] = base + info->size - 0x00008000;
+               info->start[i--] = base + info->size - 0x0000C000;
+               info->start[i--] = base + info->size - 0x00010000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00020000;
+               }
+              }
+#else
+               info->start[i--] = base + info->size - 0x00002000;
+               info->start[i--] = base + info->size - 0x00004000;
+               info->start[i--] = base + info->size - 0x00006000;
+               info->start[i--] = base + info->size - 0x00008000;
+               info->start[i--] = base + info->size - 0x0000A000;
+               info->start[i--] = base + info->size - 0x0000C000;
+               info->start[i--] = base + info->size - 0x0000E000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00010000;
+               }
+
+               } else {
+
+               info->start[i--] = base + info->size - 0x00004000;
+               info->start[i--] = base + info->size - 0x00006000;
+               info->start[i--] = base + info->size - 0x00008000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00010000;
+               }
+              }
+#endif
+       }
+
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+       uchar *boottype;
+       uchar botboot[]=", bottom boot sect)\n";
+       uchar topboot[]=", top boot sector)\n";
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       case FLASH_MAN_SST:     printf ("SST ");                break;
+       case FLASH_MAN_STM:     printf ("STM ");                break;
+       case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       if (info->flash_id & 0x0001 ) {
+       boottype = botboot;
+       } else {
+       boottype = topboot;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit%s",boottype);
+                               break;
+       case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit%s",boottype);
+                               break;
+       case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit%s",boottype);
+                               break;
+       case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit%s",boottype);
+                               break;
+       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit%s",boottype);
+                               break;
+       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit%s",boottype);
+                               break;
+       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit%s",boottype);
+                               break;
+       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit%s",boottype);
+                               break;
+       case FLASH_INTEL800B:   printf ("INTEL28F800B (8 Mbit%s",boottype);
+                               break;
+       case FLASH_INTEL800T:   printf ("INTEL28F800T (8 Mbit%s",boottype);
+                               break;
+       case FLASH_INTEL160B:   printf ("INTEL28F160B (16 Mbit%s",boottype);
+                               break;
+       case FLASH_INTEL160T:   printf ("INTEL28F160T (16 Mbit%s",boottype);
+                               break;
+       case FLASH_INTEL320B:   printf ("INTEL28F320B (32 Mbit%s",boottype);
+                               break;
+       case FLASH_INTEL320T:   printf ("INTEL28F320T (32 Mbit%s",boottype);
+                               break;
+
+#if 0 /* enable when devices are available */
+
+       case FLASH_INTEL640B:   printf ("INTEL28F640B (64 Mbit%s",boottype);
+                               break;
+       case FLASH_INTEL640T:   printf ("INTEL28F640T (64 Mbit%s",boottype);
+                               break;
+#endif
+       case FLASH_28F320J3A:   printf ("INTEL28F320J3A (32 Mbit%s",boottype);
+                               break;
+       case FLASH_28F640J3A:   printf ("INTEL28F640J3A (64 Mbit%s",boottype);
+                               break;
+       case FLASH_28F128J3A:   printf ("INTEL28F128J3A (128 Mbit%s",boottype);
+                               break;
+
+       default:                printf ("Unknown Chip Type\n");
+                               break;
+       }
+
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     "
+               );
+       }
+       printf ("\n");
+       return;
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
+{
+       short i;
+       ulong base = (ulong)addr;
+       FLASH_WORD_SIZE value;
+
+       /* Write auto select command: read Manufacturer ID */
+
+
+#ifndef CFG_FLASH_16BIT
+
+       /*
+        * Note: if it is an AMD flash and the word at addr[0000]
+         * is 0x00890089 this routine will think it is an Intel
+         * flash device and may(most likely) cause trouble.
+        */
+
+       addr[0x0000] = 0x00900090;
+       if(addr[0x0000] != 0x00890089){
+               addr[0x0555] = 0x00AA00AA;
+               addr[0x02AA] = 0x00550055;
+               addr[0x0555] = 0x00900090;
+#else
+
+       /*
+        * Note: if it is an AMD flash and the word at addr[0000]
+         * is 0x0089 this routine will think it is an Intel
+         * flash device and may(most likely) cause trouble.
+        */
+
+       addr[0x0000] = 0x0090;
+
+       if(addr[0x0000] != 0x0089){
+               addr[0x0555] = 0x00AA;
+               addr[0x02AA] = 0x0055;
+               addr[0x0555] = 0x0090;
+#endif
+       }
+       value = addr[0];
+
+       switch (value) {
+       case (AMD_MANUFACT & FLASH_ID_MASK):
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+       case (FUJ_MANUFACT & FLASH_ID_MASK):
+               info->flash_id = FLASH_MAN_FUJ;
+               break;
+       case (STM_MANUFACT & FLASH_ID_MASK):
+               info->flash_id = FLASH_MAN_STM;
+               break;
+       case (SST_MANUFACT & FLASH_ID_MASK):
+               info->flash_id = FLASH_MAN_SST;
+               break;
+       case (INTEL_MANUFACT & FLASH_ID_MASK):
+               info->flash_id = FLASH_MAN_INTEL;
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* no or unknown flash  */
+
+       }
+
+       value = addr[1];                        /* device ID            */
+
+       switch (value) {
+
+       case (AMD_ID_LV400T & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM400T;
+               info->sector_count = 11;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (AMD_ID_LV400B & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM400B;
+               info->sector_count = 11;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (AMD_ID_LV800T & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM800T;
+               info->sector_count = 19;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (AMD_ID_LV800B & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM800B;
+               info->sector_count = 19;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (AMD_ID_LV160T & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM160T;
+               info->sector_count = 35;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (AMD_ID_LV160B & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM160B;
+               info->sector_count = 35;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+#if 0  /* enable when device IDs are available */
+       case (AMD_ID_LV320T & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM320T;
+               info->sector_count = 67;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+
+       case (AMD_ID_LV320B & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 67;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+#endif
+
+       case (INTEL_ID_28F800B3T & FLASH_ID_MASK):
+               info->flash_id += FLASH_INTEL800T;
+               info->sector_count = 23;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (INTEL_ID_28F800B3B & FLASH_ID_MASK):
+               info->flash_id += FLASH_INTEL800B;
+               info->sector_count = 23;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (INTEL_ID_28F160B3T & FLASH_ID_MASK):
+               info->flash_id += FLASH_INTEL160T;
+               info->sector_count = 39;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (INTEL_ID_28F160B3B & FLASH_ID_MASK):
+               info->flash_id += FLASH_INTEL160B;
+               info->sector_count = 39;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
+               info->flash_id += FLASH_INTEL320T;
+               info->sector_count = 71;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+
+       case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 71;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+
+#if 0 /* enable when devices are available */
+       case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
+               info->flash_id += FLASH_INTEL320T;
+               info->sector_count = 135;
+               info->size = 0x01000000;
+               break;                          /* => 16 MB             */
+
+       case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 135;
+               info->size = 0x01000000;
+               break;                          /* => 16 MB             */
+#endif
+       case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
+               info->flash_id += FLASH_28F320J3A;
+               info->sector_count = 32;
+               info->size = 0x00400000;
+               break;                          /* => 32 MBit   */
+       case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
+               info->flash_id += FLASH_28F640J3A;
+               info->sector_count = 64;
+               info->size = 0x00800000;
+               break;                          /* => 64 MBit   */
+       case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
+               info->flash_id += FLASH_28F128J3A;
+               info->sector_count = 128;
+               info->size = 0x01000000;
+               break;                          /* => 128 MBit          */
+
+       default:
+               /* FIXME*/
+               info->flash_id = FLASH_UNKNOWN;
+               return (0);                     /* => no or unknown flash */
+       }
+
+       flash_get_offsets(base, info);
+
+       /* check for protected sectors */
+       for (i = 0; i < info->sector_count; i++) {
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+               addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+               info->protect[i] = addr[2] & 1;
+       }
+
+       /*
+        * Prevent writes to uninitialized FLASH.
+        */
+       if (info->flash_id != FLASH_UNKNOWN) {
+               addr = (volatile FLASH_WORD_SIZE *)info->start[0];
+               if( (info->flash_id & 0xFF00) == FLASH_MAN_INTEL){
+                  *addr = (0x00F000F0 & FLASH_ID_MASK);        /* reset bank */
+               } else {
+                  *addr = (0x00FF00FF & FLASH_ID_MASK);        /* reset bank */
+               }
+       }
+
+       return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+
+       volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
+       int flag, prot, sect, l_sect, barf;
+       ulong start, now, last;
+       int rcode = 0;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       if ((info->flash_id == FLASH_UNKNOWN) ||
+           ((info->flash_id > FLASH_AMD_COMP) &&
+             ( (info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL ) ) ){
+               printf ("Can't erase unknown flash type - aborted\n");
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       l_sect = -1;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+    if(info->flash_id < FLASH_AMD_COMP) {
+#ifndef CFG_FLASH_16BIT
+       addr[0x0555] = 0x00AA00AA;
+       addr[0x02AA] = 0x00550055;
+       addr[0x0555] = 0x00800080;
+       addr[0x0555] = 0x00AA00AA;
+       addr[0x02AA] = 0x00550055;
+#else
+       addr[0x0555] = 0x00AA;
+       addr[0x02AA] = 0x0055;
+       addr[0x0555] = 0x0080;
+       addr[0x0555] = 0x00AA;
+       addr[0x02AA] = 0x0055;
+#endif
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
+                       addr[0] = (0x00300030 & FLASH_ID_MASK);
+                       l_sect = sect;
+               }
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* wait at least 80us - let's wait 1 ms */
+       udelay (1000);
+
+       /*
+        * We wait for the last triggered sector
+        */
+       if (l_sect < 0)
+               goto DONE;
+
+       start = get_timer (0);
+       last  = start;
+       addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
+       while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
+                         (0x00800080&FLASH_ID_MASK)  )
+       {
+               if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                       printf ("Timeout\n");
+                       return 1;
+               }
+               /* show that we're waiting */
+               if ((now - last) > 1000) {      /* every second */
+                       serial_putc ('.');
+                       last = now;
+               }
+       }
+
+DONE:
+       /* reset to read mode */
+       addr = (volatile FLASH_WORD_SIZE *)info->start[0];
+       addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
+    } else {
+
+
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       barf = 0;
+#ifndef CFG_FLASH_16BIT
+                       addr = (vu_long*)(info->start[sect]);
+                       addr[0] = 0x00200020;
+                       addr[0] = 0x00D000D0;
+                       while(!(addr[0] & 0x00800080)); /* wait for error or finish */
+                       if( addr[0] & 0x003A003A) {     /* check for error */
+                               barf = addr[0] & 0x003A0000;
+                               if( barf ) {
+                                       barf >>=16;
+                               } else {
+                                       barf = addr[0] & 0x0000003A;
+                               }
+                       }
+#else
+                       addr = (vu_short*)(info->start[sect]);
+                       addr[0] = 0x0020;
+                       addr[0] = 0x00D0;
+                       while(!(addr[0] & 0x0080));     /* wait for error or finish */
+                       if( addr[0] & 0x003A)   /* check for error */
+                               barf = addr[0] & 0x003A;
+#endif
+                       if(barf) {
+                               printf("\nFlash error in sector at %lx\n",(unsigned long)addr);
+                               if(barf & 0x0002) printf("Block locked, not erased.\n");
+                               if((barf & 0x0030) == 0x0030)
+                                       printf("Command Sequence error.\n");
+                               if((barf & 0x0030) == 0x0020)
+                                       printf("Block Erase error.\n");
+                               if(barf & 0x0008) printf("Vpp Low error.\n");
+                               rcode = 1;
+                       } else printf(".");
+                       l_sect = sect;
+               }
+       addr = (volatile FLASH_WORD_SIZE *)info->start[0];
+       addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
+
+       }
+
+    }
+       printf (" done\n");
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*flash_info_t *addr2info (ulong addr)
+{
+       flash_info_t *info;
+       int i;
+
+       for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
+               if ((addr >= info->start[0]) &&
+                   (addr < (info->start[0] + info->size)) ) {
+                       return (info);
+               }
+       }
+
+       return (NULL);
+}
+*/
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ * Make sure all target addresses are within Flash bounds,
+ * and no protected sectors are hit.
+ * Returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - target range includes protected sectors
+ * 8 - target address not in Flash memory
+ */
+
+/*int flash_write (uchar *src, ulong addr, ulong cnt)
+{
+       int i;
+       ulong         end        = addr + cnt - 1;
+       flash_info_t *info_first = addr2info (addr);
+       flash_info_t *info_last  = addr2info (end );
+       flash_info_t *info;
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       if (!info_first || !info_last) {
+               return (8);
+       }
+
+       for (info = info_first; info <= info_last; ++info) {
+               ulong b_end = info->start[0] + info->size;*/    /* bank end addr */
+/*             short s_end = info->sector_count - 1;
+               for (i=0; i<info->sector_count; ++i) {
+                       ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
+
+                       if ((end >= info->start[i]) && (addr < e_addr) &&
+                           (info->protect[i] != 0) ) {
+                               return (4);
+                       }
+               }
+       }
+
+*/     /* finally write data to flash */
+/*     for (info = info_first; info <= info_last && cnt>0; ++info) {
+               ulong len;
+
+               len = info->start[0] + info->size - addr;
+               if (len > cnt)
+                       len = cnt;
+               if ((i = write_buff(info, src, addr, len)) != 0) {
+                       return (i);
+               }
+               cnt  -= len;
+               addr += len;
+               src  += len;
+       }
+       return (0);
+}
+*/
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+#ifndef CFG_FLASH_16BIT
+       ulong cp, wp, data;
+       int l;
+#else
+       ulong cp, wp;
+       ushort data;
+#endif
+       int i, rc;
+
+#ifndef CFG_FLASH_16BIT
+
+
+       wp = (addr & ~3);       /* get lower word aligned address */
+
+       /*
+        * handle unaligned start bytes
+        */
+       if ((l = addr - wp) != 0) {
+               data = 0;
+               for (i=0, cp=wp; i<l; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+               for (; i<4 && cnt>0; ++i) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+                       ++cp;
+               }
+               for (; cnt==0 && i<4; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp += 4;
+       }
+
+       /*
+        * handle word aligned part
+        */
+       while (cnt >= 4) {
+               data = 0;
+               for (i=0; i<4; ++i) {
+                       data = (data << 8) | *src++;
+               }
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp  += 4;
+               cnt -= 4;
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       data = 0;
+       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i<4; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *)cp);
+       }
+
+       return (write_word(info, wp, data));
+
+#else
+       wp = (addr & ~1);       /* get lower word aligned address */
+
+       /*
+        * handle unaligned start byte
+        */
+       if (addr - wp) {
+               data = 0;
+               data = (data << 8) | *src++;
+               --cnt;
+               if ((rc = write_short(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp += 2;
+       }
+
+       /*
+        * handle word aligned part
+        */
+/*     l = 0; used for debuging  */
+       while (cnt >= 2) {
+               data = 0;
+               for (i=0; i<2; ++i) {
+                       data = (data << 8) | *src++;
+               }
+
+/*             if(!l){
+                       printf("%x",data);
+                       l = 1;
+               }  used for debuging */
+
+               if ((rc = write_short(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp  += 2;
+               cnt -= 2;
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       data = 0;
+       for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i<2; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *)cp);
+       }
+
+       return (write_short(info, wp, data));
+
+
+#endif
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+#ifndef CFG_FLASH_16BIT
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+       vu_long *addr = (vu_long*)(info->start[0]);
+       ulong start,barf;
+       int flag;
+
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((vu_long *)dest) & data) != data) {
+               return (2);
+       }
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+     if(info->flash_id > FLASH_AMD_COMP) {
+       /* AMD stuff */
+       addr[0x0555] = 0x00AA00AA;
+       addr[0x02AA] = 0x00550055;
+       addr[0x0555] = 0x00A000A0;
+     } else {
+       /* intel stuff */
+       *addr = 0x00400040;
+     }
+       *((vu_long *)dest) = data;
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* data polling for D7 */
+       start = get_timer (0);
+
+     if(info->flash_id > FLASH_AMD_COMP) {
+
+       while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       return (1);
+               }
+       }
+
+     } else {
+
+       while(!(addr[0] & 0x00800080)){         /* wait for error or finish */
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       return (1);
+       }
+
+       if( addr[0] & 0x003A003A) {     /* check for error */
+               barf = addr[0] & 0x003A0000;
+               if( barf ) {
+                       barf >>=16;
+               } else {
+                       barf = addr[0] & 0x0000003A;
+               }
+               printf("\nFlash write error at address %lx\n",(unsigned long)dest);
+               if(barf & 0x0002) printf("Block locked, not erased.\n");
+               if(barf & 0x0010) printf("Programming error.\n");
+               if(barf & 0x0008) printf("Vpp Low error.\n");
+               return(2);
+       }
+
+
+     }
+
+       return (0);
+
+}
+
+#else
+
+static int write_short (flash_info_t *info, ulong dest, ushort data)
+{
+       vu_short *addr = (vu_short*)(info->start[0]);
+       ulong start,barf;
+       int flag;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((vu_short *)dest) & data) != data) {
+               return (2);
+       }
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+     if(info->flash_id < FLASH_AMD_COMP) {
+       /* AMD stuff */
+       addr[0x0555] = 0x00AA;
+       addr[0x02AA] = 0x0055;
+       addr[0x0555] = 0x00A0;
+     } else {
+       /* intel stuff */
+        *addr = 0x00D0;
+       *addr = 0x0040;
+     }
+       *((vu_short *)dest) = data;
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* data polling for D7 */
+       start = get_timer (0);
+
+     if(info->flash_id < FLASH_AMD_COMP) {
+          /* AMD stuff */
+       while ((*((vu_short *)dest) & 0x0080) != (data & 0x0080)) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       return (1);
+               }
+       }
+
+     } else {
+       /* intel stuff */
+       while(!(addr[0] & 0x0080)){     /* wait for error or finish */
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
+       }
+
+       if( addr[0] & 0x003A) { /* check for error */
+               barf = addr[0] & 0x003A;
+               printf("\nFlash write error at address %lx\n",(unsigned long)dest);
+               if(barf & 0x0002) printf("Block locked, not erased.\n");
+               if(barf & 0x0010) printf("Programming error.\n");
+               if(barf & 0x0008) printf("Vpp Low error.\n");
+               return(2);
+       }
+       *addr = 0x00B0;
+       *addr = 0x0070;
+       while(!(addr[0] & 0x0080)){     /* wait for error or finish */
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) return (1);
+       }
+
+       *addr = 0x00FF;
+
+     }
+
+       return (0);
+
+}
+
+
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+
diff --git a/board/eric/init.S b/board/eric/init.S
new file mode 100644 (file)
index 0000000..bdf90a5
--- /dev/null
@@ -0,0 +1,355 @@
+/*------------------------------------------------------------------------------+ */
+/* */
+/*       This source code has been made available to you by IBM on an AS-IS */
+/*       basis.  Anyone receiving this source is licensed under IBM */
+/*       copyrights to use it in any way he or she deems fit, including */
+/*       copying it, modifying it, compiling it, and redistributing it either */
+/*       with or without modifications.  No license under IBM patents or */
+/*       patent applications is to be implied by the copyright license. */
+/* */
+/*       Any user of this software should understand that IBM cannot provide */
+/*       technical support for this software and will not be responsible for */
+/*       any consequences resulting from the use of this software. */
+/* */
+/*       Any person who transfers this source code or any derivative work */
+/*       must include the IBM copyright notice, this paragraph, and the */
+/*       preceding two paragraphs in the transferred software. */
+/* */
+/*       COPYRIGHT   I B M   CORPORATION 1995 */
+/*       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M */
+/*------------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------- */
+/* Function:     ext_bus_cntlr_init */
+/* Description:  Initializes the External Bus Controller for the external */
+/*             peripherals. IMPORTANT: For pass1 this code must run from */
+/*             cache since you can not reliably change a peripheral banks */
+/*             timing register (pbxap) while running code from that bank. */
+/*             For ex., since we are running from ROM on bank 0, we can NOT */
+/*             execute the code that modifies bank 0 timings from ROM, so */
+/*             we run it from cache. */
+/* */
+/*----------------------------------------------------------------------------- */
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1      /* avoid reading Linux autoconf.h file  */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+
+       .globl  ext_bus_cntlr_init
+ext_bus_cntlr_init:
+        mflr    r4                      /* save link register */
+        bl      ..getAddr
+..getAddr:
+        mflr    r3                      /* get address of ..getAddr */
+        mtlr    r4                      /* restore link register */
+        addi    r4,0,14                 /* set ctr to 10; used to prefetch */
+        mtctr   r4                      /* 10 cache lines to fit this function */
+                                        /* in cache (gives us 8x10=80 instrctns) */
+..ebcloop:
+        icbt    r0,r3                   /* prefetch cache line for addr in r3 */
+        addi    r3,r3,32               /* move to next cache line */
+        bdnz    ..ebcloop               /* continue for 10 cache lines */
+
+        /*------------------------------------------------------------------- */
+        /* Delay to ensure all accesses to ROM are complete before changing */
+       /* bank 0 timings. 200usec should be enough. */
+        /*   200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+        /*------------------------------------------------------------------- */
+       addis   r3,0,0x0
+        ori     r3,r3,0xA000          /* ensure 200usec have passed since reset */
+        mtctr   r3
+..spinlp:
+        bdnz    ..spinlp                /* spin loop */
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 0 (Flash) initialization (from openbios) */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb0ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS0_AP@h
+        ori     r4,r4,CS0_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb0cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS0_CR@h
+        ori     r4,r4,CS0_CR@l
+        mtdcr   ebccfgd,r4
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 1 (NVRAM/RTC) initialization */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb1ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS1_AP@h
+        ori     r4,r4,CS1_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb1cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS1_CR@h
+        ori     r4,r4,CS1_CR@l
+        mtdcr   ebccfgd,r4
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 2 (A/D converter) initialization */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb2ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS2_AP@h
+        ori     r4,r4,CS2_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb2cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS2_CR@h
+        ori     r4,r4,CS2_CR@l
+        mtdcr   ebccfgd,r4
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 3 (Ethernet PHY Reset) initialization */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb3ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS3_AP@h
+        ori     r4,r4,CS3_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb3cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS3_CR@h
+        ori     r4,r4,CS3_CR@l
+        mtdcr   ebccfgd,r4
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 4 (PC-MIP PRSNT1#) initialization */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb4ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS4_AP@h
+        ori     r4,r4,CS4_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb4cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS4_CR@h
+        ori     r4,r4,CS4_CR@l
+        mtdcr   ebccfgd,r4
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 5 (PC-MIP PRSNT2#) initialization */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb5ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS5_AP@h
+        ori     r4,r4,CS5_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb5cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS5_CR@h
+        ori     r4,r4,CS5_CR@l
+        mtdcr   ebccfgd,r4
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 6 (CPU LED0) initialization */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb6ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS6_AP@h
+        ori     r4,r4,CS6_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb6cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS6_CR@h
+        ori     r4,r4,CS5_CR@l
+        mtdcr   ebccfgd,r4
+
+        /*----------------------------------------------------------------------- */
+        /* Memory Bank 7 (CPU LED1) initialization */
+        /*----------------------------------------------------------------------- */
+
+        addi    r4,0,pb7ap
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS7_AP@h
+        ori     r4,r4,CS7_AP@l
+        mtdcr   ebccfgd,r4
+
+        addi    r4,0,pb7cr
+        mtdcr   ebccfga,r4
+        addis   r4,0,CS7_CR@h
+        ori     r4,r4,CS7_CR@l
+        mtdcr   ebccfgd,r4
+
+/*     addis   r4,r0,FPGA_BRDC@h */
+/*        ori     r4,r4,FPGA_BRDC@l */
+/*        lbz     r3,0(r4)                //get FPGA board control reg */
+/*        eieio */
+/*        ori  r3,r3,0x01              //set UART1 control to select CTS/RTS */
+/*     stb     r3,0(r4) */
+
+       nop                             /* pass2 DCR errata #8 */
+        blr
+
+/*----------------------------------------------------------------------------- */
+/* Function:     sdram_init */
+/* Description:  Configures SDRAM memory banks on ERIC. */
+/*               We do manually init our SDRAM. */
+/*               If we have two SDRAM banks, simply undef SINGLE_BANK (ROLF :-) */
+/*              It is assumed that a 32MB 12x8(2) SDRAM is used. */
+/*----------------------------------------------------------------------------- */
+        .globl  sdram_init
+
+sdram_init:
+
+       mflr    r31
+
+#ifdef CFG_SDRAM_MANUALLY
+        /*------------------------------------------------------------------- */
+        /* Set MB0CF for bank 0. (0-32MB) Address Mode 4 since 12x8(2) */
+        /*------------------------------------------------------------------- */
+
+        addi    r4,0,mem_mb0cf
+        mtdcr   memcfga,r4
+        addis   r4,0,MB0CF@h
+        ori     r4,r4,MB0CF@l
+        mtdcr   memcfgd,r4
+
+        /*------------------------------------------------------------------- */
+        /* Set MB1CF for bank 1. (32MB-64MB) Address Mode 4 since 12x8(2) */
+        /*------------------------------------------------------------------- */
+
+        addi    r4,0,mem_mb1cf
+        mtdcr   memcfga,r4
+        addis   r4,0,MB1CF@h
+        ori     r4,r4,MB1CF@l
+        mtdcr   memcfgd,r4
+
+        /*------------------------------------------------------------------- */
+        /* Set MB2CF for bank 2. off */
+        /*------------------------------------------------------------------- */
+
+        addi    r4,0,mem_mb2cf
+        mtdcr   memcfga,r4
+        addis   r4,0,MB2CF@h
+        ori     r4,r4,MB2CF@l
+        mtdcr   memcfgd,r4
+
+        /*------------------------------------------------------------------- */
+        /* Set MB3CF for bank 3. off */
+        /*------------------------------------------------------------------- */
+
+        addi    r4,0,mem_mb3cf
+        mtdcr   memcfga,r4
+        addis   r4,0,MB3CF@h
+        ori     r4,r4,MB3CF@l
+        mtdcr   memcfgd,r4
+
+        /*------------------------------------------------------------------- */
+        /* Set the SDRAM Timing reg, SDTR1 and the refresh timer reg, RTR. */
+        /* To set the appropriate timings, we need to know the SDRAM speed. */
+       /* We can use the PLB speed since the SDRAM speed is the same as */
+       /* the PLB speed. The PLB speed is the FBK divider times the */
+       /* 405GP reference clock, which on the Walnut board is 33Mhz. */
+       /* Thus, if FBK div is 2, SDRAM is 66Mhz; if FBK div is 3, SDRAM is */
+       /* 100Mhz; if FBK is 3, SDRAM is 133Mhz. */
+       /* NOTE: The Walnut board supports SDRAM speeds of 66Mhz, 100Mhz, and */
+       /* maybe 133Mhz. */
+        /*------------------------------------------------------------------- */
+
+        mfdcr   r5,strap                 /* determine FBK divider */
+                                          /* via STRAP reg to calc PLB speed. */
+                                          /* SDRAM speed is the same as the PLB */
+                                         /* speed. */
+        rlwinm  r4,r5,4,0x3             /* get FBK divide bits */
+
+..chk_66:
+        cmpi    %cr0,0,r4,0x1
+        bne     ..chk_100
+       addis   r6,0,SDTR_66@h          /* SDTR1 value for 66Mhz */
+       ori     r6,r6,SDTR_66@l
+       addis   r7,0,RTR_66             /* RTR value for 66Mhz */
+        b      ..sdram_ok
+..chk_100:
+        cmpi    %cr0,0,r4,0x2
+        bne     ..chk_133
+        addis   r6,0,SDTR_100@h        /* SDTR1 value for 100Mhz */
+        ori     r6,r6,SDTR_100@l
+        addis   r7,0,RTR_100           /* RTR value for 100Mhz */
+        b       ..sdram_ok
+..chk_133:
+        addis   r6,0,0x0107            /* SDTR1 value for 133Mhz */
+        ori     r6,r6,0x4015
+        addis   r7,0,0x07F0            /* RTR value for 133Mhz */
+
+..sdram_ok:
+        /*------------------------------------------------------------------- */
+        /* Set SDTR1 */
+        /*------------------------------------------------------------------- */
+        addi    r4,0,mem_sdtr1
+        mtdcr   memcfga,r4
+        mtdcr   memcfgd,r6
+
+        /*------------------------------------------------------------------- */
+        /* Set RTR */
+        /*------------------------------------------------------------------- */
+        addi    r4,0,mem_rtr
+        mtdcr   memcfga,r4
+        mtdcr   memcfgd,r7
+
+        /*------------------------------------------------------------------- */
+        /* Delay to ensure 200usec have elapsed since reset. Assume worst */
+        /* case that the core is running 200Mhz: */
+        /*   200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+        /*------------------------------------------------------------------- */
+        addis   r3,0,0x0000
+        ori     r3,r3,0xA000          /* ensure 200usec have passed since reset */
+        mtctr   r3
+..spinlp2:
+        bdnz    ..spinlp2               /* spin loop */
+
+        /*------------------------------------------------------------------- */
+        /* Set memory controller options reg, MCOPT1. */
+       /* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst */
+       /* read/prefetch. */
+        /*------------------------------------------------------------------- */
+        addi    r4,0,mem_mcopt1
+        mtdcr   memcfga,r4
+        addis   r4,0,0x8080             /* set DC_EN=1 */
+        ori     r4,r4,0x0000
+        mtdcr   memcfgd,r4
+
+        /*------------------------------------------------------------------- */
+        /* Delay to ensure 10msec have elapsed since reset. This is */
+        /* required for the MPC952 to stabalize. Assume worst */
+        /* case that the core is running 200Mhz: */
+        /*   200,000,000 (cycles/sec) X .010 (sec) = 0x1E8480 cycles */
+        /* This delay should occur before accessing SDRAM. */
+        /*------------------------------------------------------------------- */
+        addis   r3,0,0x001E
+        ori     r3,r3,0x8480          /* ensure 10msec have passed since reset */
+        mtctr   r3
+..spinlp3:
+        bdnz    ..spinlp3                /* spin loop */
+
+#else
+/*fixme: do SDRAM Autoconfig from EEPROM here */
+
+#endif
+        mtlr    r31                     /* restore lr */
+        blr
diff --git a/board/esd/ar405/flash.c b/board/esd/ar405/flash.c
new file mode 100644 (file)
index 0000000..4fa6b27
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/*
+ * include common flash code (for esd boards)
+ */
+#include "../common/flash.c"
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       unsigned long size_b0, size_b1;
+       int i;
+        uint pbcr;
+        unsigned long base_b0, base_b1;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+
+       base_b0 = FLASH_BASE0_PRELIM;
+       size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]);
+
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+
+       base_b1 = FLASH_BASE1_PRELIM;
+       size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]);
+
+       /* Re-do sizing to get full correct info */
+
+        if (size_b1)
+          {
+            mtdcr(ebccfga, pb0cr);
+            pbcr = mfdcr(ebccfgd);
+            mtdcr(ebccfga, pb0cr);
+            base_b1 = -size_b1;
+            pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
+            mtdcr(ebccfgd, pbcr);
+            /*          printf("pb1cr = %x\n", pbcr); */
+          }
+
+        if (size_b0)
+          {
+            mtdcr(ebccfga, pb1cr);
+            pbcr = mfdcr(ebccfgd);
+            mtdcr(ebccfga, pb1cr);
+            base_b0 = base_b1 - size_b0;
+            pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+            mtdcr(ebccfgd, pbcr);
+            /*            printf("pb0cr = %x\n", pbcr); */
+          }
+
+       size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]);
+
+       flash_get_offsets (base_b0, &flash_info[0]);
+
+       /* monitor protection ON by default */
+       (void)flash_protect(FLAG_PROTECT_SET,
+                           base_b0+size_b0-CFG_MONITOR_LEN,
+                           base_b0+size_b0-1,
+                           &flash_info[0]);
+
+       if (size_b1) {
+               /* Re-do sizing to get full correct info */
+               size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]);
+
+               flash_get_offsets (base_b1, &flash_info[1]);
+
+               /* monitor protection ON by default */
+               (void)flash_protect(FLAG_PROTECT_SET,
+                                   base_b1+size_b1-CFG_MONITOR_LEN,
+                                   base_b1+size_b1-1,
+                                   &flash_info[1]);
+                /* monitor protection OFF by default (one is enough) */
+                (void)flash_protect(FLAG_PROTECT_CLEAR,
+                                    base_b0+size_b0-CFG_MONITOR_LEN,
+                                    base_b0+size_b0-1,
+                                    &flash_info[0]);
+       } else {
+               flash_info[1].flash_id = FLASH_UNKNOWN;
+               flash_info[1].sector_count = -1;
+       }
+
+       flash_info[0].size = size_b0;
+       flash_info[1].size = size_b1;
+
+       return (size_b0 + size_b1);
+}
diff --git a/board/esd/canbt/flash.c b/board/esd/canbt/flash.c
new file mode 100644 (file)
index 0000000..214948f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/*
+ * include common flash code (for esd boards)
+ */
+#include "../common/flash.c"
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       unsigned long size_b0;
+       int i;
+        uint pbcr;
+        unsigned long base_b0;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+
+       size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+
+        /* Setup offsets */
+        flash_get_offsets (-size_b0, &flash_info[0]);
+
+        /* Re-do sizing to get full correct info */
+        mtdcr(ebccfga, pb0cr);
+        pbcr = mfdcr(ebccfgd);
+        mtdcr(ebccfga, pb0cr);
+        base_b0 = -size_b0;
+        pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+        mtdcr(ebccfgd, pbcr);
+        /*          printf("pb1cr = %x\n", pbcr); */
+
+        /* Monitor protection ON by default */
+        (void)flash_protect(FLAG_PROTECT_SET,
+                            -CFG_MONITOR_LEN,
+                            0xffffffff,
+                            &flash_info[0]);
+
+        flash_info[0].size = size_b0;
+
+       return (size_b0);
+}
diff --git a/board/esd/cpciiser4/flash.c b/board/esd/cpciiser4/flash.c
new file mode 100644 (file)
index 0000000..214948f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+/*
+ * include common flash code (for esd boards)
+ */
+#include "../common/flash.c"
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       unsigned long size_b0;
+       int i;
+        uint pbcr;
+        unsigned long base_b0;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+
+       size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+
+        /* Setup offsets */
+        flash_get_offsets (-size_b0, &flash_info[0]);
+
+        /* Re-do sizing to get full correct info */
+        mtdcr(ebccfga, pb0cr);
+        pbcr = mfdcr(ebccfgd);
+        mtdcr(ebccfga, pb0cr);
+        base_b0 = -size_b0;
+        pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+        mtdcr(ebccfgd, pbcr);
+        /*          printf("pb1cr = %x\n", pbcr); */
+
+        /* Monitor protection ON by default */
+        (void)flash_protect(FLAG_PROTECT_SET,
+                            -CFG_MONITOR_LEN,
+                            0xffffffff,
+                            &flash_info[0]);
+
+        flash_info[0].size = size_b0;
+
+       return (size_b0);
+}
diff --git a/board/esd/dasa_sim/eeprom.c b/board/esd/dasa_sim/eeprom.c
new file mode 100644 (file)
index 0000000..59ef1d6
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
+ *
+ * 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
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+
+
+#define EEPROM_CAP              0x50000358
+#define EEPROM_DATA             0x5000035c
+
+
+unsigned int eepromReadLong(int offs)
+{
+  unsigned int value;
+  volatile unsigned short ret;
+  int count;
+
+  *(unsigned short *)EEPROM_CAP = offs;
+
+  count = 0;
+
+  for (;;)
+    {
+      count++;
+      ret = *(unsigned short *)EEPROM_CAP;
+
+      if ((ret & 0x8000) != 0)
+        break;
+    }
+
+  value = *(unsigned long *)EEPROM_DATA;
+
+  return value;
+}
+
+
+unsigned char eepromReadByte(int offs)
+{
+  unsigned int valueLong;
+  unsigned char *ptr;
+
+  valueLong = eepromReadLong(offs & ~3);
+  ptr = (unsigned char *)&valueLong;
+
+  return ptr[offs & 3];
+}
+
+
+void eepromWriteLong(int offs, unsigned int value)
+{
+  volatile unsigned short ret;
+  int count;
+
+  count = 0;
+
+  *(unsigned long *)EEPROM_DATA = value;
+  *(unsigned short *)EEPROM_CAP = 0x8000 + offs;
+
+  for (;;)
+    {
+      count++;
+      ret = *(unsigned short *)EEPROM_CAP;
+
+      if ((ret & 0x8000) == 0)
+        break;
+    }
+}
+
+
+void eepromWriteByte(int offs, unsigned char valueByte)
+{
+  unsigned int valueLong;
+  unsigned char *ptr;
+
+  valueLong = eepromReadLong(offs & ~3);
+  ptr = (unsigned char *)&valueLong;
+
+  ptr[offs & 3] = valueByte;
+
+  eepromWriteLong(offs & ~3, valueLong);
+}
+
+
+void i2c_read (uchar *addr, int alen, uchar *buffer, int len)
+{
+  int i;
+  int len2, ptr;
+
+  /*  printf("\naddr=%x alen=%x buffer=%x len=%x", addr[0], addr[1], *(short *)addr, alen, buffer, len); // test-only */
+
+  ptr = *(short *)addr;
+
+  /*
+   * Read till lword boundary
+   */
+  len2 = 4 - (*(short *)addr & 0x0003);
+  for (i=0; i<len2; i++)
+    {
+      *buffer++ = eepromReadByte(ptr++);
+    }
+
+  /*
+   * Read all lwords
+   */
+  len2 = (len - len2) >> 2;
+  for (i=0; i<len2; i++)
+    {
+      *(unsigned int *)buffer = eepromReadLong(ptr);
+      buffer += 4;
+      ptr += 4;
+    }
+
+  /*
+   * Read last bytes
+   */
+  len2 = (*(short *)addr + len) & 0x0003;
+  for (i=0; i<len2; i++)
+    {
+      *buffer++ = eepromReadByte(ptr++);
+    }
+}
+
+void i2c_write (uchar *addr, int alen, uchar *buffer, int len)
+{
+  int i;
+  int len2, ptr;
+
+  /*  printf("\naddr=%x alen=%x buffer=%x len=%x", addr[0], addr[1], *(short *)addr, alen, buffer, len); // test-only */
+
+  ptr = *(short *)addr;
+
+  /*
+   * Write till lword boundary
+   */
+  len2 = 4 - (*(short *)addr & 0x0003);
+  for (i=0; i<len2; i++)
+    {
+      eepromWriteByte(ptr++, *buffer++);
+    }
+
+  /*
+   * Write all lwords
+   */
+  len2 = (len - len2) >> 2;
+  for (i=0; i<len2; i++)
+    {
+      eepromWriteLong(ptr, *(unsigned int *)buffer);
+      buffer += 4;
+      ptr += 4;
+    }
+
+  /*
+   * Write last bytes
+   */
+  len2 = (*(short *)addr + len) & 0x0003;
+  for (i=0; i<len2; i++)
+    {
+      eepromWriteByte(ptr++, *buffer++);
+    }
+}
diff --git a/board/evb64260/ecctest.c b/board/evb64260/ecctest.c
new file mode 100644 (file)
index 0000000..e7c58b3
--- /dev/null
@@ -0,0 +1,91 @@
+#ifdef ECC_TEST
+static inline void ecc_off(void)
+{
+       *(volatile int *)(INTERNAL_REG_BASE_ADDR+0x4b4) &= ~0x00200000;
+}
+
+static inline void ecc_on(void)
+{
+       *(volatile int *)(INTERNAL_REG_BASE_ADDR+0x4b4) |= 0x00200000;
+}
+
+static int putshex(const char *buf, int len)
+{
+    int i;
+    for (i=0;i<len;i++) {
+       printf("%02x", buf[i]);
+    }
+    return 0;
+}
+
+static int char_memcpy(void *d, const void *s, int len)
+{
+    int i;
+    char *cd=d;
+    const char *cs=s;
+    for(i=0;i<len;i++) {
+       *(cd++)=*(cs++);
+    }
+    return 0;
+}
+
+static int memory_test(char *buf)
+{
+    const char src[][16]={
+       {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0},
+       {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+       {0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02},
+       {0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04},
+       {0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08},
+       {0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10},
+       {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
+       {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40},
+       {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},
+       {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55},
+       {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa},
+       {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}
+    };
+    const int foo[] = {0};
+    int i,j,a;
+
+    printf("\ntest @ %d %p\n", foo[0], buf);
+    for(i=0;i<12;i++) {
+       for(a=0;a<8;a++) {
+           const char *s=src[i]+a;
+           int align=(unsigned)(s)&0x7;
+           /* ecc_off(); */
+           memcpy(buf,s,8);
+           /* ecc_on(); */
+           putshex(s,8);
+           if(memcmp(buf,s,8)) {
+               putc('\n');
+               putshex(buf,8);
+               printf(" [FAIL] (%p) align=%d\n", s, align);
+               for(j=0;j<8;j++) {
+                   s[j]==buf[j]?puts("  "):printf("%02x", (s[j])^(buf[j]));
+               }
+               putc('\n');
+           } else {
+               printf(" [PASS] (%p) align=%d\n", s, align);
+           }
+           /* ecc_off(); */
+           char_memcpy(buf,s,8);
+           /* ecc_on(); */
+           putshex(s,8);
+           if(memcmp(buf,s,8)) {
+               putc('\n');
+               putshex(buf,8);
+               printf(" [FAIL] (%p) align=%d\n", s, align);
+               for(j=0;j<8;j++) {
+                   s[j]==buf[j]?puts("  "):printf("%02x", (s[j])^(buf[j]));
+               }
+               putc('\n');
+           } else {
+               printf(" [PASS] (%p) align=%d\n", s, align);
+           }
+       }
+    }
+
+    return 0;
+}
+#endif
diff --git a/board/evb64260/eth.h b/board/evb64260/eth.h
new file mode 100644 (file)
index 0000000..ecc3762
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * eth.h - header file for the polled mode GT ethernet driver
+ */
+
+#ifndef __GT6426x_ETH_H__
+#define __GT6426x_ETH_H__
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <common.h>
+
+typedef struct eth0_tx_desc_struct {
+       volatile __u32 bytecount_reserved;
+       volatile __u32 command_status;
+       volatile struct eth0_tx_desc_struct * next_desc;
+       /* Note - the following will not work for 64 bit addressing */
+       volatile unsigned char * buff_pointer;
+} eth0_tx_desc_single __attribute__ ((packed));
+
+typedef struct eth0_rx_desc_struct {
+  volatile __u32 buff_size_byte_count;
+  volatile __u32 command_status;
+  volatile struct eth0_rx_desc_struct * next_desc;
+  volatile unsigned char * buff_pointer;
+} eth0_rx_desc_single __attribute__ ((packed));
+
+#define NT 20 /* Number of Transmit buffers */
+#define NR 20 /* Number of Receive buffers */
+#define MAX_BUFF_SIZE (1536+2*CACHE_LINE_SIZE) /* 1600 */
+#define ETHERNET_PORTS_DIFFERENCE_OFFSETS 0x400
+
+unsigned long TDN_ETH0 , RDN_ETH0; /* Rx/Tx current Descriptor Number*/
+unsigned int EVB64260_ETH0_irq;
+
+#define CLOSED 0
+#define OPENED 1
+
+#define PORT_ETH0 0
+
+extern eth0_tx_desc_single *eth0_tx_desc;
+extern eth0_rx_desc_single *eth0_rx_desc;
+extern char *eth0_tx_buffer;
+extern char *eth0_rx_buffer[NR];
+extern char *eth_data;
+
+extern int gt6426x_eth_poll(void *v);
+extern int gt6426x_eth_transmit(void *v, volatile char *p, unsigned int s);
+extern void gt6426x_eth_disable(void *v);
+extern int gt6426x_eth_probe(void *v, bd_t *bis);
+
+#endif  /* __GT64260x_ETH_H__ */
diff --git a/board/evb64260/mpsc.c b/board/evb64260/mpsc.c
new file mode 100644 (file)
index 0000000..31a6a0d
--- /dev/null
@@ -0,0 +1,864 @@
+/*
+ * (C) Copyright 2001
+ * John Clemens <clemens@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * mpsc.c - driver for console over the MPSC.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/cache.h>
+
+#include <malloc.h>
+#include "mpsc.h"
+
+int (*mpsc_putchar)(char ch) = mpsc_putchar_early;
+
+static volatile unsigned int *rx_desc_base=NULL;
+static unsigned int rx_desc_index=0;
+static volatile unsigned int *tx_desc_base=NULL;
+static unsigned int tx_desc_index=0;
+
+/* local function declarations */
+static int galmpsc_connect(int channel, int connect);
+static int galmpsc_route_serial(int channel, int connect);
+static int galmpsc_route_rx_clock(int channel, int brg);
+static int galmpsc_route_tx_clock(int channel, int brg);
+static int galmpsc_write_config_regs(int mpsc, int mode);
+static int galmpsc_config_channel_regs(int mpsc);
+static int galmpsc_set_char_length(int mpsc, int value);
+static int galmpsc_set_stop_bit_length(int mpsc, int value);
+static int galmpsc_set_parity(int mpsc, int value);
+static int galmpsc_enter_hunt(int mpsc);
+static int galmpsc_set_brkcnt(int mpsc, int value);
+static int galmpsc_set_tcschar(int mpsc, int value);
+static int galmpsc_set_snoop(int mpsc, int value);
+static int galmpsc_shutdown(int mpsc);
+
+static int galsdma_set_RFT(int channel);
+static int galsdma_set_SFM(int channel);
+static int galsdma_set_rxle(int channel);
+static int galsdma_set_txle(int channel);
+static int galsdma_set_burstsize(int channel, unsigned int value);
+static int galsdma_set_RC(int channel, unsigned int value);
+
+static int galbrg_set_CDV(int channel, int value);
+static int galbrg_enable(int channel);
+static int galbrg_disable(int channel);
+static int galbrg_set_clksrc(int channel, int value);
+static int galbrg_set_CUV(int channel, int value);
+
+static void galsdma_enable_rx(void);
+
+/* static int galbrg_reset(int channel); */
+
+#define SOFTWARE_CACHE_MANAGEMENT
+
+#ifdef SOFTWARE_CACHE_MANAGEMENT
+#define FLUSH_DCACHE(a,b)               if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));}
+#define FLUSH_AND_INVALIDATE_DCACHE(a,b) if(dcache_status()){flush_dcache_range((u32)(a),(u32)(b));}
+#define INVALIDATE_DCACHE(a,b)          if(dcache_status()){invalidate_dcache_range((u32)(a),(u32)(b));}
+#else
+#define FLUSH_DCACHE(a,b)
+#define FLUSH_AND_INVALIDATE_DCACHE(a,b)
+#define INVALIDATE_DCACHE(a,b)
+#endif
+
+
+/* GT64240A errata: cant read MPSC/BRG registers... so make mirrors in ram for read/modify write */
+#define MIRROR_HACK ((struct _tag_mirror_hack *)&(gd->mirror_hack))
+
+#define GT_REG_WRITE_MIRROR_G(a,d) {MIRROR_HACK->a ## _M = d; GT_REG_WRITE(a,d);}
+#define GTREGREAD_MIRROR_G(a) (MIRROR_HACK->a ## _M)
+
+#define GT_REG_WRITE_MIRROR(a,i,g,d) {MIRROR_HACK->a ## _M[i] = d; GT_REG_WRITE(a + (i*g),d);}
+#define GTREGREAD_MIRROR(a,i,g) (MIRROR_HACK->a ## _M[i])
+
+/* make sure this isn't bigger than 16 long words (u-boot.h) */
+struct _tag_mirror_hack {
+    unsigned GALMPSC_PROTOCONF_REG_M[2];       /* 8008 */
+    unsigned GALMPSC_CHANNELREG_1_M[2];                /* 800c */
+    unsigned GALMPSC_CHANNELREG_2_M[2];                /* 8010 */
+    unsigned GALBRG_0_CONFREG_M[2];            /* b200 */
+
+    unsigned GALMPSC_ROUTING_REGISTER_M;       /* b400 */
+    unsigned GALMPSC_RxC_ROUTE_M;              /* b404 */
+    unsigned GALMPSC_TxC_ROUTE_M;              /* b408 */
+
+    unsigned int baudrate;                     /* current baudrate, for tsc delay calc */
+};
+
+/* static struct _tag_mirror_hack *mh = NULL;   */
+
+/* special function for running out of flash.  doesn't modify any
+ * global variables [josh] */
+int
+mpsc_putchar_early(char ch)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       int mpsc=CHANNEL;
+       int temp=GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+       galmpsc_set_tcschar(mpsc,ch);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_2+(mpsc*GALMPSC_REG_GAP), temp|0x200);
+
+#define MAGIC_FACTOR   (10*1000000)
+
+       udelay(MAGIC_FACTOR / MIRROR_HACK->baudrate);
+       return 0;
+}
+
+/* This is used after relocation, see serial.c and mpsc_init2 */
+static int
+mpsc_putchar_sdma(char ch)
+{
+       volatile unsigned int *p;
+       unsigned int temp;
+
+
+       /* align the descriptor */
+       p = tx_desc_base;
+       memset((void *)p, 0, 8 * sizeof(unsigned int));
+
+       /* fill one 64 bit buffer */
+       /* word swap, pad with 0 */
+       p[4] = 0;                                               /* x */
+       p[5] = (unsigned int)ch;                                /* x */
+
+       /* CHANGED completely according to GT64260A dox - NTL */
+       p[0] = 0x00010001;                                      /* 0 */
+       p[1] = DESC_OWNER | DESC_FIRST | DESC_LAST;             /* 4 */
+       p[2] = 0;                                               /* 8 */
+       p[3] = (unsigned int)&p[4];                             /* c */
+
+#if 0
+       p[9] = DESC_FIRST | DESC_LAST;
+       p[10] = (unsigned int)&p[0];
+       p[11] = (unsigned int)&p[12];
+#endif
+
+       FLUSH_DCACHE(&p[0], &p[8]);
+
+       GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR+(CHANNEL*GALSDMA_REG_DIFF),
+                    (unsigned int)&p[0]);
+       GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR+(CHANNEL*GALSDMA_REG_DIFF),
+                    (unsigned int)&p[0]);
+
+       temp = GTREGREAD(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF));
+       temp |= (TX_DEMAND | TX_STOP);
+       GT_REG_WRITE(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF), temp);
+
+       INVALIDATE_DCACHE(&p[1], &p[2]);
+
+       while(p[1] & DESC_OWNER) {
+           udelay(100);
+           INVALIDATE_DCACHE(&p[1], &p[2]);
+       }
+
+       return 0;
+}
+
+char
+mpsc_getchar(void)
+{
+    DECLARE_GLOBAL_DATA_PTR;
+    static unsigned int done = 0;
+    volatile char ch;
+    unsigned int len=0, idx=0, temp;
+
+    volatile unsigned int *p;
+
+
+    do {
+       p=&rx_desc_base[rx_desc_index*8];
+
+       INVALIDATE_DCACHE(&p[0], &p[1]);
+       /* Wait for character */
+       while (p[1] & DESC_OWNER){
+           udelay(100);
+           INVALIDATE_DCACHE(&p[0], &p[1]);
+       }
+
+       /* Handle error case */
+       if (p[1] & (1<<15)) {
+               printf("oops, error: %08x\n", p[1]);
+
+               temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,CHANNEL,GALMPSC_REG_GAP);
+               temp |= (1 << 23);
+               GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2, CHANNEL,GALMPSC_REG_GAP, temp);
+
+               /* Can't poll on abort bit, so we just wait. */
+               udelay(100);
+
+               galsdma_enable_rx();
+       }
+
+       /* Number of bytes left in this descriptor */
+       len = p[0] & 0xffff;
+
+       if (len) {
+           /* Where to look */
+           idx = 5;
+           if (done > 3) idx = 4;
+           if (done > 7) idx = 7;
+           if (done > 11) idx = 6;
+
+           INVALIDATE_DCACHE(&p[idx], &p[idx+1]);
+           ch = p[idx] & 0xff;
+           done++;
+       }
+
+       if (done < len) {
+               /* this descriptor has more bytes still
+                * shift down the char we just read, and leave the
+                * buffer in place for the next time around
+                */
+               p[idx] =  p[idx] >> 8;
+               FLUSH_DCACHE(&p[idx], &p[idx+1]);
+       }
+
+       if (done == len) {
+               /* nothing left in this descriptor.
+                * go to next one
+                */
+               p[1] = DESC_OWNER | DESC_FIRST | DESC_LAST;
+               p[0] = 0x00100000;
+               FLUSH_DCACHE(&p[0], &p[1]);
+               /* Next descriptor */
+               rx_desc_index = (rx_desc_index + 1) % RX_DESC;
+               done = 0;
+       }
+    } while (len==0);  /* galileo bug.. len might be zero */
+
+    return ch;
+}
+
+int
+mpsc_test_char(void)
+{
+       volatile unsigned int *p=&rx_desc_base[rx_desc_index*8];
+
+       INVALIDATE_DCACHE(&p[1], &p[2]);
+
+       if (p[1] & DESC_OWNER) return 0;
+       else return 1;
+}
+
+int
+mpsc_init(int baud)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       memset(MIRROR_HACK, 0, sizeof(struct _tag_mirror_hack));
+       MIRROR_HACK->GALMPSC_ROUTING_REGISTER_M=0x3fffffff;
+
+       /* BRG CONFIG */
+       galbrg_set_baudrate(CHANNEL, baud);
+#ifdef CONFIG_ZUMA_V2
+       galbrg_set_clksrc(CHANNEL,0x8); /* connect TCLK -> BRG */
+#else
+       galbrg_set_clksrc(CHANNEL,0);
+#endif
+       galbrg_set_CUV(CHANNEL, 0);
+       galbrg_enable(CHANNEL);
+
+       /* Set up clock routing */
+       galmpsc_connect(CHANNEL, GALMPSC_CONNECT);
+       galmpsc_route_serial(CHANNEL, GALMPSC_CONNECT);
+       galmpsc_route_rx_clock(CHANNEL, CHANNEL);
+       galmpsc_route_tx_clock(CHANNEL, CHANNEL);
+
+       /* reset MPSC state */
+       galmpsc_shutdown(CHANNEL);
+
+       /* SDMA CONFIG */
+       galsdma_set_burstsize(CHANNEL, L1_CACHE_BYTES/8);       /* in 64 bit words (8 bytes) */
+       galsdma_set_txle(CHANNEL);
+       galsdma_set_rxle(CHANNEL);
+       galsdma_set_RC(CHANNEL, 0xf);
+       galsdma_set_SFM(CHANNEL);
+       galsdma_set_RFT(CHANNEL);
+
+       /* MPSC CONFIG */
+       galmpsc_write_config_regs(CHANNEL, GALMPSC_UART);
+       galmpsc_config_channel_regs(CHANNEL);
+       galmpsc_set_char_length(CHANNEL, GALMPSC_CHAR_LENGTH_8);       /* 8 */
+       galmpsc_set_parity(CHANNEL, GALMPSC_PARITY_NONE);              /* N */
+       galmpsc_set_stop_bit_length(CHANNEL, GALMPSC_STOP_BITS_1);     /* 1 */
+
+       /* COMM_MPSC CONFIG */
+#ifdef SOFTWARE_CACHE_MANAGEMENT
+       galmpsc_set_snoop(CHANNEL, 0);                                  /* disable snoop */
+#else
+       galmpsc_set_snoop(CHANNEL, 1);                                  /* enable snoop */
+#endif
+
+       return 0;
+}
+
+void
+mpsc_init2(void)
+{
+       int i;
+
+       mpsc_putchar = mpsc_putchar_sdma;
+
+       /* RX descriptors */
+       rx_desc_base = (unsigned int *)malloc(((RX_DESC+1)*8) *
+               sizeof(unsigned int));
+
+       /* align descriptors */
+       rx_desc_base = (unsigned int *)
+               (((unsigned int)rx_desc_base+32) & 0xFFFFFFF0);
+
+       rx_desc_index = 0;
+
+       memset((void *)rx_desc_base, 0, (RX_DESC*8)*sizeof(unsigned int));
+
+       for (i = 0; i < RX_DESC; i++) {
+               rx_desc_base[i*8 + 3] = (unsigned int)&rx_desc_base[i*8 + 4]; /* Buffer */
+               rx_desc_base[i*8 + 2] = (unsigned int)&rx_desc_base[(i+1)*8]; /* Next descriptor */
+               rx_desc_base[i*8 + 1] = DESC_OWNER | DESC_FIRST | DESC_LAST;  /* Command & control */
+               rx_desc_base[i*8] = 0x00100000;
+       }
+       rx_desc_base[(i-1)*8 + 2] = (unsigned int)&rx_desc_base[0];
+
+       FLUSH_DCACHE(&rx_desc_base[0], &rx_desc_base[RX_DESC*8]);
+       GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR+(CHANNEL*GALSDMA_REG_DIFF),
+                    (unsigned int)&rx_desc_base[0]);
+
+       /* TX descriptors */
+       tx_desc_base = (unsigned int *)malloc(((TX_DESC+1)*8) *
+               sizeof(unsigned int));
+
+       /* align descriptors */
+       tx_desc_base = (unsigned int *)
+               (((unsigned int)tx_desc_base+32) & 0xFFFFFFF0);
+
+       tx_desc_index = -1;
+
+       memset((void *)tx_desc_base, 0, (TX_DESC*8)*sizeof(unsigned int));
+
+       for (i = 0; i < TX_DESC; i++) {
+               tx_desc_base[i*8 + 5] = (unsigned int)0x23232323;
+               tx_desc_base[i*8 + 4] = (unsigned int)0x23232323;
+               tx_desc_base[i*8 + 3] = (unsigned int)&tx_desc_base[i*8 + 4];
+               tx_desc_base[i*8 + 2] = (unsigned int)&tx_desc_base[(i+1)*8];
+               tx_desc_base[i*8 + 1] = DESC_OWNER | DESC_FIRST | DESC_LAST;
+
+               /* set sbytecnt and shadow byte cnt to 1 */
+               tx_desc_base[i*8] = 0x00010001;
+       }
+       tx_desc_base[(i-1)*8 + 2] = (unsigned int)&tx_desc_base[0];
+
+       FLUSH_DCACHE(&tx_desc_base[0], &tx_desc_base[TX_DESC*8]);
+
+       udelay(100);
+
+       galsdma_enable_rx();
+
+       return;
+}
+
+int
+galbrg_set_baudrate(int channel, int rate)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       int clock;
+
+       galbrg_disable(channel);
+
+#ifdef CONFIG_ZUMA_V2
+       /* from tclk */
+       clock = (CFG_BUS_HZ/(16*rate)) - 1;
+#else
+       clock = (3686400/(16*rate)) - 1;
+#endif
+
+       galbrg_set_CDV(channel, clock);
+
+       galbrg_enable(channel);
+
+       MIRROR_HACK->baudrate = rate;
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+/* Below are all the private functions that no one else needs */
+
+static int
+galbrg_set_CDV(int channel, int value)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP);
+       temp &= 0xFFFF0000;
+       temp |= (value & 0x0000FFFF);
+       GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG,channel,GALBRG_REG_GAP, temp);
+
+       return 0;
+}
+
+static int
+galbrg_enable(int channel)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP);
+       temp |= 0x00010000;
+       GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP,temp);
+
+       return 0;
+}
+
+static int
+galbrg_disable(int channel)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP);
+       temp &= 0xFFFEFFFF;
+       GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG, channel, GALBRG_REG_GAP,temp);
+
+       return 0;
+}
+
+static int
+galbrg_set_clksrc(int channel, int value)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALBRG_0_CONFREG,channel, GALBRG_REG_GAP);
+       temp &= 0xFF83FFFF;
+       temp |= (value << 18);
+       GT_REG_WRITE_MIRROR(GALBRG_0_CONFREG,channel, GALBRG_REG_GAP,temp);
+
+       return 0;
+}
+
+static int
+galbrg_set_CUV(int channel, int value)
+{
+       GT_REG_WRITE(GALBRG_0_BTREG + (channel * GALBRG_REG_GAP), value);
+
+       return 0;
+}
+
+#if 0
+static int
+galbrg_reset(int channel)
+{
+       unsigned int temp;
+
+       temp = GTREGREAD(GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
+       temp |= 0x20000;
+       GT_REG_WRITE(GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
+
+       return 0;
+}
+#endif
+
+static int
+galsdma_set_RFT(int channel)
+{
+       unsigned int temp;
+
+        temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+       temp |= 0x00000001;
+       GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+       return 0;
+}
+
+static int
+galsdma_set_SFM(int channel)
+{
+       unsigned int temp;
+
+        temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+       temp |= 0x00000002;
+       GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+       return 0;
+}
+
+static int
+galsdma_set_rxle(int channel)
+{
+       unsigned int temp;
+
+        temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+       temp |= 0x00000040;
+       GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+       return 0;
+}
+
+static int
+galsdma_set_txle(int channel)
+{
+       unsigned int temp;
+
+        temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+       temp |= 0x00000080;
+       GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+       return 0;
+}
+
+static int
+galsdma_set_RC(int channel, unsigned int value)
+{
+       unsigned int temp;
+
+       temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+       temp &= ~0x0000003c;
+       temp |= (value << 2);
+       GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF), temp);
+
+       return 0;
+}
+
+static int
+galsdma_set_burstsize(int channel, unsigned int value)
+{
+       unsigned int temp;
+
+       temp = GTREGREAD(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF));
+       temp &= 0xFFFFCFFF;
+       switch (value) {
+        case 8:
+               GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+                            (temp | (0x3 << 12)));
+               break;
+
+        case 4:
+               GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+                            (temp | (0x2 << 12)));
+               break;
+
+        case 2:
+               GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+                            (temp | (0x1 << 12)));
+               break;
+
+        case 1:
+               GT_REG_WRITE(GALSDMA_0_CONF_REG+(channel*GALSDMA_REG_DIFF),
+                            (temp | (0x0 << 12)));
+               break;
+
+        default:
+               return -1;
+               break;
+       }
+
+       return 0;
+}
+
+static int
+galmpsc_connect(int channel, int connect)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR_G(GALMPSC_ROUTING_REGISTER);
+
+       if ((channel == 0) && connect)
+               temp &= ~0x00000007;
+       else if ((channel == 1) && connect)
+               temp &= ~(0x00000007 << 6);
+       else if ((channel == 0) && !connect)
+               temp |= 0x00000007;
+       else
+               temp |= (0x00000007 << 6);
+
+       /* Just in case... */
+       temp &= 0x3fffffff;
+
+       GT_REG_WRITE_MIRROR_G(GALMPSC_ROUTING_REGISTER, temp);
+
+       return 0;
+}
+
+static int
+galmpsc_route_serial(int channel, int connect)
+{
+       unsigned int temp;
+
+       temp = GTREGREAD(GALMPSC_SERIAL_MULTIPLEX);
+
+       if ((channel == 0) && connect)
+               temp |= 0x00000100;
+       else if ((channel == 1) && connect)
+               temp |= 0x00001000;
+       else if ((channel == 0) && !connect)
+               temp &= ~0x00000100;
+       else
+               temp &= ~0x00001000;
+
+       GT_REG_WRITE(GALMPSC_SERIAL_MULTIPLEX,temp);
+
+       return 0;
+}
+
+static int
+galmpsc_route_rx_clock(int channel, int brg)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR_G(GALMPSC_RxC_ROUTE);
+
+       if (channel == 0)
+               temp |= brg;
+       else
+               temp |= (brg << 8);
+
+       GT_REG_WRITE_MIRROR_G(GALMPSC_RxC_ROUTE,temp);
+
+       return 0;
+}
+
+static int
+galmpsc_route_tx_clock(int channel, int brg)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR_G(GALMPSC_TxC_ROUTE);
+
+       if (channel == 0)
+               temp |= brg;
+       else
+               temp |= (brg << 8);
+
+       GT_REG_WRITE_MIRROR_G(GALMPSC_TxC_ROUTE,temp);
+
+       return 0;
+}
+
+static int
+galmpsc_write_config_regs(int mpsc, int mode)
+{
+       if (mode == GALMPSC_UART) {
+               /* Main config reg Low (Null modem, Enable Tx/Rx, UART mode) */
+               GT_REG_WRITE(GALMPSC_MCONF_LOW + (mpsc*GALMPSC_REG_GAP),
+                            0x000004c4);
+
+               /* Main config reg High (32x Rx/Tx clock mode, width=8bits */
+               GT_REG_WRITE(GALMPSC_MCONF_HIGH +(mpsc*GALMPSC_REG_GAP),
+                            0x024003f8);
+               /*        22 2222 1111 */
+               /*        54 3210 9876 */
+               /* 0000 0010 0000 0000 */
+               /*       1 */
+               /*       098 7654 3210 */
+               /* 0000 0011 1111 1000 */
+       } else
+               return -1;
+
+       return 0;
+}
+
+static int
+galmpsc_config_channel_regs(int mpsc)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, 0);
+       GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, 0);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_3+(mpsc*GALMPSC_REG_GAP), 1);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_4+(mpsc*GALMPSC_REG_GAP), 0);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_5+(mpsc*GALMPSC_REG_GAP), 0);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_6+(mpsc*GALMPSC_REG_GAP), 0);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_7+(mpsc*GALMPSC_REG_GAP), 0);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_8+(mpsc*GALMPSC_REG_GAP), 0);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_9+(mpsc*GALMPSC_REG_GAP), 0);
+       GT_REG_WRITE(GALMPSC_CHANNELREG_10+(mpsc*GALMPSC_REG_GAP), 0);
+
+       galmpsc_set_brkcnt(mpsc, 0x3);
+       galmpsc_set_tcschar(mpsc, 0xab);
+
+       return 0;
+}
+
+static int
+galmpsc_set_brkcnt(int mpsc, int value)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP);
+       temp &= 0x0000FFFF;
+       temp |= (value << 16);
+       GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, temp);
+
+       return 0;
+}
+
+static int
+galmpsc_set_tcschar(int mpsc, int value)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP);
+       temp &= 0xFFFF0000;
+       temp |= value;
+       GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_1,mpsc,GALMPSC_REG_GAP, temp);
+
+       return 0;
+}
+
+static int
+galmpsc_set_char_length(int mpsc, int value)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP);
+       temp &= 0xFFFFCFFF;
+       temp |= (value << 12);
+       GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP, temp);
+
+       return 0;
+}
+
+static int
+galmpsc_set_stop_bit_length(int mpsc, int value)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP);
+       temp |= (value << 14);
+       GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG,mpsc,GALMPSC_REG_GAP,temp);
+
+       return 0;
+}
+
+static int
+galmpsc_set_parity(int mpsc, int value)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+       if (value != -1) {
+               temp &= 0xFFF3FFF3;
+               temp |= ((value << 18) | (value << 2));
+               temp |= ((value << 17) | (value << 1));
+       } else {
+               temp &= 0xFFF1FFF1;
+       }
+
+       GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, temp);
+
+       return 0;
+}
+
+static int
+galmpsc_enter_hunt(int mpsc)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       int temp;
+
+       temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+       temp |= 0x80000000;
+       GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP, temp);
+
+       /* Should Poll on Enter Hunt bit, but the register is write-only */
+       /* errata suggests pausing 100 system cycles */
+       udelay(100);
+
+       return 0;
+}
+
+
+static int
+galmpsc_shutdown(int mpsc)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int temp;
+
+       /* cause RX abort (clears RX) */
+       temp = GTREGREAD_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP);
+       temp |= MPSC_RX_ABORT | MPSC_TX_ABORT;
+       temp &= ~MPSC_ENTER_HUNT;
+       GT_REG_WRITE_MIRROR(GALMPSC_CHANNELREG_2,mpsc,GALMPSC_REG_GAP,temp);
+
+       GT_REG_WRITE(GALSDMA_0_COM_REG, 0);
+       GT_REG_WRITE(GALSDMA_0_COM_REG, SDMA_TX_ABORT | SDMA_RX_ABORT);
+
+       /* shut down the MPSC */
+       GT_REG_WRITE(GALMPSC_MCONF_LOW, 0);
+       GT_REG_WRITE(GALMPSC_MCONF_HIGH, 0);
+       GT_REG_WRITE_MIRROR(GALMPSC_PROTOCONF_REG, mpsc, GALMPSC_REG_GAP,0);
+
+       udelay(100);
+
+       /* shut down the sdma engines. */
+       /* reset config to default */
+       GT_REG_WRITE(GALSDMA_0_CONF_REG, 0x000000fc);
+
+       udelay(100);
+
+       /* clear the SDMA current and first TX and RX pointers */
+       GT_REG_WRITE(GALSDMA_0_CUR_RX_PTR, 0);
+       GT_REG_WRITE(GALSDMA_0_CUR_TX_PTR, 0);
+       GT_REG_WRITE(GALSDMA_0_FIR_TX_PTR, 0);
+
+       udelay(100);
+
+       return 0;
+}
+
+static void
+galsdma_enable_rx(void)
+{
+       int temp;
+
+       /* Enable RX processing */
+       temp = GTREGREAD(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF));
+       temp |= RX_ENABLE;
+       GT_REG_WRITE(GALSDMA_0_COM_REG+(CHANNEL*GALSDMA_REG_DIFF), temp);
+
+       galmpsc_enter_hunt(CHANNEL);
+}
+
+static int
+galmpsc_set_snoop(int mpsc, int value)
+{
+       int reg = mpsc ? MPSC_1_ADDRESS_CONTROL_LOW : MPSC_0_ADDRESS_CONTROL_LOW;
+       int temp=GTREGREAD(reg);
+       if(value)
+           temp |= (1<< 6) | (1<<14) | (1<<22) | (1<<30);
+       else
+           temp &= ~((1<< 6) | (1<<14) | (1<<22) | (1<<30));
+       GT_REG_WRITE(reg, temp);
+       return 0;
+}
diff --git a/board/evb64260/zuma_pbb.c b/board/evb64260/zuma_pbb.c
new file mode 100644 (file)
index 0000000..10c4845
--- /dev/null
@@ -0,0 +1,200 @@
+#include <common.h>
+#include <malloc.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+#include <command.h>
+#include <cmd_bsp.h>
+#endif
+
+#include <pci.h>
+#include <galileo/pci.h>
+#include "zuma_pbb.h"
+
+#undef DEBUG
+
+#define PAT_LO 0x00010203
+#define PAT_HI 0x04050607
+
+static PBB_DMA_REG_MAP *zuma_pbb_reg = NULL;
+
+static char test_buf1[2048];
+static char test_buf2[2048];
+
+int zuma_test_dma (int cmd, int size)
+{
+       static const char *const test_legend[] = {
+               "write", "verify",
+               "copy", "compare",
+               "write inc", "verify inc"
+       };
+       register int i, j;
+       unsigned int p1 = ((unsigned int) test_buf1 + 0xff) & (~0xff);
+       unsigned int p2 = ((unsigned int) test_buf2 + 0xff) & (~0xff);
+       volatile unsigned int *ps = (unsigned int *) p1;
+       volatile unsigned int *pd = (unsigned int *) p2;
+       unsigned int funct, pat_lo = PAT_LO, pat_hi = PAT_HI;
+       DMA_INT_STATUS stat;
+       int ret = 0;
+
+       if (!zuma_pbb_reg) {
+               printf ("not initted\n");
+               return -1;
+       }
+
+       if (cmd < 0 || cmd > 5) {
+               printf ("inv cmd %d\n", cmd);
+               return -1;
+       }
+
+       if (cmd == 2 || cmd == 3) {
+               /* not implemented */
+               return 0;
+       }
+
+       if (size <= 0 || size > 1024)
+               size = 1024;
+
+       size &= (~7);                           /* throw away bottom 3 bits */
+
+       p1 = ((unsigned int) test_buf1 + 0xff) & (~0xff);
+       p2 = ((unsigned int) test_buf2 + 0xff) & (~0xff);
+
+       memset ((void *) p1, 0, size);
+       memset ((void *) p2, 0, size);
+
+       for (i = 0; i < size / 4; i += 2) {
+               ps[i] = pat_lo;
+               ps[i + 1] = pat_hi;
+               if (cmd == 4 || cmd == 5) {
+                       unsigned char *pl = (unsigned char *) &pat_lo;
+                       unsigned char *ph = (unsigned char *) &pat_hi;
+
+                       for (j = 0; j < 4; j++) {
+                               pl[j] += 8;
+                               ph[j] += 8;
+                       }
+               }
+       }
+
+       funct = (1 << 31) | (cmd << 24) | (size);
+
+       zuma_pbb_reg->int_mask.pci_bits.chan0 =
+                       EOF_RX_FLAG | EOF_TX_FLAG | EOB_TX_FLAG;
+
+       zuma_pbb_reg->debug_57 = PAT_LO;        /* patl */
+       zuma_pbb_reg->debug_58 = PAT_HI;        /* path */
+
+       zuma_pbb_reg->debug_54 = cpu_to_le32 (p1);      /* src 0x01b0 */
+       zuma_pbb_reg->debug_55 = cpu_to_le32 (p2);      /* dst 0x01b8 */
+       zuma_pbb_reg->debug_56 = cpu_to_le32 (funct);   /* func, 0x01c0 */
+
+       /* give DMA time to chew on things.. dont use DRAM or PCI */
+       /* if you can avoid it. */
+       do {
+               for (i = 0; i < 1000 * 10; i++);
+       } while (le32_to_cpu (zuma_pbb_reg->debug_56) & (1 << 31));
+
+       stat.word = zuma_pbb_reg->status.word;
+       zuma_pbb_reg->int_mask.word = 0;
+
+       printf ("stat: %08x (%x)\n", stat.word, stat.pci_bits.chan0);
+
+       printf ("func: %08x\n", le32_to_cpu (zuma_pbb_reg->debug_56));
+       printf ("src @%08x: %08x %08x %08x %08x\n", p1, ps[0], ps[1], ps[2],
+                       ps[3]);
+       printf ("dst @%08x: %08x %08x %08x %08x\n", p2, pd[0], pd[1], pd[2],
+                       pd[3]);
+       printf ("func: %08x\n", le32_to_cpu (zuma_pbb_reg->debug_56));
+
+
+       if (cmd == 0 || cmd == 4) {
+               /* this is a write */
+               if (!(stat.pci_bits.chan0 & EOF_RX_FLAG) ||     /* not done */
+                       (memcmp ((void *) ps, (void *) pd, size) != 0)) {       /* cmp error */
+                       for (i = 0; i < size / 4; i += 2) {
+                               if ((ps[i] != pd[i]) || (ps[i + 1] != pd[i + 1])) {
+                                       printf ("s @%p:%08x %08x\n", &ps[i], ps[i], ps[i + 1]);
+                                       printf ("d @%p:%08x %08x\n", &pd[i], pd[i], pd[i + 1]);
+                               }
+                       }
+                       ret = -1;
+               }
+       } else {
+               /* this is a verify */
+               if (!(stat.pci_bits.chan0 & EOF_TX_FLAG) ||     /* not done */
+                       (stat.pci_bits.chan0 & EOB_TX_FLAG)) {  /* cmp error */
+                       printf ("%08x: %08x %08x\n",
+                                       le32_to_cpu (zuma_pbb_reg->debug_63),
+                                       zuma_pbb_reg->debug_61, zuma_pbb_reg->debug_62);
+                       ret = -1;
+               }
+       }
+
+       printf ("%s cmd %d, %d bytes: %s!\n", test_legend[cmd], cmd, size,
+                       (ret == 0) ? "PASSED" : "FAILED");
+       return 0;
+}
+
+void zuma_init_pbb (void)
+{
+       unsigned int iobase;
+       pci_dev_t dev =
+                       pci_find_device (VENDOR_ID_ZUMA, DEVICE_ID_ZUMA_PBB, 0);
+
+       if (dev == -1) {
+               printf ("no zuma pbb\n");
+               return;
+       }
+
+       pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &iobase);
+
+       zuma_pbb_reg =
+                       (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK);
+
+       if (!zuma_pbb_reg) {
+               printf ("zuma pbb bar none! (hah hah, get it?)\n");
+               return;
+       }
+
+       zuma_pbb_reg->int_mask.word = 0;
+
+       printf ("pbb @ %p v%d.%d, timestamp %08x\n", zuma_pbb_reg,
+                       zuma_pbb_reg->version.pci_bits.rev_major,
+                       zuma_pbb_reg->version.pci_bits.rev_minor,
+                       zuma_pbb_reg->timestamp);
+
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+static int last_cmd = 4;               /* write increment */
+static int last_size = 64;
+
+int
+do_zuma_init_pbb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       zuma_init_pbb ();
+       return 0;
+}
+
+int
+do_zuma_test_dma (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       if (argc > 1) {
+               last_cmd = simple_strtoul (argv[1], NULL, 10);
+       }
+       if (argc > 2) {
+               last_size = simple_strtoul (argv[2], NULL, 10);
+       }
+       zuma_test_dma (last_cmd, last_size);
+       return 0;
+}
+
+int
+do_zuma_init_mbox (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       zuma_mbox_init ();
+       return 0;
+}
+
+#endif /* CFG_CMD_BSP */
diff --git a/board/evb64260/zuma_pbb_mbox.c b/board/evb64260/zuma_pbb_mbox.c
new file mode 100644 (file)
index 0000000..5131339
--- /dev/null
@@ -0,0 +1,187 @@
+#include <common.h>
+#include <galileo/pci.h>
+#include <net.h>
+#include <pci.h>
+
+#include "zuma_pbb.h"
+#include "zuma_pbb_mbox.h"
+
+
+struct _zuma_mbox_dev zuma_mbox_dev;
+
+
+static int zuma_mbox_write(struct _zuma_mbox_dev *dev, unsigned int data)
+{
+  unsigned int status, count = 0, i;
+
+  status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+
+  while((status & OUT_PENDING) && count < 1000) {
+    count++;
+    for(i=0;i<1000;i++);
+    status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+  }
+  if(count < 1000) {
+    /* if SET it means msg pending */
+    /* printf("mbox real write %08x\n",data); */
+    dev->sip->mbox_out = cpu_to_le32(data);
+    return 4;
+  }
+
+  printf("mbox tx timeout\n");
+  return 0;
+}
+
+static int zuma_mbox_read(struct _zuma_mbox_dev *dev, unsigned int *data)
+{
+  unsigned int status, count = 0, i;
+
+  status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+
+  while(!(status & IN_VALID) && count < 1000) {
+    count++;
+    for(i=0;i<1000;i++);
+    status = (volatile int)le32_to_cpu(dev->sip->mbox_status);
+  }
+  if(count < 1000) {
+    /* if SET it means msg pending */
+    *data=le32_to_cpu(dev->sip->mbox_in);
+    /*printf("mbox real read %08x\n", *data); */
+    return 4;
+  }
+  printf("mbox rx timeout\n");
+  return 0;
+}
+
+static int zuma_mbox_do_one_mailbox(unsigned int out, unsigned int *in)
+{
+  int ret;
+  ret=zuma_mbox_write(&zuma_mbox_dev,out);
+  /*printf("write 0x%08x (%d bytes)\n", out, ret); */
+  if(ret!=4) return -1;
+  ret=zuma_mbox_read(&zuma_mbox_dev,in);
+  /*printf("read 0x%08x (%d bytes)\n", *in, ret); */
+  if(ret!=4) return -1;
+  return 0;
+}
+
+
+#define RET_IF_FAILED(x)       if ((x) == -1) return -1
+
+static int zuma_mbox_do_all_mailbox(void)
+{
+  unsigned int data_in;
+  unsigned short sdata_in;
+
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_START, &data_in));
+
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_MACL, &data_in));
+  memcpy(zuma_acc_mac+2,&data_in,4);
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_MACH, &data_in));
+  sdata_in=data_in&0xffff;
+  memcpy(zuma_acc_mac,&sdata_in,2);
+
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_IP, &data_in));
+  zuma_ip=data_in;
+
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_SLOT, &data_in));
+  zuma_slot_bac=data_in>>3;
+
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_BAUD, &data_in));
+  zuma_console_baud = data_in & 0xffff;
+  zuma_debug_baud   = data_in >> 16;
+
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_ENG_PRV_MACL, &data_in));
+  memcpy(zuma_prv_mac+2,&data_in,4);
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_ENG_PRV_MACH, &data_in));
+  sdata_in=data_in&0xffff;
+  memcpy(zuma_prv_mac,&sdata_in,2);
+
+  RET_IF_FAILED(zuma_mbox_do_one_mailbox(ZUMA_MBOXMSG_DONE, &data_in));
+
+  return 0;
+}
+
+
+static void
+zuma_mbox_dump(void)
+{
+  printf("ACC MAC=%04x%08x\n",*(unsigned short *)(&zuma_acc_mac),*(unsigned int *)((char *)&zuma_acc_mac+2));
+  printf("PRV MAC=%04x%08x\n",*(unsigned short *)(&zuma_prv_mac),*(unsigned int *)((char *)&zuma_prv_mac+2));
+  printf("slot:bac=%d:%d\n",(zuma_slot_bac>>2)&0xf, zuma_slot_bac & 0x3);
+  printf("BAUD1=%d BAUD2=%d\n",zuma_console_baud,zuma_debug_baud);
+}
+
+
+static void
+zuma_mbox_setenv(void)
+{
+  unsigned char *data, buf[32];
+  unsigned char save = 0;
+
+  data = getenv("baudrate");
+
+  if(!data || (zuma_console_baud != simple_strtoul(data, NULL, 10))) {
+    sprintf(buf, "%6d", zuma_console_baud);
+    setenv("baudrate", buf);
+    save=1;
+    printf("baudrate doesn't match from mbox\n");
+  }
+
+  ip_to_string(zuma_ip, buf);
+  setenv("ipaddr", buf);
+
+  sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x",
+         zuma_prv_mac[0],
+         zuma_prv_mac[1],
+         zuma_prv_mac[2],
+         zuma_prv_mac[3],
+         zuma_prv_mac[4],
+         zuma_prv_mac[5]);
+  setenv("ethaddr", buf);
+
+  sprintf(buf,"%02x",zuma_slot_bac);
+  setenv("bacslot", buf);
+
+  if(save)
+    saveenv();
+}
+
+/**
+ *     zuma_mbox_init:
+ */
+
+int zuma_mbox_init(void)
+{
+  unsigned int iobase;
+  memset(&zuma_mbox_dev, 0, sizeof(struct _zuma_mbox_dev));
+
+  zuma_mbox_dev.dev = pci_find_device(VENDOR_ID_ZUMA, DEVICE_ID_ZUMA_PBB, 0);
+
+  if(zuma_mbox_dev.dev == -1) {
+    printf("no zuma pbb\n");
+    return -1;
+  }
+
+  pci_read_config_dword(zuma_mbox_dev.dev, PCI_BASE_ADDRESS_0, &iobase);
+
+  zuma_mbox_dev.sip = (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK);
+
+  zuma_mbox_dev.sip->int_mask.word=0;
+
+  printf("pbb @ %p v%d.%d, timestamp %08x\n", zuma_mbox_dev.sip,
+        zuma_mbox_dev.sip->version.pci_bits.rev_major,
+        zuma_mbox_dev.sip->version.pci_bits.rev_minor,
+        zuma_mbox_dev.sip->timestamp);
+
+  if (zuma_mbox_do_all_mailbox() == -1) {
+         printf("mailbox failed.. no ACC?\n");
+         return -1;
+  }
+
+  zuma_mbox_dump();
+
+  zuma_mbox_setenv();
+
+  return 0;
+}
diff --git a/board/fads/fads.c b/board/fads/fads.c
new file mode 100644 (file)
index 0000000..3b97f51
--- /dev/null
@@ -0,0 +1,876 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.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
+ */
+
+#include <common.h>
+#include <config.h>
+#include <mpc8xx.h>
+#include "fads.h"
+
+/* ------------------------------------------------------------------------- */
+
+#define        _NOT_USED_      0xFFFFFFFF
+
+#if defined(CONFIG_DRAM_50MHZ)
+/* 50MHz tables */
+const uint dram_60ns[] =
+{ 0x8fffec24, 0x0fffec04, 0x0cffec04, 0x00ffec04,
+  0x00ffec00, 0x37ffec47, 0xffffffff, 0xffffffff,
+  0x8fffec24, 0x0fffec04, 0x08ffec04, 0x00ffec0c,
+  0x03ffec00, 0x00ffec44, 0x00ffcc08, 0x0cffcc44,
+  0x00ffec0c, 0x03ffec00, 0x00ffec44, 0x00ffcc00,
+  0x3fffc847, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06,
+  0xffffcc85, 0xffffcc05, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint dram_70ns[] =
+{ 0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04,
+  0x00ffcc00, 0x37ffcc47, 0xffffffff, 0xffffffff,
+  0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04,
+  0x00ffcc08, 0x0cffcc44, 0x00ffec0c, 0x03ffec00,
+  0x00ffec44, 0x00ffcc08, 0x0cffcc44, 0x00ffec04,
+  0x00ffec00, 0x3fffec47, 0xffffffff, 0xffffffff,
+  0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04,
+  0x7fffcc06, 0xffffcc85, 0xffffcc05, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_60ns[] =
+{ 0x8ffbec24, 0x0ff3ec04, 0x0cf3ec04, 0x00f3ec04,
+  0x00f3ec00, 0x37f7ec47, 0xffffffff, 0xffffffff,
+  0x8fffec24, 0x0ffbec04, 0x0cf3ec04, 0x00f3ec0c,
+  0x0cf3ec00, 0x00f3ec4c, 0x0cf3ec00, 0x00f3ec4c,
+  0x0cf3ec00, 0x00f3ec44, 0x03f3ec00, 0x3ff7ec47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x33bfcc4f, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06,
+  0xffffcc85, 0xffffcc05, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_70ns[] =
+{ 0x8ffbcc24, 0x0ff3cc04, 0x0cf3cc04, 0x00f3cc04,
+  0x00f3cc00, 0x37f7cc47, 0xffffffff, 0xffffffff,
+  0x8fffcc24, 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc0c,
+  0x03f3cc00, 0x00f3cc44, 0x00f3ec0c, 0x0cf3ec00,
+  0x00f3ec4c, 0x03f3ec00, 0x00f3ec44, 0x00f3cc00,
+  0x33f7cc47, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
+  0x0cafcc00, 0x33bfcc47, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04,
+  0x7fffcc04, 0xffffcc86, 0xffffcc05, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+#elif defined(CONFIG_DRAM_25MHZ)
+
+/* 25MHz tables */
+
+const uint dram_60ns[] =
+{ 0x0fffcc04, 0x08ffcc00, 0x33ffcc47, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c,
+  0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c,
+  0x08ffcc00, 0x33ffcc47, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fafcc04, 0x08afcc00, 0x3fbfcc47, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+  0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+  0x31bfcc43, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint dram_70ns[] =
+{ 0x0fffec04, 0x08ffec04, 0x00ffec00, 0x3fffcc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c,
+  0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c,
+  0x08ffcc00, 0x33ffcc47, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fafcc04, 0x08afcc00, 0x3fbfcc47, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+  0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
+  0x31bfcc43, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_60ns[] =
+{ 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0ffbcc04, 0x09f3cc0c, 0x09f3cc0c, 0x09f3cc0c,
+  0x08f3cc00, 0x3ff7cc47, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fefcc04, 0x08afcc00, 0x07afcc48, 0x08afcc48,
+  0x08afcc48, 0x39bfcc47, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+const uint edo_70ns[] =
+{ 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0ffbec04, 0x08f3ec04, 0x03f3ec48, 0x08f3cc00,
+  0x0ff3cc4c, 0x08f3cc00, 0x0ff3cc4c, 0x08f3cc00,
+  0x3ff7cc47, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x0fefcc04, 0x08afcc00, 0x07afcc4c, 0x08afcc00,
+  0x07afcc4c, 0x08afcc00, 0x07afcc4c, 0x08afcc00,
+  0x37bfcc47, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x33ffcc07, 0xffffffff, 0xffffffff, 0xffffffff };
+
+
+#else
+#error dram not correct defined - use CONFIG_DRAM_25MHZ or CONFIG_DRAM_50MHZ
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+       uint k;
+
+       puts ("Board: ");
+
+#ifdef CONFIG_FADS
+       k = (*((uint *)BCSR3) >> 24) & 0x3f;
+
+       switch(k) {
+       case 0x03 :
+       case 0x20 :
+       case 0x21 :
+       case 0x22 :
+       case 0x23 :
+       case 0x24 :
+       case 0x3f :
+               puts ("FADS");
+               break;
+
+       default :
+               printf("unknown board (0x%02x)\n", k);
+               return -1;
+       }
+
+       printf(" with db ");
+
+       switch(k) {
+       case 0x03 :
+               puts ("MPC823");
+               break;
+       case 0x20 :
+               puts ("MPC801");
+               break;
+       case 0x21 :
+               puts ("MPC850");
+               break;
+       case 0x22 :
+               puts ("MPC821, MPC860 / MPC860SAR / MPC860T");
+               break;
+       case 0x23 :
+               puts ("MPC860SAR");
+               break;
+       case 0x24 :
+               puts ("MPC860T");
+               break;
+       case 0x3f :
+               puts ("MPC850SAR");
+               break;
+       }
+
+       printf(" rev ");
+
+       k = (((*((uint *)BCSR3) >> 23) & 1) << 3)
+         | (((*((uint *)BCSR3) >> 19) & 1) << 2)
+         | (((*((uint *)BCSR3) >> 16) & 3));
+
+       switch(k) {
+       case 0x01 :
+               puts ("ENG or PILOT\n");
+               break;
+
+       default:
+               printf("unknown (0x%x)\n", k);
+               return -1;
+       }
+
+       return 0;
+#endif /* CONFIG_FADS */
+
+#ifdef CONFIG_ADS
+  printf("ADS rev ");
+
+  k = (((*((uint *)BCSR3) >> 23) & 1) << 3)
+    | (((*((uint *)BCSR3) >> 19) & 1) << 2)
+    | (((*((uint *)BCSR3) >> 16) & 3));
+
+  switch(k) {
+  case 0x00 : puts ("ENG - this board sucks, check the errata, not supported\n");
+              return -1;
+  case 0x01 : puts ("PILOT - warning, read errata \n"); break;
+  case 0x02 : puts ("A - warning, read errata \n"); break;
+  case 0x03 : puts ("B \n"); break;
+  default   : printf ("unknown revision (0x%x)\n", k); return -1;
+  }
+
+  return 0;
+#endif /* CONFIG_ADS */
+
+}
+
+/* ------------------------------------------------------------------------- */
+int _draminit(uint base, uint noMbytes, uint edo, uint delay)
+{
+       volatile immap_t     *immap = (immap_t *)CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+       /* init upm */
+
+       switch(delay)
+       {
+               case 70:
+               {
+                       if(edo)
+                       {
+                               upmconfig(UPMA, (uint *) edo_70ns, sizeof(edo_70ns)/sizeof(uint));
+                       }
+                       else
+                       {
+                               upmconfig(UPMA, (uint *) dram_70ns, sizeof(dram_70ns)/sizeof(uint));
+                       }
+
+                       break;
+               }
+
+               case 60:
+               {
+                       if(edo)
+                       {
+                               upmconfig(UPMA, (uint *) edo_60ns, sizeof(edo_60ns)/sizeof(uint));
+                       }
+                       else
+                       {
+                               upmconfig(UPMA, (uint *) dram_60ns, sizeof(dram_60ns)/sizeof(uint));
+                       }
+
+                       break;
+               }
+
+               default :
+                       return -1;
+       }
+
+       memctl->memc_mptpr = 0x0400; /* divide by 16 */
+
+       switch(noMbytes)
+       {
+
+               case 8:  /* 8 Mbyte uses both CS3 and CS2 */
+               {
+                       memctl->memc_mamr = 0x13a01114;
+                       memctl->memc_or3 = 0xffc00800;
+                       memctl->memc_br3 = 0x00400081 + base;
+                       memctl->memc_or2 = 0xffc00800;
+                       break;
+               }
+
+               case 4: /* 4 Mbyte uses only CS2 */
+               {
+                       memctl->memc_mamr = 0x13a01114;
+                       memctl->memc_or2 = 0xffc00800;
+                       break;
+               }
+
+               case 32: /* 32 Mbyte uses both CS3 and CS2 */
+               {
+                       memctl->memc_mamr = 0x13b01114;
+                       memctl->memc_or3 = 0xff000800;
+                       memctl->memc_br3 = 0x01000081 + base;
+                       memctl->memc_or2 = 0xff000800;
+                       break;
+               }
+
+               case 16: /* 16 Mbyte uses only CS2 */
+               {
+#ifdef CONFIG_ADS
+                       memctl->memc_mamr = 0x60b21114;
+#else
+                       memctl->memc_mamr = 0x13b01114;
+#endif
+                       memctl->memc_or2 = 0xff000800;
+                       break;
+               }
+
+               default:
+                   return -1;
+       }
+
+       memctl->memc_br2 = 0x81 + base;     /* use upma */
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void _dramdisable(void)
+{
+       volatile immap_t     *immap = (immap_t *)CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+       memctl->memc_br2 = 0x00000000;
+       memctl->memc_br3 = 0x00000000;
+
+       /* maybe we should turn off upma here or something */
+}
+
+#if defined(CONFIG_SDRAM_100MHZ)
+
+/* ------------------------------------------------------------------------- */
+/* sdram table by Dan Malek                                                  */
+
+/* This has the stretched early timing so the 50 MHz
+ * processor can make the 100 MHz timing.  This will
+ * work at all processor speeds.
+ */
+
+#define SDRAM_MPTPRVALUE 0x0400
+
+#define SDRAM_MBMRVALUE0 0xc3802114  /* (16-14) 50 MHz */
+#define SDRAM_MBMRVALUE1 SDRAM_MBMRVALUE0
+
+#define SDRAM_OR4VALUE   0xffc00a00
+#define SDRAM_BR4VALUE   0x000000c1   /* base address will be or:ed on */
+
+#define SDRAM_MARVALUE   0x88
+
+#define SDRAM_MCRVALUE0  0x80808111   /* run pattern 0x11 */
+#define SDRAM_MCRVALUE1  SDRAM_MCRVALUE0
+
+
+const uint sdram_table[] =
+{
+       /* single read. (offset 0 in upm RAM) */
+       0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x11adfc04,
+       0xefbbbc00, 0x1ff77c45, 0xffffffff, 0xffffffff,
+
+       /* burst read. (offset 8 in upm RAM) */
+       0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x10adfc04,
+       0xf0affc00, 0xf0affc00, 0xf1affc00, 0xefbbbc00,
+       0x1ff77c45, 0xeffbbc04, 0x1ff77c34, 0xefeabc34,
+       0x1fb57c35, 0xffffffff, 0xffffffff, 0xffffffff,
+
+       /* single write. (offset 18 in upm RAM) */
+       0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x01b93c04,
+       0x1ff77c45, 0xffffffff, 0xffffffff, 0xffffffff,
+
+       /* burst write. (offset 20 in upm RAM) */
+       0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x10ad7c00,
+       0xf0affc00, 0xf0affc00, 0xe1bbbc04, 0x1ff77c45,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+
+       /* refresh. (offset 30 in upm RAM) */
+       0xeffafc84, 0x1ff5fc04, 0xfffffc04, 0xfffffc04,
+       0xfffffc84, 0xfffffc07, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+
+       /* exception. (offset 3c in upm RAM) */
+       0xeffffc06, 0x1ffffc07, 0xffffffff, 0xffffffff };
+
+#elif defined(CONFIG_SDRAM_50MHZ)
+
+/* ------------------------------------------------------------------------- */
+/* sdram table stolen from the fads manual                                   */
+/* for chip MB811171622A-100                                                 */
+
+/* this table is for 32-50MHz operation */
+
+#define _not_used_ 0xffffffff
+
+#define SDRAM_MPTPRVALUE 0x0400
+
+#define SDRAM_MBMRVALUE0 0x80802114   /* refresh at 32MHz */
+#define SDRAM_MBMRVALUE1 0x80802118
+
+#define SDRAM_OR4VALUE   0xffc00a00
+#define SDRAM_BR4VALUE   0x000000c1   /* base address will be or:ed on */
+
+#define SDRAM_MARVALUE   0x88
+
+#define SDRAM_MCRVALUE0  0x80808105
+#define SDRAM_MCRVALUE1  0x80808130
+
+const uint sdram_table[] =
+{
+       /* single read. (offset 0 in upm RAM) */
+       0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+       0x1ff77c47,
+
+       /* MRS initialization (offset 5) */
+
+       0x1ff77c34, 0xefeabc34, 0x1fb57c35,
+
+       /* burst read. (offset 8 in upm RAM) */
+       0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+       0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
+       _not_used_, _not_used_, _not_used_, _not_used_,
+       _not_used_, _not_used_, _not_used_, _not_used_,
+
+       /* single write. (offset 18 in upm RAM) */
+       0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
+       _not_used_, _not_used_, _not_used_, _not_used_,
+
+       /* burst write. (offset 20 in upm RAM) */
+       0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+       0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
+       _not_used_, _not_used_, _not_used_, _not_used_,
+       _not_used_, _not_used_, _not_used_, _not_used_,
+
+       /* refresh. (offset 30 in upm RAM) */
+       0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+       0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
+       _not_used_, _not_used_, _not_used_, _not_used_,
+
+       /* exception. (offset 3c in upm RAM) */
+       0x7ffffc07, _not_used_, _not_used_, _not_used_ };
+
+/* ------------------------------------------------------------------------- */
+#else
+#error SDRAM not correctly configured
+#endif
+
+int _initsdram(uint base, uint noMbytes)
+{
+       volatile immap_t     *immap = (immap_t *)CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+       if(noMbytes != 4)
+       {
+               return -1;
+       }
+
+       upmconfig(UPMB, (uint *)sdram_table,sizeof(sdram_table)/sizeof(uint));
+
+       memctl->memc_mptpr = SDRAM_MPTPRVALUE;
+
+       /* Configure the refresh (mostly).  This needs to be
+       * based upon processor clock speed and optimized to provide
+       * the highest level of performance.  For multiple banks,
+       * this time has to be divided by the number of banks.
+       * Although it is not clear anywhere, it appears the
+       * refresh steps through the chip selects for this UPM
+       * on each refresh cycle.
+       * We have to be careful changing
+       * UPM registers after we ask it to run these commands.
+       */
+
+       memctl->memc_mbmr = SDRAM_MBMRVALUE0;
+       memctl->memc_mar = SDRAM_MARVALUE;  /* MRS code */
+
+       udelay(200);
+
+       /* Now run the precharge/nop/mrs commands.
+       */
+
+       memctl->memc_mcr = 0x80808111;   /* run pattern 0x11 */
+
+       udelay(200);
+
+       /* Run 8 refresh cycles */
+
+       memctl->memc_mcr = SDRAM_MCRVALUE0;
+
+       udelay(200);
+
+       memctl->memc_mbmr = SDRAM_MBMRVALUE1;
+       memctl->memc_mcr = SDRAM_MCRVALUE1;
+
+       udelay(200);
+
+       memctl->memc_mbmr = SDRAM_MBMRVALUE0;
+
+       memctl->memc_or4 = SDRAM_OR4VALUE;
+       memctl->memc_br4 = SDRAM_BR4VALUE | base;
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void _sdramdisable(void)
+{
+       volatile immap_t     *immap = (immap_t *)CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+       memctl->memc_br4 = 0x00000000;
+
+       /* maybe we should turn off upmb here or something */
+}
+
+/* ------------------------------------------------------------------------- */
+
+int initsdram(uint base, uint *noMbytes)
+{
+       uint m = 4;
+
+       *((uint *)BCSR1) |= BCSR1_SDRAM_EN; /* enable sdram */
+                                                                 /* _fads_sdraminit needs access to sdram */
+       *noMbytes = m;
+
+       if(!_initsdram(base, m))
+       {
+
+               return 0;
+       }
+       else
+       {
+               *((uint *)BCSR1) &= ~BCSR1_SDRAM_EN; /* disable sdram */
+
+               _sdramdisable();
+
+               return -1;
+       }
+}
+
+long int initdram (int board_type)
+{
+#ifdef CONFIG_ADS
+       /* ADS: has no SDRAM, so start DRAM at 0 */
+       uint base = (unsigned long)0x0;
+#else
+       /* FADS: has 4MB SDRAM, put DRAM above it */
+       uint base = (unsigned long)0x00400000;
+#endif
+       uint k, m, s;
+
+       k = (*((uint *)BCSR2) >> 23) & 0x0f;
+
+       m = 0;
+
+       switch(k & 0x3)
+       {
+               /* "MCM36100 / MT8D132X" */
+               case 0x00 :
+                       m = 4;
+                       break;
+
+               /* "MCM36800 / MT16D832X" */
+               case 0x01 :
+                       m = 32;
+                       break;
+               /* "MCM36400 / MT8D432X" */
+               case 0x02 :
+                       m = 16;
+                       break;
+               /* "MCM36200 / MT16D832X ?" */
+               case 0x03 :
+                       m = 8;
+                       break;
+
+       }
+
+       switch(k >> 2)
+       {
+               case 0x02 :
+                       k = 70;
+                       break;
+
+               case 0x03 :
+                       k = 60;
+                       break;
+
+               default :
+                       printf("unknown dramdelay (0x%x) - defaulting to 70 ns", k);
+                       k = 70;
+       }
+
+#ifdef CONFIG_FADS
+       /* the FADS is missing this bit, all rams treated as non-edo */
+       s = 0;
+#else
+       s = (*((uint *)BCSR2) >> 27) & 0x01;
+#endif
+
+       if(!_draminit(base, m, s, k))
+       {
+#ifdef CONFIG_FADS
+               uint    sdramsz;
+#endif
+               *((uint *)BCSR1) &= ~BCSR1_DRAM_EN;  /* enable dram */
+
+#ifdef CONFIG_FADS
+               if (!initsdram(0x00000000, &sdramsz)) {
+                               m += sdramsz;
+                               printf("(%u MB SDRAM) ", sdramsz);
+               } else {
+                               _dramdisable();
+
+                               /********************************
+                               *DRAM ERROR, HALT PROCESSOR
+                               *********************************/
+                               while(1);
+
+                               return -1;
+               }
+#endif
+
+               return (m << 20);
+       }
+       else
+       {
+               _dramdisable();
+
+               /********************************
+               *DRAM ERROR, HALT PROCESSOR
+               *********************************/
+               while(1);
+
+               return -1;
+       }
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+    /* TODO: XXX XXX XXX */
+    printf ("test: 16 MB - ok\n");
+
+    return (0);
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+#ifdef CFG_PCMCIA_MEM_ADDR
+volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
+#endif
+
+int pcmcia_init(void)
+{
+       volatile pcmconf8xx_t   *pcmp;
+       uint v, slota, slotb;
+
+       /*
+       ** Enable the PCMCIA for a Flash card.
+       */
+       pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+#if 0
+       pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR;
+       pcmp->pcmc_por0 = 0xc00ff05d;
+#endif
+
+       /* Set all slots to zero by default. */
+       pcmp->pcmc_pgcra = 0;
+       pcmp->pcmc_pgcrb = 0;
+#ifdef PCMCIA_SLOT_A
+       pcmp->pcmc_pgcra = 0x40;
+#endif
+#ifdef PCMCIA_SLOT_B
+       pcmp->pcmc_pgcrb = 0x40;
+#endif
+
+       /* enable PCMCIA buffers */
+       *((uint *)BCSR1) &= ~BCSR1_PCCEN;
+
+       /* Check if any PCMCIA card is plugged in. */
+
+       slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ;
+       slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ;
+
+       if (!(slota || slotb))
+       {
+               printf("No card present\n");
+#ifdef PCMCIA_SLOT_A
+               pcmp->pcmc_pgcra = 0;
+#endif
+#ifdef PCMCIA_SLOT_B
+               pcmp->pcmc_pgcrb = 0;
+#endif
+               return -1;
+       }
+       else
+               printf("Card present (");
+
+       v = 0;
+
+       /* both the ADS and the FADS have a 5V keyed pcmcia connector (?)
+       **
+       ** Paolo - Yes, but i have to insert some 3.3V card in that slot on
+       **         my FADS... :-)
+       */
+
+#if defined(CONFIG_MPC860)
+       switch( (pcmp->pcmc_pipr >> 30) & 3 )
+#elif defined(CONFIG_MPC823) || defined(CONFIG_MPC850)
+       switch( (pcmp->pcmc_pipr >> 14) & 3 )
+#endif
+       {
+               case 0x00 :
+                       printf("5V");
+                       v = 5;
+                       break;
+               case 0x01 :
+                       printf("5V and 3V");
+#ifdef CONFIG_FADS
+                       v = 3; /* User lower voltage if supported! */
+#else
+                       v = 5;
+#endif
+                       break;
+               case 0x03 :
+                       printf("5V, 3V and x.xV");
+#ifdef CONFIG_FADS
+                       v = 3; /* User lower voltage if supported! */
+#else
+                       v = 5;
+#endif
+                       break;
+       }
+
+       switch(v){
+#ifdef CONFIG_FADS
+       case 3:
+           printf("; using 3V");
+           /*
+           ** Enable 3 volt Vcc.
+           */
+           *((uint *)BCSR1) &= ~BCSR1_PCCVCC1;
+           *((uint *)BCSR1) |= BCSR1_PCCVCC0;
+           break;
+#endif
+       case 5:
+           printf("; using 5V");
+#ifdef CONFIG_ADS
+           /*
+           ** Enable 5 volt Vcc.
+           */
+           *((uint *)BCSR1) &= ~BCSR1_PCCVCCON;
+#endif
+#ifdef CONFIG_FADS
+           /*
+           ** Enable 5 volt Vcc.
+           */
+           *((uint *)BCSR1) &= ~BCSR1_PCCVCC0;
+           *((uint *)BCSR1) |= BCSR1_PCCVCC1;
+#endif
+           break;
+
+       default:
+               *((uint *)BCSR1) |= BCSR1_PCCEN;  /* disable pcmcia */
+
+               printf("; unknown voltage");
+               return -1;
+       }
+       printf(")\n");
+       /* disable pcmcia reset after a while */
+
+       udelay(20);
+
+#ifdef MPC860
+       pcmp->pcmc_pgcra = 0;
+#elif MPC823
+       pcmp->pcmc_pgcrb = 0;
+#endif
+
+       /* If you using a real hd you should give a short
+       * spin-up time. */
+#ifdef CONFIG_DISK_SPINUP_TIME
+       udelay(CONFIG_DISK_SPINUP_TIME);
+#endif
+
+       return 0;
+}
+
+#endif /* CFG_CMD_PCMCIA */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CFG_PC_IDE_RESET
+
+void ide_set_reset(int on)
+{
+       volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+       /*
+        * Configure PC for IDE Reset Pin
+        */
+       if (on) {               /* assert RESET */
+               immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
+       } else {                /* release RESET */
+               immr->im_ioport.iop_pcdat |=   CFG_PC_IDE_RESET;
+       }
+
+       /* program port pin as GPIO output */
+       immr->im_ioport.iop_pcpar &= ~(CFG_PC_IDE_RESET);
+       immr->im_ioport.iop_pcso  &= ~(CFG_PC_IDE_RESET);
+       immr->im_ioport.iop_pcdir |=   CFG_PC_IDE_RESET;
+}
+
+#endif /* CFG_PC_IDE_RESET */
+/* ------------------------------------------------------------------------- */
diff --git a/board/genietv/genietv.c b/board/genietv/genietv.c
new file mode 100644 (file)
index 0000000..8f32ad7
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * genietv/genietv.c
+ *
+ * The GENIETV is using the following physical memorymap (copied from
+ * the FADS configuration):
+ *
+ * ff020000 -> ff02ffff : pcmcia
+ * ff010000 -> ff01ffff : BCSR       connected to CS1, setup by 8xxROM
+ * ff000000 -> ff00ffff : IMAP       internal in the cpu
+ * 02800000 -> 0287ffff : flash      connected to CS0
+ * 00000000 -> nnnnnnnn : sdram      setup by U-Boot
+ *
+ * CS pins are connected as follows:
+ *
+ * CS0 -512Kb boot flash
+ * CS1 - SDRAM #1
+ * CS2 - SDRAM #2
+ * CS3 - Flash #1
+ * CS4 - Flash #2
+ * CS5 - LON (if present)
+ * CS6 - PCMCIA #1
+ * CS7 - PCMCIA #2
+ *
+ * Ports are configured as follows:
+ *
+ * PA7 - SDRAM banks enable
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+#define CFG_PA7                0x0100
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+#define        _NOT_USED_      0xFFFFFFFF
+
+const uint sdram_table[] =
+{
+       /*
+        * Single Read. (Offset 0 in UPMB RAM)
+        */
+       0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBEEC00,
+       0x1FFDDC47, /* last */
+       /*
+        * SDRAM Initialization (offset 5 in UPMB RAM)
+        *
+         * This is no UPM entry point. The following definition uses
+         * the remaining space to establish an initialization
+         * sequence, which is executed by a RUN command.
+        *
+        */
+                   0x1FFDDC34, 0xEFEEAC34, 0x1FBD5C35, /* last */
+       /*
+        * Burst Read. (Offset 8 in UPMB RAM)
+        */
+       0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
+       0xF0AFFC00, 0xF1AFFC00, 0xEFBEEC00, 0x1FFDDC47, /* last */
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       /*
+        * Single Write. (Offset 18 in UPMB RAM)
+        */
+       0x1F2DFC04, 0xEEAFAC00, 0x01BE4C04, 0x1FFDDC47, /* last */
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       /*
+        * Burst Write. (Offset 20 in UPMB RAM)
+        */
+       0x1F0DFC04, 0xEEAFAC00, 0x10AF5C00, 0xF0AFFC00,
+       0xF0AFFC00, 0xE1BEEC04, 0x1FFDDC47, /* last */
+                                           _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       /*
+        * Refresh  (Offset 30 in UPMB RAM)
+        */
+       0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
+       0xFFFFFC84, 0xFFFFFC07, /* last */
+                               _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       /*
+        * Exception. (Offset 3c in UPMB RAM)
+        */
+       0x7FFFFC07, /* last */
+                   _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity
+ */
+
+int checkboard (void)
+{
+    puts ("Board: GenieTV\n");
+    return 0;
+}
+
+#if 0
+static void PrintState(void)
+{
+    volatile immap_t     *im  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &im->im_memctl;
+
+    printf("\n0 - FLASH: B=%08x O=%08x", memctl->memc_br0, memctl->memc_or0);
+    printf("\n1 - SDRAM: B=%08x O=%08x", memctl->memc_br1, memctl->memc_or1);
+    printf("\n2 - SDRAM: B=%08x O=%08x", memctl->memc_br2, memctl->memc_or2);
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+    volatile immap_t     *im  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &im->im_memctl;
+    long int size_b0, size_b1, size8;
+
+    /* Enable SDRAM */
+
+    /* Configuring PA7 for general purpouse output pin */
+    im->im_ioport.iop_papar &= ~CFG_PA7 ;      /* 0 = general purpouse */
+    im->im_ioport.iop_padir |= CFG_PA7 ;       /* 1 = output */
+
+    /* Enable SDRAM - PA7 = 1 */
+    im->im_ioport.iop_padat |= CFG_PA7 ;       /* value of PA7 */
+
+    /*
+     * Preliminary prescaler for refresh (depends on number of
+     * banks): This value is selected for four cycles every 62.4 us
+     * with two SDRAM banks or four cycles every 31.2 us with one
+     * bank. It will be adjusted after memory sizing.
+     */
+    memctl->memc_mptpr = CFG_MPTPR_2BK_4K ;
+
+    memctl->memc_mbmr = CFG_MBMR_8COL;
+
+    upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+    /*
+     * Map controller banks 1 and 2 to the SDRAM banks 1 and 2 at
+     * preliminary addresses - these have to be modified after the
+     * SDRAM size has been determined.
+     */
+
+    memctl->memc_or1 = 0xF0000000 | CFG_OR_TIMING_SDRAM;
+    memctl->memc_br1 = ((SDRAM_BASE1_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V);
+
+    memctl->memc_or2 = 0xF0000000 | CFG_OR_TIMING_SDRAM;
+    memctl->memc_br2 = ((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V);
+
+    /* perform SDRAM initialization sequence */
+    memctl->memc_mar  = 0x00000088;
+
+    memctl->memc_mcr  = 0x80802105;    /* SDRAM bank 0 */
+
+    memctl->memc_mcr  = 0x80804105;    /* SDRAM bank 1 */
+
+    /* Execute refresh 8 times */
+    memctl->memc_mbmr = (CFG_MBMR_8COL & ~MAMR_TLFB_MSK) | MAMR_TLFB_8X ;
+
+    memctl->memc_mcr  = 0x80802130;    /* SDRAM bank 0 - execute twice */
+
+    memctl->memc_mcr  = 0x80804130;    /* SDRAM bank 1 - execute twice */
+
+    /* Execute refresh 4 times */
+    memctl->memc_mbmr = CFG_MBMR_8COL;
+
+    /*
+     * Check Bank 0 Memory Size for re-configuration
+     *
+     * try 8 column mode
+     */
+
+#if 0
+    PrintState();
+#endif
+/*    printf ("\nChecking bank1..."); */
+    size8 = dram_size (CFG_MBMR_8COL, (ulong *)SDRAM_BASE1_PRELIM, SDRAM_MAX_SIZE);
+
+    size_b0 = size8 ;
+
+/*    printf ("\nChecking bank2..."); */
+    size_b1 = dram_size (memctl->memc_mbmr, (ulong *)SDRAM_BASE2_PRELIM,SDRAM_MAX_SIZE);
+
+    /*
+     * Final mapping: map bigger bank first
+     */
+
+    memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+    memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V;
+
+    if (size_b1 > 0)
+    {
+        /*
+         * Position Bank 1 immediately above Bank 0
+         */
+        memctl->memc_or2 = ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+        memctl->memc_br2 = ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V) +
+                          (size_b0 & BR_BA_MSK);
+    }
+       else
+    {
+        /*
+         * No bank 1
+         *
+         * invalidate bank
+         */
+        memctl->memc_br2 = 0;
+       /* adjust refresh rate depending on SDRAM type, one bank */
+       memctl->memc_mptpr = CFG_MPTPR_1BK_4K;
+    }
+
+    /* If no memory detected, disable SDRAM */
+    if ((size_b0 + size_b1) == 0)
+    {
+       printf("disabling SDRAM!\n");
+       /* Disable SDRAM - PA7 = 1 */
+       im->im_ioport.iop_padat &= ~CFG_PA7 ;   /* value of PA7 */
+    }
+/*     else */
+/*    printf("done! (%08lx)\n", size_b0 + size_b1); */
+
+#if 0
+    PrintState();
+#endif
+    return (size_b0 + size_b1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mbmr_value, long int *base, long int maxsize)
+{
+    volatile long int   *addr;
+    long int             cnt, val;
+
+    /*memctl->memc_mbmr = mbmr_value; */
+
+    for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+       addr = base + cnt;      /* pointer arith! */
+
+       *addr = ~cnt;
+    }
+
+    /* write 0 to base address */
+    addr = base;
+    *addr = 0;
+
+    /* check at base address */
+    if ((val = *addr) != 0) {
+       printf("(0)");
+       return (0);
+    }
+
+    for (cnt = 1; ; cnt <<= 1) {
+       addr = base + cnt;      /* pointer arith! */
+
+       val = *addr;
+       if (val != (~cnt)) {
+/*         printf("(%08lx)", cnt*sizeof(long)); */
+           return (cnt * sizeof(long));
+       }
+    }
+    /* NOTREACHED */
+       return (0);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+
+#ifdef CFG_PCMCIA_MEM_ADDR
+volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
+#endif
+
+int pcmcia_init(void)
+{
+       volatile pcmconf8xx_t   *pcmp;
+       uint v, slota, slotb;
+
+       /*
+       ** Enable the PCMCIA for a Flash card.
+       */
+       pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+#if 0
+       pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR;
+       pcmp->pcmc_por0 = 0xc00ff05d;
+#endif
+
+       /* Set all slots to zero by default. */
+       pcmp->pcmc_pgcra = 0;
+       pcmp->pcmc_pgcrb = 0;
+#ifdef PCMCIA_SLOT_A
+       pcmp->pcmc_pgcra = 0x40;
+#endif
+#ifdef PCMCIA_SLOT_B
+       pcmp->pcmc_pgcrb = 0x40;
+#endif
+
+       /* Check if any PCMCIA card is luged in. */
+       slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ;
+       slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ;
+
+       if (!(slota || slotb))
+       {
+               printf("No card present\n");
+#ifdef PCMCIA_SLOT_A
+               pcmp->pcmc_pgcra = 0;
+#endif
+#ifdef PCMCIA_SLOT_B
+               pcmp->pcmc_pgcrb = 0;
+#endif
+               return -1;
+       }
+           else
+       printf("Unknown card (");
+
+       v = 0;
+
+       switch( (pcmp->pcmc_pipr >> 14) & 3 )
+       {
+               case 0x00 :
+                       printf("5V");
+                       v = 5;
+                       break;
+               case 0x01 :
+                       printf("5V and 3V");
+                       v = 3;
+                       break;
+               case 0x03 :
+                       printf("5V, 3V and x.xV");
+                       v = 3;
+                       break;
+       }
+
+       switch(v){
+       case 3:
+           printf("; using 3V");
+           /* Enable 3 volt Vcc. */
+
+           break;
+
+       default:
+               printf("; unknown voltage");
+               return -1;
+       }
+       printf(")\n");
+       /* disable pcmcia reset after a while */
+
+       udelay(20);
+
+       pcmp->pcmc_pgcrb = 0;
+
+       /* If you using a real hd you should give a short
+       * spin-up time. */
+#ifdef CONFIG_DISK_SPINUP_TIME
+       udelay(CONFIG_DISK_SPINUP_TIME);
+#endif
+
+       return 0;
+}
+#endif /* CFG_CMD_PCMCIA */
diff --git a/board/lart/config.mk b/board/lart/config.mk
new file mode 100644 (file)
index 0000000..8f1a62b
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# LART board with SA1100 cpu
+#
+# see http://www.lart.tudelft.nl/ for more information on LART
+#
+
+#
+# LART has 4 banks of 8 MB DRAM
+#
+# c000'0000
+# c100'0000
+# c800'0000
+# c900'0000
+#
+# Linux-Kernel is expected to be at c000'8000, entry c000'8000
+#
+# we load ourself to c170'0000, the upper 1 MB of second bank
+#
+# download areas is c800'0000
+#
+
+
+TEXT_BASE = 0xc1700000
diff --git a/board/lart/memsetup.S b/board/lart/memsetup.S
new file mode 100644 (file)
index 0000000..bebd697
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * 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
+ */
+
+
+
+#include <config.h>
+#include <version.h>
+
+
+/* some parameters for the board */
+
+MEM_BASE:      .long   0xa0000000
+MEM_START:     .long   0xc0000000
+
+#define        MDCNFG  0x00
+#define MDCAS0 0x04
+#define MDCAS1 0x08
+#define MDCAS2 0x0c
+#define MSC0   0x10
+#define MSC1   0x14
+#define MECR   0x18
+
+mdcas0:                .long   0xc71c703f
+mdcas1:                .long   0xffc71c71
+mdcas2:                .long   0xffffffff
+/* mdcnfg:             .long   0x0bb2bcbf */
+mdcnfg:                .long   0x0334b22f      @ alt
+/* mcs0:               .long   0xfff8fff8 */
+msc0:          .long   0xad8c4888      @ alt
+mecr:          .long   0x00060006
+/* mecr:               .long   0x994a994a      @ alt */
+
+/* setting up the memory */
+
+.globl memsetup
+memsetup:
+       ldr     r0, MEM_BASE
+
+       /* Setup the flash memory */
+       ldr     r1, msc0
+       str     r1, [r0, #MSC0]
+
+       /* Set up the DRAM */
+
+       /* MDCAS0 */
+       ldr     r1, mdcas0
+       str     r1, [r0, #MDCAS0]
+
+       /* MDCAS1 */
+       ldr     r1, mdcas1
+       str     r1, [r0, #MDCAS1]
+
+       /* MDCAS2 */
+       ldr     r1, mdcas2
+       str     r1, [r0, #MDCAS2]
+
+       /* MDCNFG */
+       ldr     r1, mdcnfg
+       str     r1, [r0, #MDCNFG]
+
+       /* Set up PCMCIA space */
+       ldr     r1, mecr
+       str     r1, [r0, #MECR]
+
+       /* Load something to activate bank */
+       ldr     r1, MEM_START
+
+.rept  8
+       ldr     r0, [r1]
+.endr
+
+       /* everything is fine now */
+       mov     pc, lr
+
diff --git a/board/lubbock/memsetup.S b/board/lubbock/memsetup.S
new file mode 100644 (file)
index 0000000..c027834
--- /dev/null
@@ -0,0 +1,749 @@
+/*
+ * Most of this taken from Redboot hal_platform_setup.h with cleanup
+ *
+ * NOTE: I haven't clean this up considerably, just enough to get it
+ * running. See hal_platform_setup.h for the source. See
+ * board/cradle/memsetup.S for another PXA250 setup that is
+ * much cleaner.
+ *
+ * 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
+ */
+
+#include <config.h>
+#include <version.h>
+#include <asm/arch/pxa-regs.h>
+
+DRAM_SIZE:  .long   CFG_DRAM_SIZE
+
+/* wait for coprocessor write complete */
+   .macro CPWAIT reg
+   mrc  p15,0,\reg,c2,c0,0
+   mov  \reg,\reg
+   sub  pc,pc,#4
+   .endm
+
+
+.globl memsetup
+memsetup:
+
+    mov      r10, lr
+
+    /* Set up GPIO pins first */
+
+       ldr             r0,     =GPSR0
+       ldr             r1,     =CFG_GPSR0_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPSR1
+       ldr             r1,     =CFG_GPSR1_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPSR2
+       ldr             r1,     =CFG_GPSR2_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPCR0
+       ldr             r1,     =CFG_GPCR0_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPCR1
+       ldr             r1,     =CFG_GPCR1_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPCR2
+       ldr             r1,     =CFG_GPCR2_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPDR0
+       ldr             r1,     =CFG_GPDR0_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPDR1
+       ldr             r1,     =CFG_GPDR1_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GPDR2
+       ldr             r1,     =CFG_GPDR2_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GAFR0_L
+       ldr             r1,     =CFG_GAFR0_L_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GAFR0_U
+       ldr             r1,     =CFG_GAFR0_U_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GAFR1_L
+       ldr             r1,     =CFG_GAFR1_L_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GAFR1_U
+       ldr             r1,     =CFG_GAFR1_U_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GAFR2_L
+       ldr             r1,     =CFG_GAFR2_L_VAL
+       str             r1,   [r0]
+
+       ldr             r0,     =GAFR2_U
+       ldr             r1,     =CFG_GAFR2_U_VAL
+       str             r1,   [r0]
+
+   /* enable GPIO pins */
+       ldr             r0,     =PSSR
+       ldr             r1,     =CFG_PSSR_VAL
+       str             r1,   [r0]
+
+   ldr    r3, =MSC1                            /* low - bank 2 Lubbock Registers / SRAM */
+   ldr    r2, =CFG_MSC1_VAL                    /* high - bank 3 Ethernet Controller */
+   str    r2, [r3]                             /* need to set MSC1 before trying to write to the HEX LEDs */
+   ldr    r2, [r3]                             /* need to read it back to make sure the value latches (see MSC section of manual) */
+
+   ldr    r1, =LED_BLANK
+   mov    r0, #0xFF
+   str    r0, [r1]             /* turn on hex leds */
+
+loop:
+   ldr         r0, =0xB0070001
+   ldr         r1, =_LED
+   str         r0, [r1]                                                        /* hex display */
+
+/*********************************************************************
+    Initlialize Memory Controller
+        The sequence below is based on the recommended init steps detailed
+        in the EAS, chapter 5 (Chapter 10, Operating Systems Developers Guide)
+
+
+    pause for 200 uSecs- allow internal clocks to settle
+        *Note: only need this if hard reset... doing it anyway for now
+*/
+
+       @ ---- Wait 200 usec
+       ldr r3, =OSCR       @ reset the OS Timer Count to zero
+       mov r2, #0
+       str r2, [r3]
+       ldr r4, =0x300                  @ really 0x2E1 is about 200usec, so 0x300 should be plenty
+1:
+       ldr r2, [r3]
+       cmp r4, r2
+       bgt 1b
+
+mem_init:
+        @ get memory controller base address
+        ldr     r1,  =MEMC_BASE
+
+@****************************************************************************
+@  Step 1
+@
+
+        @ write msc0, read back to ensure data latches
+        @
+        ldr     r2,   =CFG_MSC0_VAL
+        str     r2,   [r1, #MSC0_OFFSET]
+        ldr     r2,   [r1, #MSC0_OFFSET]
+
+        @ write msc1
+        ldr     r2,  =CFG_MSC1_VAL
+        str     r2,  [r1, #MSC1_OFFSET]
+        ldr     r2,  [r1, #MSC1_OFFSET]
+
+        @ write msc2
+        ldr     r2,  =CFG_MSC2_VAL
+        str     r2,  [r1, #MSC2_OFFSET]
+        ldr     r2,  [r1, #MSC2_OFFSET]
+
+        @ write mecr
+        ldr     r2,  =CFG_MECR_VAL
+        str     r2,  [r1, #MECR_OFFSET]
+
+        @ write mcmem0
+        ldr     r2,  =CFG_MCMEM0_VAL
+        str     r2,  [r1, #MCMEM0_OFFSET]
+
+        @ write mcmem1
+        ldr     r2,  =CFG_MCMEM1_VAL
+        str     r2,  [r1, #MCMEM1_OFFSET]
+
+        @ write mcatt0
+        ldr     r2,  =CFG_MCATT0_VAL
+        str     r2,  [r1, #MCATT0_OFFSET]
+
+        @ write mcatt1
+        ldr     r2,  =CFG_MCATT1_VAL
+        str     r2,  [r1, #MCATT1_OFFSET]
+
+        @ write mcio0
+        ldr     r2,  =CFG_MCIO0_VAL
+        str     r2,  [r1, #MCIO0_OFFSET]
+
+        @ write mcio1
+        ldr     r2,  =CFG_MCIO1_VAL
+        str     r2,  [r1, #MCIO1_OFFSET]
+
+        @-------------------------------------------------------
+        @ 3rd bullet, Step 1
+        @
+
+        @ get the mdrefr settings
+        ldr     r3,  =CFG_MDREFR_VAL_100
+
+        @ extract DRI field (we need a valid DRI field)
+        @
+        ldr     r2,  =0xFFF
+
+        @ valid DRI field in r3
+        @
+        and     r3,  r3,  r2
+
+        @ get the reset state of MDREFR
+        @
+        ldr     r4,  [r1, #MDREFR_OFFSET]
+
+        @ clear the DRI field
+        @
+        bic     r4,  r4,  r2
+
+        @ insert the valid DRI field loaded above
+        @
+        orr     r4,  r4,  r3
+
+        @ write back mdrefr
+        @
+        str     r4,  [r1, #MDREFR_OFFSET]
+
+        @ *Note: preserve the mdrefr value in r4 *
+
+@****************************************************************************
+@  Step 2
+@
+        /* This should be for SRAM, why is it commented out??? */
+
+        @ fetch sxcnfg value
+        @
+        @ldr     r2,  =0
+        @ write back sxcnfg
+        @str     r2,  [r1, #SXCNFG_OFFSET]
+
+/*        @if sxcnfg=0, don't program for synch-static memory */
+        @cmp     r2,  #0
+        @beq     1f
+
+        @program sxmrs
+        @ldr     r2,  =SXMRS_SETTINGS
+        @str     r2,  [r1, #SXMRS_OFFSET]
+
+
+@****************************************************************************
+@  Step 3
+@
+
+        @ Assumes previous mdrefr value in r4, if not then read current mdrefr
+
+        @ clear the free-running clock bits
+        @ (clear K0Free, K1Free, K2Free
+        @
+        bic     r4,  r4,  #(0x00800000 | 0x01000000 | 0x02000000)
+
+        @ set K1RUN if bank 0 installed
+        @
+        orr   r4,  r4,  #0x00010000
+
+
+
+#ifdef THIS
+@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+@<!<!<!<!<!<!<!<!<!<!<!  Begin INSERT 1    <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+        @ Lubbock: Allow the user to select the {T/R/M} with predetermined
+        @   SDCLK.  Based on Table 3-1 in PXA250 and PXA210 Dev Man.
+        @
+        @  * = Must set MDREFR.K1DB2 to halve the MemClk for desired SDCLK[1]
+        @
+        @   S25, S26 used to provide all 400 MHz BIN values for Cotulla (0,0 - 1,3)
+        @   S25, S26 used to provide all 200 MHz BIN values for Sabinal
+        @
+        @   S23: Force the halving of MemClk when deriving SDCLK[1]
+        @        DOT: no override  !DOT: halve (if not already forced half)
+/*        @        *For certain MemClks, SDCLK's derivation is forced to be halved */
+        @
+        @   S24: Run/Turbo.
+        @        DOT: Run mode   !DOT: Turbo mode
+        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+        @
+        @ Allow the user to control K1DB2 where applicable
+        @
+        @ Get the value of S23:          @ 1 = DOT (unity), 0 = !DOT (halve it)
+        @
+        @ DOT:   set K1DB2     (SDCLD = MemClk)
+        @ !DOT:  clear K1DB2   (SDCLK = MemClk/2)
+        @
+        @ldr r2, =FPGA_REGS_BASE_PHYSICAL
+
+        bl GET_S23                          @ r3, r2                    @ get the value of S23 in R0, i put the base adx of fpga in r3
+
+        cmp      r3, #0x0                 @ is !DOT?
+        orreq    r4, r4,  #0x00020000     @ SDClk[1] = MemClk/2
+        bicne    r4, r4,  #0x00020000     @ SDClk[1] = MemClk
+
+        @
+        @ Next, we need to look for S25,S26 selections that necessitate the
+        @  halving of MemClk to derive SDCLK[1]: (S25,S26)={03-0C, 10-13}
+        @ Override above S23-based selection accordingly.
+        @
+        ldr r2, =FPGA_REGS_BASE_PHYSICAL
+        bl  GET_S25                           @ r0, r2
+                                       @ get the value of S25 in R0, i put the base adx of fpga in r2
+
+
+
+        ldr r2, =FPGA_REGS_BASE_PHYSICAL
+        BL  GET_S26                              @ r3, r2
+                                      @ get the value of S26 in R1, i put the base adx of fpga in r2
+
+        orr     r0, r0, r3               @ concatenate S25 & S26 vals
+        and     r0, r0, #0xFF
+
+        @ Set K1DB2 for the frequencies that require it
+        @
+        cmp     r0, #0x03
+        cmpne   r0, #0x04
+        cmpne   r0, #0x05
+        cmpne   r0, #0x06
+        cmpne   r0, #0x07
+        cmpne   r0, #0x08
+        cmpne   r0, #0x09
+        cmpne   r0, #0x0A
+        cmpne   r0, #0x0B
+        cmpne   r0, #0x0C
+        cmpne   r0, #0x10
+        cmpne   r0, #0x11
+        cmpne   r0, #0x12
+        cmpne   r0, #0x13
+        orreq   r4, r4,  #0x00020000     @ SDCLK[1] = (MemClk)/2 for 03 - 0C @ 10 - 13
+
+        @
+        @ *Must make MSC0&1 adjustments now for MEMClks > 100MHz.
+        @
+        @ Adjust MSC0 for MemClks > 100 MHz
+        @
+        ldreq   r0,   [r1, #MSC0_OFFSET]
+        ldreq   r3,   =0x7F007F00
+        biceq   r0,   r0, r3                @ clear MSC0[14:12, 11:8] (RRR, RDN)
+        ldreq   r3,   =0x46004600
+        orreq   r0,   r0, r3                @ set   MSC0[14, 10:9]  (doubling RRR, RDN)
+        streq   r0,   [r1, #MSC0_OFFSET]
+        ldreq   r0,   [r1, #MSC0_OFFSET]    @ read it back to ensure that the data latches
+
+        @
+        @ Adjust MSC1.LH for MemClks > 100 MHz
+        @
+        ldreq   r0,   [r1, #MSC1_OFFSET]
+        ldreq   r3,   =0x7FF0
+        biceq   r0,   r0, r3               @ clear MSC1[14:12, 11:8, 7:4] (RRR, RDN, RDF)
+        ldreq   r3,   =0x4880
+        orreq   r0,   r0, r3               @ set   MSC1[14, 11, 7]  (doubling RRR, RDN, RDF)
+        streq   r0,   [r1, #MSC1_OFFSET]
+        ldreq   r0,   [r1, #MSC1_OFFSET]   @ read it back to ensure that the data latches
+
+        @                                                                   @
+        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#endif
+
+@<!<!<!<!<!<!<!<!<!<!<!    End INSERT 1    <!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+@<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<!<
+
+
+        @ write back mdrefr
+        @
+        str     r4,  [r1, #MDREFR_OFFSET]
+        ldr     r4,  [r1, #MDREFR_OFFSET]
+
+        @ deassert SLFRSH
+        @
+        bic     r4,  r4,  #0x00400000
+
+        @ write back mdrefr
+        @
+        str     r4,  [r1, #MDREFR_OFFSET]
+
+        @ assert E1PIN
+        @
+        orr     r4,  r4,  #0x00008000
+
+        @ write back mdrefr
+        @
+        str     r4,  [r1, #MDREFR_OFFSET]
+        ldr     r4,  [r1, #MDREFR_OFFSET]
+        nop
+        nop
+
+
+@****************************************************************************
+@  Step 4
+@
+
+        @ fetch platform value of mdcnfg
+        @
+        ldr     r2,  =CFG_MDCNFG_VAL
+
+        @ disable all sdram banks
+        @
+        bic     r2,  r2,  #(MDCNFG_DE0 | MDCNFG_DE1)
+        bic     r2,  r2,  #(MDCNFG_DE2 | MDCNFG_DE3)
+
+        @ program banks 0/1 for bus width
+        @
+        bic   r2,  r2,  #MDCNFG_DWID0      @0=32-bit
+
+
+        @ write initial value of mdcnfg, w/o enabling sdram banks
+        @
+        str     r2,  [r1, #MDCNFG_OFFSET]
+
+@ ****************************************************************************
+@  Step 5
+@
+
+        @ pause for 200 uSecs
+        @
+       ldr r3, =OSCR   @reset the OS Timer Count to zero
+       mov r2, #0
+           str r2, [r3]
+           ldr r4, =0x300                      @really 0x2E1 is about 200usec, so 0x300 should be plenty
+1:
+           ldr r2, [r3]
+           cmp r4, r2
+           bgt 1b
+
+
+@****************************************************************************
+@  Step 6
+@
+
+           mov    r0, #0x78                                @turn everything off
+      mcr    p15, 0, r0, c1, c0, 0             @(caches off, MMU off, etc.)
+
+
+@ ****************************************************************************
+@  Step 7
+@
+        @ Access memory *not yet enabled* for CBR refresh cycles (8)
+        @ - CBR is generated for all banks
+
+           ldr     r2, =CFG_DRAM_BASE
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+
+
+@ ****************************************************************************
+@  Step 8: NOP (enable dcache if you wanna... we dont)
+@
+
+
+@ ****************************************************************************
+@  Step 9
+@
+
+
+        @get memory controller base address
+        @
+        ldr     r1,  =MEMC_BASE
+
+        @fetch current mdcnfg value
+        @
+        ldr     r3,  [r1, #MDCNFG_OFFSET]
+
+        @enable sdram bank 0 if installed (must do for any populated bank)
+        @
+        orr     r3,  r3,  #MDCNFG_DE0
+
+        @write back mdcnfg, enabling the sdram bank(s)
+        @
+        str     r3,  [r1, #MDCNFG_OFFSET]
+
+
+@****************************************************************************
+@  Step 10
+@
+
+        @ write mdmrs
+        @
+        ldr     r2,  =CFG_MDMRS_VAL
+        str     r2,  [r1, #MDMRS_OFFSET]
+
+
+@****************************************************************************
+@  Step 11: Final Step
+@
+
+@INITINTC
+        @********************************************************************
+        @ Disable (mask) all interrupts at the interrupt controller
+        @
+
+        @ clear the interrupt level register (use IRQ, not FIQ)
+        @
+        mov     r1, #0
+        ldr     r2,  =ICLR
+        str     r1,  [r2]
+
+        @ mask all interrupts at the controller
+        @
+        ldr     r2,  =ICMR
+        str     r1,  [r2]
+
+
+@INITCLKS
+        @ ********************************************************************
+        @ Disable the peripheral clocks, and set the core clock
+        @ frequency (hard-coding at 398.12MHz for now).
+        @
+
+               @ Turn Off ALL on-chip peripheral clocks for re-configuration
+               @ *Note: See label 'ENABLECLKS' for the re-enabling
+               @
+        ldr     r1,  =CKEN
+        mov     r2,  #0
+        str     r2,  [r1]
+
+
+        @ default value in case no valid rotary switch setting is found
+        ldr     r2, =(CCCR_L27 | CCCR_M2 | CCCR_N10)        @ DEFAULT: {200/200/100}
+
+
+        @... and write the core clock config register
+        @
+        ldr     r1,  =CCCR
+        str     r2,  [r1]
+
+/*        @ enable the 32Khz oscillator for RTC and PowerManager
+        @
+        ldr     r1,  =OSCC
+        mov     r2,  #OSCC_OON
+        str     r2,  [r1]
+
+
+        @ NOTE:  spin here until OSCC.OOK get set,
+        @        meaning the PLL has settled.
+        @
+60:
+        ldr     r2, [r1]
+        ands    r2, r2, #1
+        beq     60b
+*/
+
+@OSCC_OON_DONE
+
+
+#ifdef  A0_COTULLA
+    @****************************************************************************
+    @ !!! Take care of A0 Errata Sighting #4 --
+    @ after a frequency change, the memory controller must be restarted
+    @
+
+        @ get memory controller base address
+        ldr     r1,  =MEMC_BASE
+
+        @ get the current state of MDREFR
+        @
+        ldr     r2,  [r1, #MDREFR_OFFSET]
+
+        @ clear E0PIN, E1PIN
+        @
+        bic     r3,  r2,  #(MDREFR_E0PIN | MDREFR_E1PIN)
+
+        @ write MDREFR with E0PIN, E1PIN cleared (disable sdclk[0,1])
+        @
+        str     r3,  [r1, #MDREFR_OFFSET]
+
+        @ then write MDREFR with E0PIN, E1PIN set (enable sdclk[0,1])
+        @
+        str     r2,  [r1, #MDREFR_OFFSET]
+
+        @ get the current state of MDCNFG
+        @
+        ldr     r3,  [r1, #MDCNFG_OFFSET]
+
+        @ disable all SDRAM banks
+        @
+        bic     r3,  r3,  #(MDCNFG_DE0 | MDCNFG_DE1)
+        bic     r3,  r3,  #(MDCNFG_DE2 |  MDCNFG_DE3)
+
+        @ write back MDCNFG
+        @
+        ldr     r3,  [r1, #MDCNFG_OFFSET]
+
+           @ Access memory not yet enabled for CBR refresh cycles (8)
+        @ - CBR is generated for *all* banks
+           ldr     r2, =CFG_DRAM_BASE
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+           str     r2, [r2]
+
+        @ fetch current mdcnfg value
+        @
+        ldr     r3,  [r1, #MDCNFG_OFFSET]
+
+        @ enable sdram bank 0 if installed
+        @
+        orr     r3,  r3,  #MDCNFG_DE0
+
+        @ write back mdcnfg, enabling the sdram bank(s)
+        @
+        str     r3,  [r1, #MDCNFG_OFFSET]
+
+        @ write mdmrs
+        @
+        ldr     r2,  =CFG_MDMRS_VAL
+        str     r2,  [r1, #MDMRS_OFFSET]
+
+
+
+    /*    @ errata: don't enable auto power-down */
+        @ get current value of mdrefr
+        @ldr     r3,  [r1, #MDREFR_OFFSET]
+        @ enable auto-power down
+        @orr     r3,  r3,  #MDREFR_APD
+        @write back mdrefr
+        @str     r3,  [r1, #MDREFR_OFFSET]
+
+#endif A0_Cotulla
+
+
+  ldr     r0, =0x000C0dE3
+  ldr          r1, =_LED
+  str          r0, [r1]                /* hex display */
+
+@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
+@ ^%^%^%^%^%^%^%^%^%   above could be replaced by prememLLI ^%^%^%^%^%^%^%^%^%
+@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
+
+
+       /* Save SDRAM size */
+    ldr     r1, =DRAM_SIZE
+        str       r8, [r1]
+
+    ldr     r0, =0xC0DE0006
+    ldr        r1, =_LED
+    str        r0, [r1]                /* hex display */
+
+       /* Interrupt init */
+       /* Mask all interrupts */
+    ldr        r0, =ICMR /* enable no sources */
+       mov r1, #0
+    str r1, [r0]
+
+#define NODEBUG
+#ifdef NODEBUG
+       /*Disable software and data breakpoints */
+       mov     r0,#0
+       mcr     p15,0,r0,c14,c8,0  /* ibcr0 */
+       mcr     p15,0,r0,c14,c9,0  /* ibcr1 */
+       mcr     p15,0,r0,c14,c4,0  /* dbcon */
+
+       /*Enable all debug functionality */
+       mov     r0,#0x80000000
+       mcr     p14,0,r0,c10,c0,0  /* dcsr */
+
+#endif
+
+       ldr     r0, =0xBEEF001D
+    ldr        r1, =_LED
+    str        r0, [r1]                /* hex display */
+
+       mov     pc, r10
+
+@ End memsetup
+
+@ %%%%%%%%%%%   Useful subroutines
+GET_S23:
+    @ This macro will read S23 and return its value in r3
+    @ r2 contains the base address of the Lubbock user registers
+    ldr r2, =FPGA_REGS_BASE_PHYSICAL
+
+    /*@ read S23's value */
+    ldr     r3, [r2, #USER_SWITCHES_OFFSET]
+
+    @ mask out irrelevant bits
+    and     r3, r3, #0x200
+
+    @ get bit into position 0
+    mov     r3, r3, LSR #9
+
+    mov     pc, lr
+@ End GET_S23
+
+
+GET_S24:
+    @ This macro will read S24 and return its value in r0
+    @ r2 contains the base address of the Lubbock user registers
+    ldr r2, =FPGA_REGS_BASE_PHYSICAL
+
+    /*@ read S24's value */
+    ldr     r0, [r2, #USER_SWITCHES_OFFSET]
+
+    @ mask out irrelevant bits
+    and     r0, r0, #0x100
+
+    @ get bit into position 0
+    mov     r0, r0, LSR #8
+
+    mov     pc, lr
+@ End GET_S23
+
+
+GET_S25:
+    @ This macro will read rotary S25 and return its value in r0
+    @ r2 contains the base address of the Lubbock user registers
+    @ read the user switches register
+    ldr     r0, [r2, #USER_SWITCHES_OFFSET]
+
+    @ mask out irrelevant bits
+    and     r0, r0, #0xF0
+
+    mov     pc, lr
+@ End subroutine
+
+
+GET_S26:
+    @ This macro will read rotary S26 and return its value in r3
+    @ r2 contains the base address of the Lubbock user registers
+    @ read the user switches register
+    ldr     r3, [r2, #USER_SWITCHES_OFFSET]
+
+    @ mask out irrelevant bits
+    and     r3, r3, #0x0F
+
+    mov     pc, lr
+@ End subroutine GET_S26
+
+
diff --git a/board/mbx8xx/config.mk b/board/mbx8xx/config.mk
new file mode 100644 (file)
index 0000000..d5e8ed2
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# (C) Copyright 2000
+# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+# Marius Groeger <mgroeger@sysgo.de>
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.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
+#
+
+#
+# MBX8xx boards
+#
+
+TEXT_BASE = 0xfe000000
+/*TEXT_BASE  = 0x00200000 */
diff --git a/board/ml2/flash.c b/board/ml2/flash.c
new file mode 100644 (file)
index 0000000..77e0931
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * flash.c: Support code for the flash chips on the Xilinx ML2 board
+ *
+ * Copyright 2002 Mind NV
+ *
+ * http://www.mind.be/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire program
+ * is licensed under the GPL.
+ *
+ */
+
+#include <common.h>
+#include <asm/u-boot.h>
+#include <configs/ML2.h>
+
+#define FLASH_BANK_SIZE (64*1024*1024)
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+#define SECT_SIZE              (512*1024)
+
+#define CMD_READ_ARRAY 0x00FF00FF00FF00FULL
+#define CMD_IDENTIFY        0x0090009000900090ULL
+#define CMD_ERASE_SETUP     0x0020002000200020ULL
+#define CMD_ERASE_CONFIRM   0x00D000D000D000D0ULL
+#define CMD_PROGRAM     0x0040004000400040ULL
+#define CMD_RESUME      0x00D000D000D000D0ULL
+#define CMD_SUSPEND     0x00B000B000B000B0ULL
+#define CMD_STATUS_READ     0x0070007000700070ULL
+#define CMD_STATUS_RESET    0x0050005000500050ULL
+
+#define BIT_BUSY        0x0080008000800080ULL
+#define BIT_ERASE_SUSPEND   0x004000400400040ULL
+#define BIT_ERASE_ERROR     0x0020002000200020ULL
+#define BIT_PROGRAM_ERROR   0x0010001000100010ULL
+#define BIT_VPP_RANGE_ERROR 0x0008000800080008ULL
+#define BIT_PROGRAM_SUSPEND 0x0004000400040004ULL
+#define BIT_PROTECT_ERROR   0x0002000200020002ULL
+#define BIT_UNDEFINED       0x0001000100010001ULL
+
+#define BIT_SEQUENCE_ERROR  0x0030003000300030ULL
+
+#define BIT_TIMEOUT     0x80000000
+
+
+inline void eieio(void) {
+
+       __asm__ __volatile__ ("eieio" : : : "memory");
+
+}
+
+ulong flash_init(void) {
+
+       int i, j;
+       ulong size = 0;
+
+       for(i=0;i<CFG_MAX_FLASH_BANKS;i++) {
+               ulong flashbase = 0;
+
+               flash_info[i].flash_id = (INTEL_MANUFACT & FLASH_VENDMASK) |
+                                                                (INTEL_ID_28F128J3A & FLASH_TYPEMASK);
+               flash_info[i].size = FLASH_BANK_SIZE;
+               flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+               memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+               if (i==0)
+                       flashbase = CFG_FLASH_BASE;
+               else
+                       panic("configured to many flash banks!\n");
+               for (j = 0; j < flash_info[i].sector_count; j++)
+                               flash_info[i].start[j]=flashbase + j * SECT_SIZE;
+
+               size += flash_info[i].size;
+       }
+
+       return size;
+}
+
+void flash_print_info  (flash_info_t *info) {
+
+       int i;
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+               case (INTEL_MANUFACT & FLASH_VENDMASK):
+                       printf("Intel: ");
+                       break;
+               default:
+                       printf("Unknown Vendor ");
+                       break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+               case (INTEL_ID_28F128J3A & FLASH_TYPEMASK):
+                       printf("4x 28F128J3A (128Mbit)\n");
+                       break;
+               default:
+                       printf("Unknown Chip Type\n");
+                       break;
+       }
+
+       printf("  Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
+       printf("  Sector Start Addresses:");
+       for (i = 0; i < info->sector_count; i++) {
+               if ((i % 5) == 0)
+                       printf("\n   ");
+               printf (" %08lX%s", info->start[i],
+                                info->protect[i] ? " (RO)" : "     ");
+       }
+       printf ("\n");
+}
+
+int flash_error (unsigned long long code) {
+
+       if (code & BIT_TIMEOUT) {
+               printf ("Timeout\n");
+               return ERR_TIMOUT;
+       }
+
+       if (~code & BIT_BUSY) {
+               printf ("Busy\n");
+               return ERR_PROG_ERROR;
+       }
+
+       if (code & BIT_VPP_RANGE_ERROR) {
+               printf ("Vpp range error\n");
+               return ERR_PROG_ERROR;
+       }
+
+       if (code & BIT_PROTECT_ERROR) {
+               printf ("Device protect error\n");
+               return ERR_PROG_ERROR;
+       }
+
+       if (code & BIT_SEQUENCE_ERROR) {
+               printf ("Command seqence error\n");
+               return ERR_PROG_ERROR;
+       }
+
+       if (code & BIT_ERASE_ERROR) {
+               printf ("Block erase error\n");
+               return ERR_PROG_ERROR;
+       }
+
+       if (code & BIT_PROGRAM_ERROR) {
+               printf ("Program error\n");
+               return ERR_PROG_ERROR;
+       }
+
+       if (code & BIT_ERASE_SUSPEND) {
+               printf ("Block erase suspended\n");
+               return ERR_PROG_ERROR;
+       }
+
+       if (code & BIT_PROGRAM_SUSPEND) {
+               printf ("Program suspended\n");
+               return ERR_PROG_ERROR;
+       }
+
+       return ERR_OK;
+
+}
+
+int flash_erase (flash_info_t *info, int s_first, int s_last) {
+
+       int rc = ERR_OK;
+       int sect;
+       unsigned long long result;
+
+       if (info->flash_id == FLASH_UNKNOWN)
+               return ERR_UNKNOWN_FLASH_TYPE;
+
+       if ((s_first < 0) || (s_first > s_last))
+               return ERR_INVAL;
+
+       if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK))
+               return ERR_UNKNOWN_FLASH_VENDOR;
+
+       for (sect=s_first; sect<=s_last; ++sect)
+               if (info->protect[sect])
+                       return ERR_PROTECTED;
+
+       for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
+               volatile unsigned long long *addr=
+                                                                       (unsigned long long *)(info->start[sect]);
+
+               printf("Erasing sector %2d ... ", sect);
+
+               *addr=CMD_STATUS_RESET;
+               eieio();
+               *addr=CMD_ERASE_SETUP;
+               eieio();
+               *addr=CMD_ERASE_CONFIRM;
+               eieio();
+
+               do {
+                       result = *addr;
+               } while(~result & BIT_BUSY);
+
+               *addr=CMD_READ_ARRAY;
+
+               if ((rc = flash_error(result)) == ERR_OK)
+                       printf("ok.\n");
+               else
+                       break;
+       }
+
+       if (ctrlc())
+               printf("User Interrupt!\n");
+
+       return rc;
+}
+
+volatile static int write_word (flash_info_t *info, ulong dest, unsigned long long data) {
+
+       volatile unsigned long long *addr=(unsigned long long *)dest;
+       unsigned long long result;
+       int rc = ERR_OK;
+
+       result=*addr;
+       if ((result & data) != data)
+               return ERR_NOT_ERASED;
+
+       *addr=CMD_STATUS_RESET;
+       eieio();
+       *addr=CMD_PROGRAM;
+       eieio();
+       *addr=data;
+       eieio();
+
+       do {
+               result=*addr;
+       } while(~result & BIT_BUSY);
+
+       *addr=CMD_READ_ARRAY;
+
+       rc = flash_error(result);
+
+       return rc;
+
+}
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) {
+
+       ulong cp, wp;
+       unsigned long long data;
+       int l;
+       int i,rc;
+
+       wp=(addr & ~7);
+
+       if((l=addr-wp) != 0) {
+               data=0;
+               for(i=0,cp=wp;i<l;++i,++cp)
+                       data = (data >> 8) | (*(uchar *)cp << 24);
+
+               for (; i<8 && cnt>0; ++i) {
+                       data = (data >> 8) | (*src++ << 24);
+                       --cnt;
+                       ++cp;
+               }
+
+               for (; i<8; ++i, ++cp)
+                       data = (data >> 8) | (*(uchar *)cp << 24);
+
+               if ((rc = write_word(info, wp, data)) != 0)
+                       return rc;
+
+               wp+=8;
+       }
+
+       while(cnt>=8) {
+               data=*((unsigned long long *)src);
+               if ((rc = write_word(info, wp, data)) != 0)
+                       return rc;
+               src+=8;
+               wp+=8;
+               cnt-=8;
+       }
+
+       if(cnt == 0)
+               return ERR_OK;
+
+       data = 0;
+       for (i=0, cp=wp; i<8 && cnt>0; ++i, ++cp) {
+               data = (data >> 8) | (*src++ << 24);
+               --cnt;
+       }
+       for (; i<8; ++i, ++cp) {
+               data = (data >> 8) | (*(uchar *)cp << 24);
+       }
+
+       return write_word(info, wp, data);
+
+}
+
diff --git a/board/ml2/init.S b/board/ml2/init.S
new file mode 100644 (file)
index 0000000..2386c2a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * init.S: Stubs for U-Boot initialization
+ *
+ * Copyright 2002 Mind NV
+ *
+ * http://www.mind.be/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#include <ppc4xx.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+
+       .globl  ext_bus_cntlr_init
+ext_bus_cntlr_init:
+        blr
+
+        .globl  sdram_init
+sdram_init:
+        blr
diff --git a/board/ml2/ml2.c b/board/ml2/ml2.c
new file mode 100644 (file)
index 0000000..a89a8f9
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * ml2.c: U-Boot platform support for Xilinx ML2 board
+ *
+ * Copyright 2002 Mind NV
+ *
+ * http://www.mind.be/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *
+ * Derived from : Other platform support files in this tree
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+
+
+int board_pre_init (void)
+{
+       return 0;
+}
+
+
+int checkboard (void)
+{
+       unsigned char *s = getenv ("serial#");
+       unsigned char *e;
+
+       if (!s || strncmp (s, "ML2", 9)) {
+               printf ("### No HW ID - assuming ML2");
+       } else {
+               for (e = s; *e; ++e) {
+                       if (*e == ' ')
+                               break;
+           &nb