Patch by Reinhard Meyer, 28 Dec 2003:
authorwdenk <wdenk>
Sun, 28 Dec 2003 11:44:59 +0000 (11:44 +0000)
committerwdenk <wdenk>
Sun, 28 Dec 2003 11:44:59 +0000 (11:44 +0000)
Add initial support for TOP5200 board

CHANGELOG
board/emk/top5200/Makefile [new file with mode: 0644]
board/emk/top5200/config.mk [new file with mode: 0644]
board/emk/top5200/flash.c [new file with mode: 0644]
board/emk/top5200/top5200.c [new file with mode: 0644]
board/emk/top5200/u-boot.lds [new file with mode: 0644]
include/configs/TOP5200.h [new file with mode: 0644]

index 84e3092e6f18dd9603df0f5c15c5aea366b6b2c2..4c0bd2b429ff7ba3c921ee1dccff0d7e60a8b6af 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,9 @@
 Changes since U-Boot 1.0.0:
 ======================================================================
 
+* Patch by Reinhard Meyer, 28 Dec 2003:
+  Add initial support for TOP5200 board
+
 * Make CPU clock on ICA-IP board controllable by a "cpuclk"
   environment variable which can set to "100", "133", or "150". The
   CPU clock will be configured accordingly upon next reboot. Other
diff --git a/board/emk/top5200/Makefile b/board/emk/top5200/Makefile
new file mode 100644 (file)
index 0000000..eb5ed59
--- /dev/null
@@ -0,0 +1,47 @@
+
+#
+# (C) Copyright 2003
+# 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 $(TOPDIR)/config.mk
+
+LIB    = lib$(BOARD).a
+
+OBJS   := $(BOARD).o flash.o
+
+$(LIB):        $(OBJS) $(SOBJS)
+       $(AR) crv $@ $(OBJS)
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
diff --git a/board/emk/top5200/config.mk b/board/emk/top5200/config.mk
new file mode 100644 (file)
index 0000000..14af97a
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2003
+# 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
+#
+
+#
+# TOP5200 board, on optional MINI5200 and EVAL5200 boards
+#
+
+TEXT_BASE = 0xfff00000
+#TEXT_BASE = 0x00100000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/emk/top5200/flash.c b/board/emk/top5200/flash.c
new file mode 100644 (file)
index 0000000..b951b5f
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * (C) Copyright 2003
+ * 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>
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+typedef unsigned char FLASH_PORT_WIDTH;
+typedef volatile unsigned char FLASH_PORT_WIDTHV;
+#define        FLASH_ID_MASK   0xFF
+
+#define FPW    FLASH_PORT_WIDTH
+#define FPWV   FLASH_PORT_WIDTHV
+
+#define FLASH_CYCLE1   0x0aaa
+#define FLASH_CYCLE2   0x0555
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size(FPWV *addr, flash_info_t *info);
+static void flash_reset(flash_info_t *info);
+static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
+static flash_info_t *flash_get_info(ulong base);
+
+/*-----------------------------------------------------------------------
+ * flash_init()
+ *
+ * sets up flash_info and returns size of FLASH (bytes)
+ */
+unsigned long flash_init (void)
+{
+       unsigned long size = 0;
+       int i;
+       extern void flash_preinit(void);
+       extern void flash_afterinit(uint, ulong, ulong);
+       ulong flashbase = CFG_FLASH_BASE;
+
+       flash_preinit();
+
+       /* There is only ONE FLASH device */
+       memset(&flash_info[0], 0, sizeof(flash_info_t));
+       flash_info[0].size =
+                       flash_get_size((FPW *)flashbase, &flash_info[0]);
+       size += flash_info[0].size;
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+       /* monitor protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_MONITOR_BASE,
+                     CFG_MONITOR_BASE+monitor_flash_len-1,
+                     flash_get_info(CFG_MONITOR_BASE));
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+       /* ENV protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_ENV_ADDR,
+                     CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+                     flash_get_info(CFG_ENV_ADDR));
+#endif
+
+
+       flash_afterinit(0, flash_info[0].start[0], flash_info[0].size);
+       return size ? size : 1;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_reset(flash_info_t *info)
+{
+       FPWV *base = (FPWV *)(info->start[0]);
+
+       /* Put FLASH back in read mode */
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
+               *base = (FPW)0x00FF00FF;        /* Intel Read Mode */
+       else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
+               *base = (FPW)0x00F000F0;        /* AMD Read Mode */
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+static flash_info_t *flash_get_info(ulong base)
+{
+       int i;
+       flash_info_t * info;
+
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
+               info = & flash_info[i];
+               if (info->size &&
+                       info->start[0] <= base && base <= info->start[0] + info->size - 1)
+                       break;
+       }
+
+       return i == CFG_MAX_FLASH_BANKS ? 0 : info;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_print_info (flash_info_t *info)
+{
+       int i;
+       uchar *boottype;
+       uchar *bootletter;
+       uchar *fmt;
+       uchar botbootletter[] = "B";
+       uchar topbootletter[] = "T";
+       uchar botboottype[] = "bottom boot sector";
+       uchar topboottype[] = "top boot sector";
+
+       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;
+#if 0
+       case FLASH_MAN_BM:      printf ("BRIGHT MICRO ");       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;
+#endif
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       /* check for top or bottom boot, if it applies */
+       if (info->flash_id & FLASH_BTYPE) {
+               boottype = botboottype;
+               bootletter = botbootletter;
+       } else {
+               boottype = topboottype;
+               bootletter = topbootletter;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM160T:
+       case FLASH_AM160B:
+               fmt = "29LV160%s (16 Mbit, %s)\n";
+               break;
+       case FLASH_AMDLV065D:
+               fmt = "29LV065 (64 Mbit, uniform sectors)\n";
+               break;
+       default:
+               fmt = "Unknown Chip Type\n";
+               break;
+       }
+
+       printf (fmt, bootletter, boottype);
+
+       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");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+ulong flash_get_size (FPWV *addr, flash_info_t *info)
+{
+       int             i;
+       ulong   offset;
+
+       /* Write auto select command: read Manufacturer ID */
+       /* Write auto select command sequence and test FLASH answer */
+       addr[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* for AMD, Intel ignores this */
+       addr[FLASH_CYCLE2] = (FPW)0x00550055;   /* for AMD, Intel ignores this */
+       addr[FLASH_CYCLE1] = (FPW)0x00900090;   /* selects Intel or AMD */
+
+       /* The manufacturer codes are only 1 byte, so just use 1 byte.
+        * This works for any bus width and any FLASH device width.
+        */
+       udelay(100);
+       switch (addr[0] & 0xff) {
+
+       case (uchar)AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+
+#if 0
+       case (uchar)INTEL_MANUFACT:
+               info->flash_id = FLASH_MAN_INTEL;
+               break;
+#endif
+
+       default:
+               printf ("unknown vendor=%x ", addr[0] & 0xff);
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               break;
+       }
+
+       /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
+       if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[2]) {
+
+       case (FPW)AMD_ID_LV160B:
+               info->flash_id += FLASH_AM160B;
+               info->sector_count = 35;
+               info->size = 0x00200000;
+               offset = 0x00e00000;
+               info->start[0] = (ulong)addr + offset;
+               info->start[1] = (ulong)addr + offset + 0x4000;
+               info->start[2] = (ulong)addr + offset + 0x6000;
+               info->start[3] = (ulong)addr + offset + 0x8000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = (ulong)addr + offset + 0x10000 * (i-3);
+               }
+               break;
+
+       case (FPW)AMD_ID_LV065D:
+               info->flash_id += FLASH_AMDLV065D;
+               info->sector_count = 128;
+               info->size = 0x00800000;
+               offset = 0x00800000;
+               for (i = 0; i < info->sector_count; i++)
+                       info->start[i] = (ulong)addr + offset + (i * 0x10000);
+               break;                          /* => 8 or 16 MB        */
+
+       default:
+               printf ("unknown AMD device=%x ", (FPW)addr[2]);
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* => no or unknown flash */
+       }
+
+       /* Put FLASH back in read mode */
+       flash_reset(info);
+
+       return (info->size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       FPWV *addr;
+       int flag, prot, sect;
+       int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
+       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;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AMDLV065D:
+               break;
+       case FLASH_UNKNOWN:
+       default:
+               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");
+       }
+
+       last  = get_timer(0);
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
+
+               if (info->protect[sect] != 0)   /* protected, skip it */
+                       continue;
+
+               /* Disable interrupts which might cause a timeout here */
+               flag = disable_interrupts();
+
+               addr = (FPWV *)(info->start[sect]);
+               if (intel) {
+                       *addr = (FPW)0x00500050; /* clear status register */
+                       *addr = (FPW)0x00200020; /* erase setup */
+                       *addr = (FPW)0x00D000D0; /* erase confirm */
+               }
+               else {
+                       /* must be AMD style if not Intel */
+                       FPWV *base;             /* first address in bank */
+
+                       base = (FPWV *)(info->start[0]);
+                       base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
+                       base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
+                       base[FLASH_CYCLE1] = (FPW)0x00800080;   /* erase mode */
+                       base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
+                       base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
+                       *addr = (FPW)0x00300030;        /* erase sector */
+               }
+
+               /* re-enable interrupts if necessary */
+               if (flag)
+                       enable_interrupts();
+
+               start = get_timer(0);
+
+               /* wait at least 50us for AMD, 80us for Intel.
+                * Let's wait 1 ms.
+                */
+               udelay (1000);
+
+               while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
+                       if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                               printf ("Timeout\n");
+
+                               if (intel) {
+                                       /* suspend erase        */
+                                       *addr = (FPW)0x00B000B0;
+                               }
+
+                               flash_reset(info);      /* reset to read mode */
+                               rcode = 1;              /* failed */
+                               break;
+                       }
+
+                       /* show that we're waiting */
+                       if ((get_timer(last)) > CFG_HZ) {/* every second */
+                               putc ('.');
+                               last = get_timer(0);
+                       }
+               }
+
+               /* show that we're waiting */
+               if ((get_timer(last)) > CFG_HZ) {       /* every second */
+                       putc ('.');
+                       last = get_timer(0);
+               }
+
+               flash_reset(info);      /* reset to read mode   */
+       }
+
+       printf (" done\n");
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * 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)
+{
+       FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
+       int bytes;        /* number of bytes to program in current word         */
+       int left;         /* number of bytes left to program                    */
+       int i, res;
+
+       for (left = cnt, res = 0;
+                left > 0 && res == 0;
+                addr += sizeof(data), left -= sizeof(data) - bytes) {
+
+               bytes = addr & (sizeof(data) - 1);
+               addr &= ~(sizeof(data) - 1);
+
+               /* combine source and destination data so can program
+                * an entire word of 16 or 32 bits
+                */
+               for (i = 0; i < sizeof(data); i++) {
+                       data <<= 8;
+                       if (i < bytes || i - bytes >= left )
+                               data += *((uchar *)addr + i);
+                       else
+                               data += *src++;
+               }
+
+               /* write one word to the flash */
+               switch (info->flash_id & FLASH_VENDMASK) {
+               case FLASH_MAN_AMD:
+                       res = write_word_amd(info, (FPWV *)addr, data);
+                       break;
+               default:
+                       /* unknown flash type, error! */
+                       printf ("missing or unknown FLASH type\n");
+                       res = 1;        /* not really a timeout, but gives error */
+                       break;
+               }
+       }
+
+       return (res);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash for AMD FLASH
+ * A word is 16 or 32 bits, whichever the bus width of the flash bank
+ * (not an individual chip) is.
+ *
+ * returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
+{
+       ulong start;
+       int flag;
+       int res = 0;    /* result, assume success       */
+       FPWV *base;             /* first address in flash bank  */
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*dest & data) != data) {
+               return (2);
+       }
+
+
+       base = (FPWV *)(info->start[0]);
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
+       base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
+       base[FLASH_CYCLE1] = (FPW)0x00A000A0;   /* selects program mode */
+
+       *dest = data;           /* start programming the data   */
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       start = get_timer (0);
+
+       /* data polling for D7 */
+       while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       *dest = (FPW)0x00F000F0;        /* reset bank */
+                       res = 1;
+               }
+       }
+
+       return (res);
+}
diff --git a/board/emk/top5200/top5200.c b/board/emk/top5200/top5200.c
new file mode 100644 (file)
index 0000000..536a515
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2003
+ * Reinhard Meyer, EMK Elektronik GmbH, r.meyer@emk-elektronik.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc5xxx.h>
+#include <pci.h>
+
+/*****************************************************************************
+ * initialize SDRAM/DDRAM controller.
+ * TBD: get data from I2C EEPROM
+ *****************************************************************************/
+long int initdram (int board_type)
+{
+       ulong dramsize = 0;
+#ifndef CFG_RAMBOOT
+       ulong   t;
+       ulong   tap_del;
+
+       #define MODE_EN         0x80000000
+       #define SOFT_PRE        2
+       #define SOFT_REF        4
+
+       /* configure SDRAM start/end */
+       *(vu_long *)MPC5XXX_SDRAM_CS0CFG = (CFG_SDRAM_BASE & 0xFFF00000) | CFG_DRAM_RAM_SIZE;
+       *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;  /* disabled */
+
+       /* setup config registers */
+       *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = CFG_DRAM_CONFIG1;
+       *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = CFG_DRAM_CONFIG2;
+
+       /* unlock mode register */
+       *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN;
+       /* precharge all banks */
+       *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN | SOFT_PRE;
+#if CFG_DRAM_DDR
+       /* set extended mode register */
+       *(vu_short *)MPC5XXX_SDRAM_MODE = CFG_DRAM_EMODE;
+#endif
+       /* set mode register */
+       *(vu_short *)MPC5XXX_SDRAM_MODE = CFG_DRAM_MODE | 0x0400;
+       /* precharge all banks */
+       *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN | SOFT_PRE;
+       /* auto refresh */
+       *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN | SOFT_REF;
+       /* set mode register */
+       *(vu_short *)MPC5XXX_SDRAM_MODE = CFG_DRAM_MODE;
+       /* normal operation */
+       *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL;
+       /* write default TAP delay */
+       *(vu_long *)MPC5XXX_CDM_PORCFG = CFG_DRAM_TAP_DEL << 24;
+
+#if 0
+       for (tap_del = 0; tap_del < 32; tap_del++) {
+               *(vu_long *)MPC5XXX_CDM_PORCFG = tap_del << 24;
+
+               printf ("\nTAP Delay:%x Filling DRAM...", *(vu_long *)MPC5XXX_CDM_PORCFG);
+               for (t = 0; t < 0x04000000; t+=4)
+                       *(vu_long *) t = t;
+               printf ("Checking DRAM...\n");
+               for (t = 0; t < 0x04000000; t+=4) {
+                       ulong   rval = *(vu_long *) t;
+                       if (rval != t) {
+                               printf ("mismatch at %x: ", t);
+                               printf (" 1.read %x", rval);
+                               printf (" 2.read %x", *(vu_long *) t);
+                               printf (" 3.read %x", *(vu_long *) t);
+                               break;
+                       }
+               }
+       }
+#endif
+#endif /* CFG_RAMBOOT */
+
+       dramsize = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS0CFG - 0x13)) << 20);
+
+       /* return total ram size */
+       return dramsize;
+}
+
+/*****************************************************************************
+ * print board identification
+ *****************************************************************************/
+int checkboard (void)
+{
+#if defined (CONFIG_EVAL5200)
+       puts ("Board: EMK TOP5200 on EVAL5200\n");
+#else
+#if defined (CONFIG_MINI5200)
+       puts ("Board: EMK TOP5200 on MINI5200\n");
+#else
+       puts ("Board: EMK TOP5200\n");
+#endif
+#endif
+       return 0;
+}
+
+/*****************************************************************************
+ * prepare for FLASH detection
+ *****************************************************************************/
+void flash_preinit(void)
+{
+       /*
+        * Now, when we are in RAM, enable flash write
+        * access for detection process.
+        * Note that CS_BOOT cannot be cleared when
+        * executing in flash.
+        */
+       *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+}
+
+/*****************************************************************************
+ * finalize FLASH setup
+ *****************************************************************************/
+void flash_afterinit(uint bank, ulong start, ulong size)
+{
+       if (bank == 0) { /* adjust mapping */
+               *(vu_long *)MPC5XXX_BOOTCS_START =
+               *(vu_long *)MPC5XXX_CS0_START = START_REG(start);
+               *(vu_long *)MPC5XXX_BOOTCS_STOP =
+               *(vu_long *)MPC5XXX_CS0_STOP = STOP_REG(start, size);
+       }
+}
+
+/*****************************************************************************
+ * otherinits after RAM is there and we are relocated to RAM
+ * note: though this is an int function, nobody cares for the result!
+ *****************************************************************************/
+int misc_init_r (void)
+{
+       /* read 'factory' part of EEPROM */
+       uchar buf[81];
+       uchar *p;
+       uint length;
+       uint addr;
+       uint len;
+
+       /* get length first */
+       addr = CFG_FACT_OFFSET;
+       if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, 2)) {
+bailout:
+               printf ("cannot read factory configuration\n");
+               printf ("be sure to set ethaddr yourself!\n");
+               return 0;
+       }
+       length = buf[0] + (buf[1] << 8);
+       addr += 2;
+
+       /* sanity check */
+       if (length < 20 || length > CFG_FACT_SIZE - 2)
+               goto bailout;
+
+       /* read lines */
+       while (length > 0) {
+               /* read one line */
+               len = length > 80 ? 80 : length;
+               if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, len))
+                       goto bailout;
+               /* mark end of buffer */
+               buf[len] = 0;
+               /* search end of line */
+               for (p = buf; *p && *p != 0x0a; p++);
+               if (!*p)
+                       goto bailout;
+               *p++ = 0;
+               /* advance to next line start */
+               length -= p - buf;
+               addr += p - buf;
+               /*printf ("%s\n", buf); */
+               /* search for our specific entry */
+               if (!strncmp ((char *) buf, "[RLA/lan/Ethernet] ", 19)) {
+                       setenv ("ethaddr", buf + 19);
+               } else if (!strncmp ((char *) buf, "[BOARD/SERIAL] ", 15)) {
+                       setenv ("serial#", buf + 15);
+               } else if (!strncmp ((char *) buf, "[BOARD/TYPE] ", 13)) {
+                       setenv ("board_id", buf + 13);
+               }
+       }
+       return (0);
+}
+
+/*****************************************************************************
+ * initialize the PCI system
+ *****************************************************************************/
+#ifdef CONFIG_PCI
+static struct pci_controller hose;
+
+extern void pci_mpc5xxx_init(struct pci_controller *);
+
+void pci_init_board(void)
+{
+       pci_mpc5xxx_init(&hose);
+}
+#endif
diff --git a/board/emk/top5200/u-boot.lds b/board/emk/top5200/u-boot.lds
new file mode 100644 (file)
index 0000000..d999dd1
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2003
+ * 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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/mpc5xxx/start.o        (.text)
+    *(.text)
+    *(.fixup)
+    *(.got1)
+    . = ALIGN(16);
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/include/configs/TOP5200.h b/include/configs/TOP5200.h
new file mode 100644 (file)
index 0000000..21daa2d
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.\r
+ *\r
+ * modified for TOP5200 by Reinhard Meyer, www.emk-elektronik.de\r
+ * TOP5200 differences from IceCube:\r
+ * 1 FLASH Bank for one Chip only, up to 64 MB in 16 MB Banks\r
+ *   bank switch controlled by TIMER_6(LSB) and TIMER_7(MSB) Pins\r
+ * 1 SDRAM/DDRAM Bank up to 256 MB\r
+ * local VPD I2C Bus is software driven and uses\r
+ *   GPIO_WKUP_6 for SDA, GPIO_WKUP_7 for SCL\r
+ * FLASH is located at 0x80000000\r
+ * Internal regs are at 0xfff00000\r
+ * Reset jumps to 0x00000100
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC5XXX         1       /* This is an MPC5xxx CPU */
+#define CONFIG_MPC5200         1       /* More exactly a MPC5200 */
+#define CONFIG_TOP5200         1       /* ... on TOP5200 board - we need this for FEC.C */
+
+#define CFG_MPC5XXX_CLKIN      33333333 /* ... running at 33MHz */
+
+#define BOOTFLAG_COLD          0x01    /* Normal Power-On: Boot from FLASH  */
+#define BOOTFLAG_WARM          0x02    /* Software reboot           */
+
+#define CFG_CACHELINE_SIZE     32      /* For MPC5xxx CPUs */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CACHELINE_SHIFT  5       /* log base 2 of the above value */
+#endif
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_PSC_CONSOLE     1       /* console is on PSC1 */
+#define CONFIG_BAUDRATE                9600    /* ... at 9600 bps */
+#define CFG_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200, 230400 }
+
+
+#ifdef CONFIG_EVAL5200         /* PCI is supported with Evaluation board only */
+/*
+ * PCI Mapping:
+ * 0x40000000 - 0x4fffffff - PCI Memory
+ * 0x50000000 - 0x50ffffff - PCI IO Space
+ */
+#  define CONFIG_PCI           1
+#  define CONFIG_PCI_PNP               1
+#  define CONFIG_PCI_SCAN_SHOW 1
+
+#  define CONFIG_PCI_MEM_BUS   0x40000000
+#  define CONFIG_PCI_MEM_PHYS  CONFIG_PCI_MEM_BUS
+#  define CONFIG_PCI_MEM_SIZE  0x10000000
+
+#  define CONFIG_PCI_IO_BUS    0x50000000
+#  define CONFIG_PCI_IO_PHYS   CONFIG_PCI_IO_BUS
+#  define CONFIG_PCI_IO_SIZE   0x01000000
+
+#  define ADD_PCI_CMD          CFG_CMD_PCI
+
+#else  /* no Evaluation board */
+
+#  define ADD_PCI_CMD          0  /* no CFG_CMD_PCI */
+
+#endif
+
+/*
+ * Supported commands
+ */
+#define CONFIG_COMMANDS                (CONFIG_CMD_DFL | ADD_PCI_CMD | \
+                                CFG_CMD_I2C | CFG_CMD_EEPROM)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY       5       /* autoboot after 5 seconds */
+#define CONFIG_BOOTCOMMAND     "bootm 100000"  /* autoboot command */
+#define CONFIG_BOOTARGS                "root=/dev/ram rw"
+
+/*
+ * IPB Bus clocking configuration.
+ */
+#undef CFG_IPBSPEED_133                /* define for 133MHz speed */
+\r
+/*
+ * I2C configuration
+ */
+/*
+ * EEPROM configuration
+ */
+#define CFG_EEPROM_PAGE_WRITE_BITS     3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 70
+
+#define CFG_I2C_EEPROM_ADDR_LEN 2
+#define CFG_EEPROM_SIZE 0x2000
+\r
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_MISC_INIT_R
+\r
+#undef CONFIG_HARD_I2C                 /* I2C with hardware support */
+#define        CONFIG_SOFT_I2C         1
+\r
+#if defined (CONFIG_SOFT_I2C)
+#  define SDA0                 0x40
+#  define SCL0                 0x80
+#  define GPIOE0               *((volatile uchar*)(CFG_MBAR+0x0c00))\r
+#  define DDR0                 *((volatile uchar*)(CFG_MBAR+0x0c08))\r
+#  define DVO0                 *((volatile uchar*)(CFG_MBAR+0x0c0c))\r
+#  define DVI0                 *((volatile uchar*)(CFG_MBAR+0x0c20))\r
+#  define ODE0                 *((volatile uchar*)(CFG_MBAR+0x0c04))\r
+#  define I2C_INIT             {GPIOE0|=(SDA0|SCL0);ODE0|=(SDA0|SCL0);DVO0|=(SDA0|SCL0);DDR0|=(SDA0|SCL0);}
+#  define I2C_READ             ((DVI0&SDA0)?1:0)
+#  define I2C_SDA(x)   {if(x)DVO0|=SDA0;else DVO0&=~SDA0;}
+#  define I2C_SCL(x)   {if(x)DVO0|=SCL0;else DVO0&=~SCL0;}
+#  define I2C_DELAY            {udelay(5);}
+#  define I2C_ACTIVE   {DDR0|=SDA0;}
+#  define I2C_TRISTATE {DDR0&=~SDA0;}
+#  define CFG_I2C_SPEED                100000
+#  define CFG_I2C_SLAVE                0x7F
+#endif
+\r
+#if defined (CONFIG_HARD_I2C)\r
+#  define CFG_I2C_MODULE       2               /* Select I2C module #1 or #2 */
+#  define CFG_I2C_SPEED                100000  /* 100 kHz */
+#  define CFG_I2C_SLAVE                0x7F
+#endif\r
+
+/*
+ * Flash configuration, expect one 16 Megabyte Bank at most
+ */
+#define CFG_FLASH_BASE         0xff000000
+#define CFG_FLASH_SIZE         0x01000000
+#define CFG_MAX_FLASH_BANKS    1       /* max num of memory banks      */
+#define CFG_ENV_ADDR           (CFG_FLASH_BASE + 0)\r
+
+#define CFG_MAX_FLASH_SECT     256     /* max num of sects on one chip */
+
+#define CFG_FLASH_ERASE_TOUT   240000  /* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT   500     /* Flash Write Timeout (in ms)  */
+
+#undef CONFIG_FLASH_16BIT      /* Flash is 8-bit */
+
+/*\r
+ * DRAM configuration - will be read from VPD later... TODO!\r
+ */\r
+#if 0\r
+/* 2x MT48LC16M16A2 - 7.0 ns SDRAMS = 64 MegaBytes Total */\r
+#define        CFG_DRAM_DDR            0\r
+#define CFG_DRAM_EMODE         0\r
+#define CFG_DRAM_MODE          0x008D\r
+#define CFG_DRAM_CONTROL       0x514F0000\r
+#define CFG_DRAM_CONFIG1       0xC2233A00\r
+#define CFG_DRAM_CONFIG2       0x88B70004\r
+#define        CFG_DRAM_TAP_DEL        0x08\r
+#define CFG_DRAM_RAM_SIZE      0x19\r
+#endif\r
+#if 1\r
+/* 2x MT48LC16M16A2 - 7.5 ns SDRAMS = 64 MegaBytes Total */\r
+#define        CFG_DRAM_DDR            0\r
+#define CFG_DRAM_EMODE         0\r
+#define CFG_DRAM_MODE          0x00CD\r
+#define CFG_DRAM_CONTROL       0x514F0000\r
+#define CFG_DRAM_CONFIG1       0xD2333A00\r
+#define CFG_DRAM_CONFIG2       0x8AD70004\r
+#define        CFG_DRAM_TAP_DEL        0x08\r
+#define CFG_DRAM_RAM_SIZE      0x19\r
+#endif\r
+\r
+/*
+ * Environment settings
+ */
+#define CFG_ENV_IS_IN_EEPROM   1       /* turn on EEPROM env feature */
+#define CFG_ENV_OFFSET         0x1000
+#define CFG_ENV_SIZE           0x0700
+#define CFG_I2C_EEPROM_ADDR 0x57
+
+/*\r
+ * VPD settings\r
+ */\r
+#define CFG_FACT_OFFSET                0x1800
+#define CFG_FACT_SIZE          0x0800
+#define CFG_I2C_FACT_ADDR      0x57
+\r
+/*
+ * Memory map\r
+ *\r
+ * Warning!!! with the current BestComm Task, MBAR MUST BE set to 0xf0000000\r
+ */
+#define CFG_MBAR                       0xf0000000      /* DO NOT CHANGE this */
+#define CFG_SDRAM_BASE         0x00000000
+#define CFG_DEFAULT_MBAR       0x80000000
+
+/* Use SRAM until RAM will be available */
+#define CFG_INIT_RAM_ADDR      MPC5XXX_SRAM
+#define CFG_INIT_RAM_END       MPC5XXX_SRAM_SIZE       /* End of used area in DPRAM */
+
+
+#define CFG_GBL_DATA_SIZE      128     /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET    (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET     CFG_GBL_DATA_OFFSET
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT         1
+#endif
+
+#define CFG_MONITOR_LEN                (256 << 10)     /* Reserve 256 kB for Monitor   */
+#define CFG_MALLOC_LEN         (128 << 10)     /* Reserve 128 kB for malloc()  */
+#define CFG_BOOTMAPSZ          (8 << 20)       /* Initial Memory map for Linux */
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_MPC5XXX_FEC     1
+#define CONFIG_FEC_10MBIT      1               /* Workaround for FEC 100Mbit problem */
+#define        CONFIG_PHY_ADDR         0x1f\r
+#define        CONFIG_PHY_TYPE         0x79c874
+/*
+ * GPIO configuration:\r
+ * PSC1,2,3 predefined as UART\r
+ * PCI disabled\r
+ * Ethernet 100 with MD
+ */
+#define CFG_GPS_PORT_CONFIG    0x00058444
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP                   /* undef to save memory     */
+#define CFG_PROMPT             "=> "   /* Monitor Command Prompt   */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#  define CFG_CBSIZE           1024    /* Console I/O Buffer Size  */
+#else
+#  define CFG_CBSIZE           256     /* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)  /* Print Buffer Size */
+#define CFG_MAXARGS            16              /* max number of command args   */
+#define CFG_BARGSIZE           CFG_CBSIZE      /* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START      0x00100000      /* memtest works on */
+#define CFG_MEMTEST_END                0x01f00000      /* 1 ... 31 MB in DRAM  */
+
+#define CFG_LOAD_ADDR          0x100000        /* default load address */
+
+#define CFG_HZ                 1000    /* decrementer freq: 1 ms ticks */
+
+/*
+ * Various low-level settings
+ */
+#define CFG_HID0_INIT          HID0_ICE | HID0_ICFI
+#define CFG_HID0_FINAL         HID0_ICE
+
+#define CFG_BOOTCS_START       CFG_FLASH_BASE
+#define CFG_BOOTCS_SIZE                CFG_FLASH_SIZE
+#define CFG_BOOTCS_CFG         0x00047801
+#define CFG_CS0_START          CFG_FLASH_BASE
+#define CFG_CS0_SIZE           CFG_FLASH_SIZE
+
+#define CFG_CS_BURST           0x00000000
+#define CFG_CS_DEADCYCLE       0x33333333
+
+#define CFG_RESET_ADDRESS      0x7f000000
+
+#endif /* __CONFIG_H */