* Add start-up delay to make sure power has stabilized before
attempting to switch on USB on SX1 board.
* Patch by Josef Wagner, 18 Mar 2004:
- Add support for MicroSys XM250 board (PXA255)
- Add support for MicroSys PM828 board (MPC8280)
- Add support for 32 MB Flash on PM825/826
- new SDRAM refresh rate for PM825/PM826
- added support for MicroSys PM520 (MPC5200)
- replaced Query by Identify command in CPU86/flash.c
to support 28F160F3B
* Fix wrap around problem with udelay() on ARM920T
* Add support for Macronix flash on TRAB board
diff --git a/board/cpu86/flash.c b/board/cpu86/flash.c
index 0769dc5..1535a6b 100644
--- a/board/cpu86/flash.c
+++ b/board/cpu86/flash.c
@@ -41,10 +41,10 @@
info->sector_count = info->size = 0;
info->flash_id = FLASH_UNKNOWN;
- /* Write query command sequence and test FLASH answer
+ /* Write identify command sequence and test FLASH answer
*/
- baseaddr[0] = 0x00980098;
- baseaddr[1] = 0x00980098;
+ baseaddr[0] = 0x00900090;
+ baseaddr[1] = 0x00900090;
flashtest_h = baseaddr[0]; /* manufacturer ID */
flashtest_l = baseaddr[1];
diff --git a/board/pm520/Makefile b/board/pm520/Makefile
new file mode 100644
index 0000000..8cf0d7d
--- /dev/null
+++ b/board/pm520/Makefile
@@ -0,0 +1,47 @@
+
+#
+# (C) Copyright 2003-2004
+# 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/pm520/config.mk b/board/pm520/config.mk
new file mode 100644
index 0000000..ad689f3
--- /dev/null
+++ b/board/pm520/config.mk
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2003-2004
+# 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
+#
+
+#
+# PM520 board
+#
+
+TEXT_BASE = 0xfff00000
+# TEXT_BASE = 0x00100000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/pm520/flash.c b/board/pm520/flash.c
new file mode 100644
index 0000000..4ea8b36
--- /dev/null
+++ b/board/pm520/flash.c
@@ -0,0 +1,545 @@
+/*
+ * (C) Copyright 2001
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2001-2004
+ * 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 <linux/byteorder/swab.h>
+
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/* Board support for 1 or 2 flash devices */
+#define FLASH_PORT_WIDTH32
+#undef FLASH_PORT_WIDTH16
+
+#ifdef FLASH_PORT_WIDTH16
+#define FLASH_PORT_WIDTH ushort
+#define FLASH_PORT_WIDTHV vu_short
+#define SWAP(x) (x)
+#else
+#define FLASH_PORT_WIDTH ulong
+#define FLASH_PORT_WIDTHV vu_long
+#define SWAP(x) (x)
+#endif
+
+/* Intel-compatible flash ID */
+#define INTEL_COMPAT 0x00890089
+#define INTEL_ALT 0x00B000B0
+
+/* Intel-compatible flash commands */
+#define INTEL_PROGRAM 0x00100010
+#define INTEL_ERASE 0x00200020
+#define INTEL_CLEAR 0x00500050
+#define INTEL_LOCKBIT 0x00600060
+#define INTEL_PROTECT 0x00010001
+#define INTEL_STATUS 0x00700070
+#define INTEL_READID 0x00900090
+#define INTEL_CONFIRM 0x00D000D0
+#define INTEL_RESET 0xFFFFFFFF
+
+/* Intel-compatible flash status bits */
+#define INTEL_FINISHED 0x00800080
+#define INTEL_OK 0x00800080
+
+#define FPW FLASH_PORT_WIDTH
+#define FPWV FLASH_PORT_WIDTHV
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (FPW *addr, flash_info_t *info);
+static int write_data (flash_info_t *info, ulong dest, FPW data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+void inline spin_wheel (void);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ int i;
+ ulong size = 0;
+
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+ switch (i) {
+ case 0:
+ flash_get_size ((FPW *) CFG_FLASH_BASE, &flash_info[i]);
+ flash_get_offsets (CFG_FLASH_BASE, &flash_info[i]);
+ break;
+ default:
+ panic ("configured to many flash banks!\n");
+ break;
+ }
+ size += flash_info[i].size;
+ }
+
+ /* Protect monitor and environment sectors
+ */
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE + monitor_flash_len - 1,
+ &flash_info[0] );
+
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+ for (i = 0; i < info->sector_count; i++) {
+ info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
+ info->protect[i] = 0;
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------
+ */
+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_INTEL:
+ printf ("INTEL ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F128J3A:
+ printf ("28F128J3A\n");
+ break;
+
+ case FLASH_28F640J3A:
+ printf ("28F640J3A\n");
+ break;
+
+ case FLASH_28F320J3A:
+ printf ("28F320J3A\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 (FPW *addr, flash_info_t *info)
+{
+ volatile FPW value;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr[0x5555] = (FPW) 0x00AA00AA;
+ addr[0x2AAA] = (FPW) 0x00550055;
+ addr[0x5555] = (FPW) 0x00900090;
+
+ mb ();
+ value = addr[0];
+
+ switch (value) {
+
+ case (FPW) INTEL_MANUFACT:
+ info->flash_id = FLASH_MAN_INTEL;
+ break;
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
+ return (0); /* no or unknown flash */
+ }
+
+ mb ();
+ value = addr[1]; /* device ID */
+
+ switch (value) {
+
+ case (FPW) INTEL_ID_28F128J3A:
+ info->flash_id += FLASH_28F128J3A;
+ info->sector_count = 128;
+ info->size = 0x02000000;
+ break; /* => 32 MB */
+
+ case (FPW) INTEL_ID_28F640J3A:
+ info->flash_id += FLASH_28F640J3A;
+ info->sector_count = 64;
+ info->size = 0x01000000;
+ break; /* => 16 MB */
+
+ case (FPW) INTEL_ID_28F320J3A:
+ info->flash_id += FLASH_28F320J3A;
+ info->sector_count = 32;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ break;
+ }
+
+ if (info->sector_count > CFG_MAX_FLASH_SECT) {
+ printf ("** ERROR: sector count %d > max (%d) **\n",
+ info->sector_count, CFG_MAX_FLASH_SECT);
+ info->sector_count = CFG_MAX_FLASH_SECT;
+ }
+
+ addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
+
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ int flag, prot, sect;
+ ulong type, start, 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;
+ }
+
+ type = (info->flash_id & FLASH_VENDMASK);
+ if ((type != FLASH_MAN_INTEL)) {
+ 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");
+ }
+
+ start = get_timer (0);
+ last = start;
+
+ /* 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 */
+ FPWV *addr = (FPWV *) (info->start[sect]);
+ FPW status;
+
+ printf ("Erasing sector %2d ... ", sect);
+
+ /* arm simple, non interrupt dependent timer */
+ start = get_timer(0);
+
+ *addr = (FPW) 0x00500050; /* clear status register */
+ *addr = (FPW) 0x00200020; /* erase setup */
+ *addr = (FPW) 0x00D000D0; /* erase confirm */
+
+ while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
+ if (get_timer(start) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ *addr = (FPW) 0x00B000B0; /* suspend erase */
+ *addr = (FPW) 0x00FF00FF; /* reset to read mode */
+ rcode = 1;
+ break;
+ }
+ }
+
+ *addr = 0x00500050; /* clear status register cmd. */
+ *addr = 0x00FF00FF; /* resest to read mode */
+
+ printf (" done\n");
+ }
+ }
+ return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp;
+ FPW data;
+ int count, i, l, rc, port_width;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return 4;
+ }
+/* get lower word aligned address */
+#ifdef FLASH_PORT_WIDTH16
+ wp = (addr & ~1);
+ port_width = 2;
+#else
+ wp = (addr & ~3);
+ port_width = 4;
+#endif
+
+ /*
+ * 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 < port_width && cnt > 0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt == 0 && i < port_width; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+ return (rc);
+ }
+ wp += port_width;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ count = 0;
+ while (cnt >= port_width) {
+ data = 0;
+ for (i = 0; i < port_width; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+ return (rc);
+ }
+ wp += port_width;
+ cnt -= port_width;
+ if (count++ > 0x800) {
+ spin_wheel ();
+ count = 0;
+ }
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i < port_width; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ return (write_data (info, wp, SWAP (data)));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word or halfword to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_data (flash_info_t *info, ulong dest, FPW data)
+{
+ FPWV *addr = (FPWV *) dest;
+ ulong status;
+ ulong start;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*addr & data) != data) {
+ printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts ();
+
+ *addr = (FPW) 0x00400040; /* write setup */
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ start = get_timer(0);
+
+ /* wait while polling the status register */
+ while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ *addr = (FPW) 0x00FF00FF; /* restore read mode */
+ return (1);
+ }
+ }
+
+ *addr = (FPW) 0x00FF00FF; /* restore read mode */
+
+ return (0);
+}
+
+void inline spin_wheel (void)
+{
+ static int p = 0;
+ static char w[] = "\\/-";
+
+ printf ("\010%c", w[p]);
+ (++p == 3) ? (p = 0) : 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Set/Clear sector's lock bit, returns:
+ * 0 - OK
+ * 1 - Error (timeout, voltage problems, etc.)
+ */
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+ ulong start;
+ int i;
+ int rc = 0;
+ vu_long *addr = (vu_long *)(info->start[sector]);
+ int flag = disable_interrupts();
+
+ *addr = INTEL_CLEAR; /* Clear status register */
+ if (prot) { /* Set sector lock bit */
+ *addr = INTEL_LOCKBIT; /* Sector lock bit */
+ *addr = INTEL_PROTECT; /* set */
+ }
+ else { /* Clear sector lock bit */
+ *addr = INTEL_LOCKBIT; /* All sectors lock bits */
+ *addr = INTEL_CONFIRM; /* clear */
+ }
+
+ start = get_timer(0);
+
+ while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
+ if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) {
+ printf("Flash lock bit operation timed out\n");
+ rc = 1;
+ break;
+ }
+ }
+
+ if (*addr != INTEL_OK) {
+ printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
+ (uint)addr, (uint)*addr);
+ rc = 1;
+ }
+
+ if (!rc)
+ info->protect[sector] = prot;
+
+ /*
+ * Clear lock bit command clears all sectors lock bits, so
+ * we have to restore lock bits of protected sectors.
+ */
+ if (!prot)
+ {
+ for (i = 0; i < info->sector_count; i++)
+ {
+ if (info->protect[i])
+ {
+ start = get_timer(0);
+ addr = (vu_long *)(info->start[i]);
+ *addr = INTEL_LOCKBIT; /* Sector lock bit */
+ *addr = INTEL_PROTECT; /* set */
+ while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
+ {
+ if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT)
+ {
+ printf("Flash lock bit operation timed out\n");
+ rc = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ *addr = INTEL_RESET; /* Reset to read array mode */
+
+ return rc;
+}
diff --git a/board/pm520/pm520.c b/board/pm520/pm520.c
new file mode 100644
index 0000000..bb0268f
--- /dev/null
+++ b/board/pm520/pm520.c
@@ -0,0 +1,193 @@
+/*
+ * (C) Copyright 2003-2004
+ * 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 <mpc5xxx.h>
+#include <pci.h>
+
+#ifndef CFG_RAMBOOT
+static long int dram_size(long int *base, long int maxsize)
+{
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof (long));
+ }
+ }
+ return (maxsize);
+}
+
+static void sdram_start (int hi_addr)
+{
+ long hi_addr_bit = hi_addr ? 0x01000000 : 0;
+
+ /* unlock mode register */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0000 | hi_addr_bit;
+ /* precharge all banks */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
+ /* set mode register */
+#if defined(CONFIG_MPC5200)
+ *(vu_long *)MPC5XXX_SDRAM_MODE = 0x408d0000;
+#elif defined(CONFIG_MGT5100)
+ *(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
+#endif
+ /* precharge all banks */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
+ /* auto refresh */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit;
+ /* set mode register */
+ *(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
+ /* normal operation */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000 | hi_addr_bit;
+}
+#endif
+
+long int initdram (int board_type)
+{
+ ulong dramsize = 0;
+#ifndef CFG_RAMBOOT
+ ulong test1, test2;
+
+ /* configure SDRAM start/end */
+#if defined(CONFIG_MPC5200)
+ *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
+
+ /* setup config registers */
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2233a00;
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
+
+#elif defined(CONFIG_MGT5100)
+ *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
+ *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
+ *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
+
+ /* setup config registers */
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2222600;
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
+
+ /* address select register */
+ *(vu_long *)MPC5XXX_SDRAM_XLBSEL = 0x03000000;
+#endif
+ sdram_start(0);
+ test1 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
+ sdram_start(1);
+ test2 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
+ if (test1 > test2) {
+ sdram_start(0);
+ dramsize = test1;
+ } else {
+ dramsize = test2;
+ }
+#if defined(CONFIG_MPC5200)
+ *(vu_long *)MPC5XXX_SDRAM_CS0CFG =
+ (0x13 + __builtin_ffs(dramsize >> 20) - 1);
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
+#elif defined(CONFIG_MGT5100)
+ *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
+#endif
+
+#else
+#ifdef CONFIG_MGT5100
+ *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
+ dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
+#else
+ dramsize = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS0CFG - 0x13)) << 20);
+#endif
+#endif /* CFG_RAMBOOT */
+ /* return total ram size */
+ return dramsize;
+}
+
+int checkboard (void)
+{
+#if defined(CONFIG_MPC5200)
+ puts ("Board: MicroSys PM520 \n");
+#elif defined(CONFIG_MGT5100)
+ puts ("Board: MicroSys PM510 \n");
+#endif
+ return 0;
+}
+
+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.
+ */
+#if defined(CONFIG_MGT5100)
+ *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
+ *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
+#endif
+ *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+}
+
+void flash_afterinit(ulong size)
+{
+ if (size == 0x800000) { /* adjust mapping */
+ *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START =
+ START_REG(CFG_BOOTCS_START | size);
+ *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP =
+ STOP_REG(CFG_BOOTCS_START | size, size);
+ }
+}
+
+#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/pm520/u-boot.lds b/board/pm520/u-boot.lds
new file mode 100644
index 0000000..672a250
--- /dev/null
+++ b/board/pm520/u-boot.lds
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2003-2004
+ * 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/board/pm826/config.mk b/board/pm826/config.mk
index d2ab4fe..c93bad9 100644
--- a/board/pm826/config.mk
+++ b/board/pm826/config.mk
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2001, 2002
+# (C) Copyright 2001-2004
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -22,21 +22,16 @@
#
#
-# PM826 boards
+# MicroSys PM826 board:
#
-# This should be equal to the CFG_FLASH_BASE or
-# CFG_BOOTROM_BASE define in config_PM826.h
-# for the "final" configuration, with U-Boot
-# in flash, or the address in RAM where
-# U-Boot is loaded at for debugging.
-#
-ifeq ($(CONFIG_BOOT_ROM),y)
- TEXT_BASE := 0xFF800000
- PLATFORM_CPPFLAGS += -DCONFIG_BOOT_ROM
-else
- TEXT_BASE := 0xFF000000
+sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
+
+ifndef TEXT_BASE
+## Standard: boot 64-bit flash
+TEXT_BASE = 0xFF000000
+
endif
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)
diff --git a/board/pm826/flash.c b/board/pm826/flash.c
index 770a46d..fee07cf 100644
--- a/board/pm826/flash.c
+++ b/board/pm826/flash.c
@@ -69,6 +69,11 @@
info->sector_count = 39;
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
break;
+ case INTEL_ID_28F640C3B:
+ info->flash_id = FLASH_28F640C3B;
+ info->sector_count = 135;
+ info->size = 0x02000000; /* 16 * 2 MB = 32 MB */
+ break;
default:
return (0); /* no or unknown flash */
}
@@ -79,10 +84,11 @@
volatile unsigned long *tmp = baseaddr;
/* set up sector start adress table (bottom sector type)
- * AND unlock the sectors (if our chip is 160C3)
+ * AND unlock the sectors (if our chip is 160C3 or 640C3)
*/
for (i = 0; i < info->sector_count; i++) {
- if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) {
+ if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
tmp[0] = 0x00600060;
tmp[1] = 0x00600060;
tmp[0] = 0x00D000D0;
@@ -177,6 +183,9 @@
case FLASH_28F160F3B:
printf ("28F160F3B (16 M, bottom sector)\n");
break;
+ case FLASH_28F640C3B:
+ printf ("28F640C3B (64 M, bottom sector)\n");
+ break;
default:
printf ("Unknown Chip Type\n");
break;
diff --git a/board/pm828/Makefile b/board/pm828/Makefile
new file mode 100644
index 0000000..b9ef0c0
--- /dev/null
+++ b/board/pm828/Makefile
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2001-2004
+# 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): .depend $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/pm828/config.mk b/board/pm828/config.mk
new file mode 100644
index 0000000..e894af7
--- /dev/null
+++ b/board/pm828/config.mk
@@ -0,0 +1,37 @@
+#
+# (C) Copyright 2003-2004
+# 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
+#
+
+#
+# MicroSys PM828 board:
+#
+
+
+sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
+
+ifndef TEXT_BASE
+## Standard: boot 64-bit flash
+TEXT_BASE = 0x40000000
+
+endif
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)
diff --git a/board/pm828/flash.c b/board/pm828/flash.c
new file mode 100644
index 0000000..1f21b3e
--- /dev/null
+++ b/board/pm828/flash.c
@@ -0,0 +1,386 @@
+/*
+ * (C) Copyright 2001-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Flash Routines for Intel devices
+ *
+ *--------------------------------------------------------------------
+ * 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 <mpc8xx.h>
+
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+/*-----------------------------------------------------------------------
+ */
+ulong flash_get_size (volatile unsigned long *baseaddr,
+ flash_info_t * info)
+{
+ short i;
+ unsigned long flashtest_h, flashtest_l;
+
+ info->sector_count = info->size = 0;
+ info->flash_id = FLASH_UNKNOWN;
+
+ /* Write query command sequence and test FLASH answer
+ */
+ baseaddr[0] = 0x00980098;
+ baseaddr[1] = 0x00980098;
+
+ flashtest_h = baseaddr[0]; /* manufacturer ID */
+ flashtest_l = baseaddr[1];
+
+ if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
+ return (0); /* no or unknown flash */
+
+ flashtest_h = baseaddr[2]; /* device ID */
+ flashtest_l = baseaddr[3];
+
+ if (flashtest_h != flashtest_l)
+ return (0);
+
+ switch (flashtest_h) {
+ case INTEL_ID_28F160C3B:
+ info->flash_id = FLASH_28F160C3B;
+ info->sector_count = 39;
+ info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
+ break;
+ case INTEL_ID_28F160F3B:
+ info->flash_id = FLASH_28F160F3B;
+ info->sector_count = 39;
+ info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
+ break;
+ case INTEL_ID_28F640C3B:
+ info->flash_id = FLASH_28F640C3B;
+ info->sector_count = 135;
+ info->size = 0x02000000; /* 16 * 2 MB = 32 MB */
+ break;
+ default:
+ return (0); /* no or unknown flash */
+ }
+
+ info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */
+
+ if (info->flash_id & FLASH_BTYPE) {
+ volatile unsigned long *tmp = baseaddr;
+
+ /* set up sector start adress table (bottom sector type)
+ * AND unlock the sectors (if our chip is 160C3 or 640c3)
+ */
+ for (i = 0; i < info->sector_count; i++) {
+ if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
+ tmp[0] = 0x00600060;
+ tmp[1] = 0x00600060;
+ tmp[0] = 0x00D000D0;
+ tmp[1] = 0x00D000D0;
+ }
+ info->start[i] = (uint) tmp;
+ tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith */
+ }
+ }
+
+ memset (info->protect, 0, info->sector_count);
+
+ baseaddr[0] = 0x00FF00FF;
+ baseaddr[1] = 0x00FF00FF;
+
+ return (info->size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+unsigned long flash_init (void)
+{
+ unsigned long size_b0 = 0;
+ 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 (only one bank) */
+
+ size_b0 = flash_get_size ((ulong *) CFG_FLASH0_BASE, &flash_info[0]);
+ if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b0, size_b0 >> 20);
+ }
+
+ /* protect monitor and environment sectors
+ */
+
+#ifndef CONFIG_BOOT_ROM
+ /* If U-Boot is booted from ROM the CFG_MONITOR_BASE > CFG_FLASH0_BASE
+ * but we shouldn't protect it.
+ */
+
+# if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]
+ );
+# endif
+#endif /* CONFIG_BOOT_ROM */
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+# ifndef CFG_ENV_SIZE
+# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
+# endif
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+#endif
+
+ return (size_b0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+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 >> 16) & 0xff) {
+ case 0x89:
+ printf ("INTEL ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F160C3B:
+ printf ("28F160C3B (16 M, bottom sector)\n");
+ break;
+ case FLASH_28F160F3B:
+ printf ("28F160F3B (16 M, bottom sector)\n");
+ break;
+ case FLASH_28F640C3B:
+ printf ("28F640C3B (64 M, bottom 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");
+}
+
+/*-----------------------------------------------------------------------
+ */
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ int flag, prot, 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;
+ }
+
+ 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");
+ }
+
+ /* Start erase on unprotected sectors
+ */
+ for (sect = s_first; sect <= s_last; sect++) {
+ volatile ulong *addr =
+ (volatile unsigned long *) info->start[sect];
+
+ start = get_timer (0);
+ last = start;
+ if (info->protect[sect] == 0) {
+ /* Disable interrupts which might cause a timeout here
+ */
+ flag = disable_interrupts ();
+
+ /* Erase the block
+ */
+ addr[0] = 0x00200020;
+ addr[1] = 0x00200020;
+ addr[0] = 0x00D000D0;
+ addr[1] = 0x00D000D0;
+
+ /* re-enable interrupts if necessary
+ */
+ if (flag)
+ enable_interrupts ();
+
+ /* wait at least 80us - let's wait 1 ms
+ */
+ udelay (1000);
+
+ last = start;
+ while ((addr[0] & 0x00800080) != 0x00800080 ||
+ (addr[1] & 0x00800080) != 0x00800080) {
+ if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout (erase suspended!)\n");
+ /* Suspend erase
+ */
+ addr[0] = 0x00B000B0;
+ addr[1] = 0x00B000B0;
+ goto DONE;
+ }
+ /* show that we're waiting
+ */
+ if ((now - last) > 1000) { /* every second */
+ serial_putc ('.');
+ last = now;
+ }
+ }
+ if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
+ printf ("*** ERROR: erase failed!\n");
+ goto DONE;
+ }
+ }
+ /* Clear status register and reset to read mode
+ */
+ addr[0] = 0x00500050;
+ addr[1] = 0x00500050;
+ addr[0] = 0x00FF00FF;
+ addr[1] = 0x00FF00FF;
+ }
+
+ printf (" done\n");
+
+DONE:
+ return 0;
+}
+
+static int write_word (flash_info_t *, volatile unsigned long *, ulong);
+
+/*-----------------------------------------------------------------------
+ * 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 v;
+ int i, l, cc = cnt, res = 0;
+
+
+ for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
+ l = (addr & 3);
+ addr &= ~3;
+
+ for (i = 0; i < 4; i++) {
+ v = (v << 8) + (i < l || i - l >= cc ?
+ *((unsigned char *) addr + i) : *src++);
+ }
+
+ if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
+ break;
+ }
+
+ return (res);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t * info, volatile unsigned long *addr,
+ ulong data)
+{
+ int flag, res = 0;
+ ulong start;
+
+ /* Check if Flash is (sufficiently) erased
+ */
+ if ((*addr & data) != data)
+ return (2);
+
+ /* Disable interrupts which might cause a timeout here
+ */
+ flag = disable_interrupts ();
+
+ *addr = 0x00400040;
+ *addr = data;
+
+ /* re-enable interrupts if necessary
+ */
+ if (flag)
+ enable_interrupts ();
+
+ start = get_timer (0);
+ while ((*addr & 0x00800080) != 0x00800080) {
+ if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
+ /* Suspend program
+ */
+ *addr = 0x00B000B0;
+ res = 1;
+ goto OUT;
+ }
+ }
+
+ if (*addr & 0x00220022) {
+ printf ("*** ERROR: program failed!\n");
+ res = 1;
+ }
+
+OUT:
+ /* Clear status register and reset to read mode
+ */
+ *addr = 0x00500050;
+ *addr = 0x00FF00FF;
+
+ return (res);
+}
diff --git a/board/pm828/pm828.c b/board/pm828/pm828.c
new file mode 100644
index 0000000..3193274
--- /dev/null
+++ b/board/pm828/pm828.c
@@ -0,0 +1,363 @@
+/*
+ * (C) Copyright 2001-2004
+ * 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 <ioports.h>
+#include <mpc8260.h>
+#include <pci.h>
+
+/*
+ * I/O Port configuration table
+ *
+ * if conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+ /* Port A configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PA31 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 COL */
+ /* PA30 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 CRS */
+ /* PA29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC1 TXER */
+ /* PA28 */ { 1, 1, 1, 1, 0, 0 }, /* FCC1 TXEN */
+ /* PA27 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RXDV */
+ /* PA26 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RXER */
+ /* PA25 */ { 0, 0, 0, 1, 0, 0 }, /* PA25 */
+ /* PA24 */ { 0, 0, 0, 1, 0, 0 }, /* PA24 */
+ /* PA23 */ { 0, 0, 0, 1, 0, 0 }, /* PA23 */
+ /* PA22 */ { 0, 0, 0, 1, 0, 0 }, /* PA22 */
+ /* PA21 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD3 */
+ /* PA20 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD2 */
+ /* PA19 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD1 */
+ /* PA18 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD0 */
+ /* PA17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD0 */
+ /* PA16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD1*/
+ /* PA15 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD2 */
+ /* PA14 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD3 */
+ /* PA13 */ { 0, 0, 0, 1, 0, 0 }, /* PA13 */
+ /* PA12 */ { 0, 0, 0, 1, 0, 0 }, /* PA12 */
+ /* PA11 */ { 0, 0, 0, 1, 0, 0 }, /* PA11 */
+ /* PA10 */ { 0, 0, 0, 1, 0, 0 }, /* PA10 */
+ /* PA9 */ { 0, 1, 0, 1, 0, 0 }, /* PA9 */
+ /* PA8 */ { 0, 1, 0, 0, 0, 0 }, /* PA8 */
+ /* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
+ /* PA6 */ { 0, 0, 0, 1, 0, 0 }, /* PA6 */
+ /* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
+ /* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
+ /* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
+ /* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
+ /* PA1 */ { 0, 0, 0, 1, 0, 0 }, /* PA1 */
+ /* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
+ },
+
+ /* Port B configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TX_ER */
+ /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RX_DV */
+ /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 TX_EN */
+#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_ETHER_INDEX == 1)
+#ifdef CONFIG_ETHER_ON_FCC2
+#error "SCC1 conflicts with FCC2"
+#endif
+ /* PB28 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 TXD */
+#else
+ /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RX_ER */
+#endif
+ /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 COL */
+ /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 CRS */
+ /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[3] */
+ /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[2] */
+ /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[1] */
+ /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[0] */
+ /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[0] */
+ /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[1] */
+ /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[2] */
+ /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[3] */
+ /* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
+ /* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* PB16 */
+ /* PB15 */ { 1, 1, 0, 0, 0, 0 }, /* SCC2 RXD */
+ /* PB14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC3 RXD */
+ /* PB13 */ { 0, 0, 0, 0, 0, 0 }, /* PB13 */
+ /* PB12 */ { 0, 0, 0, 0, 0, 0 }, /* PB12 */
+ /* PB11 */ { 0, 0, 0, 0, 0, 0 }, /* PB11 */
+ /* PB10 */ { 0, 0, 0, 0, 0, 0 }, /* PB10 */
+ /* PB9 */ { 0, 0, 0, 0, 0, 0 }, /* PB9 */
+ /* PB8 */ { 1, 1, 1, 1, 0, 0 }, /* SCC3 TXD */
+ /* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */
+ /* PB6 */ { 0, 0, 0, 0, 0, 0 }, /* PB6 */
+ /* PB5 */ { 0, 0, 0, 0, 0, 0 }, /* PB5 */
+ /* PB4 */ { 0, 0, 0, 0, 0, 0 }, /* PB4 */
+ /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
+ },
+
+ /* Port C */
+ { /* conf ppar psor pdir podr pdat */
+ /* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
+ /* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */
+ /* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 CTS */
+ /* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* SCC2 CTS */
+ /* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* PC27 */
+ /* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
+ /* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
+ /* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
+ /* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* PC23 */
+ /* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 TXCK */
+ /* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXCK */
+ /* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 TXCK(2) */
+ /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RXCK */
+ /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 TXCK */
+ /* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
+ /* PC16 */ { 0, 0, 0, 1, 0, 0 }, /* PC16 */
+ /* PC15 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
+ /* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 DCD */
+ /* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
+ /* PC12 */ { 0, 0, 0, 1, 0, 0 }, /* SCC2 DCD */
+ /* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* SCC3 CTS */
+ /* PC10 */ { 0, 0, 0, 1, 0, 0 }, /* SCC3 DCD */
+ /* PC9 */ { 0, 0, 0, 1, 0, 0 }, /* SCC4 CTS */
+ /* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* SCC4 DCD */
+ /* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
+ /* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
+ /* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */
+ /* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */
+ /* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
+ /* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* PC2 */
+ /* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* PC1 */
+ /* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* PC0 */
+ },
+
+ /* Port D */
+ { /* conf ppar psor pdir podr pdat */
+ /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 RXD */
+ /* PD30 */ { 0, 1, 1, 1, 0, 0 }, /* PD30 */
+ /* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 RTS */
+ /* PD28 */ { 0, 0, 0, 1, 0, 0 }, /* PD28 */
+ /* PD27 */ { 0, 1, 0, 1, 0, 0 }, /* SCC2 RTS */
+ /* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
+ /* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */
+ /* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */
+ /* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* SCC3 RTS */
+ /* PD22 */ { 1, 1, 0, 0, 0, 0 }, /* SCC4 RXD */
+ /* PD21 */ { 1, 1, 0, 1, 0, 0 }, /* SCC4 TXD */
+ /* PD20 */ { 0, 0, 1, 1, 0, 0 }, /* SCC4 RTS */
+ /* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
+ /* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
+ /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* PD17 */
+ /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* PD16 */
+#if defined(CONFIG_SOFT_I2C)
+ /* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
+ /* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
+#else
+#if defined(CONFIG_HARD_I2C)
+ /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
+ /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
+#else /* normal I/O port pins */
+ /* PD15 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SDA */
+ /* PD14 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SCL */
+#endif
+#endif
+ /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
+ /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
+ /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
+ /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
+ /* PD9 */ { 0, 1, 0, 1, 0, 0 }, /* PD9 */
+ /* PD8 */ { 0, 1, 0, 0, 0, 0 }, /* PD8 */
+ /* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
+ /* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
+ /* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */
+ /* PD4 */ { 1, 1, 1, 0, 0, 0 }, /* SMC2 RXD */
+ /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
+ }
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* Check Board Identity:
+ */
+int checkboard (void)
+{
+ puts ("Board: PM828\n");
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+/* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
+ *
+ * This routine performs standard 8260 initialization sequence
+ * and calculates the available memory size. It may be called
+ * several times to try different SDRAM configurations on both
+ * 60x and local buses.
+ */
+static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
+ ulong orx, volatile uchar * base)
+{
+ volatile uchar c = 0xff;
+ volatile ulong cnt, val;
+ volatile ulong *addr;
+ volatile uint *sdmr_ptr;
+ volatile uint *orx_ptr;
+ int i;
+ ulong save[32]; /* to make test non-destructive */
+ ulong maxsize;
+
+ /* We must be able to test a location outsize the maximum legal size
+ * to find out THAT we are outside; but this address still has to be
+ * mapped by the controller. That means, that the initial mapping has
+ * to be (at least) twice as large as the maximum expected size.
+ */
+ maxsize = (1 + (~orx | 0x7fff)) / 2;
+
+ sdmr_ptr = &memctl->memc_psdmr;
+ orx_ptr = &memctl->memc_or2;
+
+ *orx_ptr = orx;
+
+ /*
+ * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
+ *
+ * "At system reset, initialization software must set up the
+ * programmable parameters in the memory controller banks registers
+ * (ORx, BRx, P/LSDMR). After all memory parameters are configured,
+ * system software should execute the following initialization sequence
+ * for each SDRAM device.
+ *
+ * 1. Issue a PRECHARGE-ALL-BANKS command
+ * 2. Issue eight CBR REFRESH commands
+ * 3. Issue a MODE-SET command to initialize the mode register
+ *
+ * The initial commands are executed by setting P/LSDMR[OP] and
+ * accessing the SDRAM with a single-byte transaction."
+ *
+ * The appropriate BRx/ORx registers have already been set when we
+ * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
+ */
+
+ *sdmr_ptr = sdmr | PSDMR_OP_PREA;
+ *base = c;
+
+ *sdmr_ptr = sdmr | PSDMR_OP_CBRR;
+ for (i = 0; i < 8; i++)
+ *base = c;
+
+ *sdmr_ptr = sdmr | PSDMR_OP_MRW;
+ *(base + CFG_MRS_OFFS) = c; /* setting MR on address lines */
+
+ *sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
+ *base = c;
+
+ /*
+ * 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
+ */
+ i = 0;
+ for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+ addr = (volatile ulong *) base + cnt; /* pointer arith! */
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *) base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+ addr = (volatile ulong *) base + cnt; /* pointer arith! */
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ /* Write the actual size to ORx
+ */
+ *orx_ptr = orx | ~(cnt * sizeof (long) - 1);
+ return (cnt * sizeof (long));
+ }
+ }
+ return (maxsize);
+}
+
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+
+#ifndef CFG_RAMBOOT
+ ulong size8, size9;
+#endif
+ ulong psize = 32 * 1024 * 1024;
+
+ memctl->memc_psrt = CFG_PSRT;
+ memctl->memc_mptpr = CFG_MPTPR;
+
+#ifndef CFG_RAMBOOT
+ size8 = try_init (memctl, CFG_PSDMR_8COL, CFG_OR2_8COL,
+ (uchar *) CFG_SDRAM_BASE);
+ size9 = try_init (memctl, CFG_PSDMR_9COL, CFG_OR2_9COL,
+ (uchar *) CFG_SDRAM_BASE);
+
+ if (size8 < size9) {
+ psize = size9;
+ printf ("(60x:9COL) ");
+ } else {
+ psize = try_init (memctl, CFG_PSDMR_8COL, CFG_OR2_8COL,
+ (uchar *) CFG_SDRAM_BASE);
+ printf ("(60x:8COL) ");
+ }
+#endif
+ return (psize);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_DOC)
+extern void doc_probe (ulong physadr);
+void doc_init (void)
+{
+ doc_probe (CFG_DOC_BASE);
+}
+#endif
+
+#ifdef CONFIG_PCI
+struct pci_controller hose;
+
+extern void pci_mpc8250_init(struct pci_controller *);
+
+void pci_init_board(void)
+{
+ pci_mpc8250_init(&hose);
+}
+#endif
diff --git a/board/pm828/u-boot.lds b/board/pm828/u-boot.lds
new file mode 100644
index 0000000..e191370
--- /dev/null
+++ b/board/pm828/u-boot.lds
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2001-2004
+ * 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/mpc8260/start.o (.text)
+ *(.text)
+ common/environment.o(.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/board/sx1/platform.S b/board/sx1/platform.S
index 3048128..bd54df1 100644
--- a/board/sx1/platform.S
+++ b/board/sx1/platform.S
@@ -118,30 +118,21 @@
str r1, [r0] /* EMIFS GlB Configuration. (value 0x12 most likely) */
ldr r0, _GPIO_PIN_CONTROL_REG
- ldrh r1,[r0]
+ mov r1,#0
orr r1, r1, #0x0001 /* M_PCM_SYNC */
orr r1, r1, #0x4000 /* IPC_ACTIVE */
- orr r1, r1, #0x0002 /* A_IRDA_OFF */
- orr r1, r1, #0x0800 /* A_SWITCH */
- orr r1, r1, #0x8000 /* A_USB_ON */
strh r1,[r0]
ldr r0, _GPIO_DIR_CONTROL_REG
- ldrh r1,[r0]
+ mov r1,#0
bic r1, r1, #0x0001 /* M_PCM_SYNC */
bic r1, r1, #0x4000 /* IPC_ACTIVE */
- bic r1, r1, #0x0002 /* A_IRDA_OFF */
- bic r1, r1, #0x0800 /* A_SWITCH */
- bic r1, r1, #0x8000 /* A_USB_ON */
strh r1,[r0]
ldr r0, _GPIO_DATA_OUTPUT_REG
- ldrh r1,[r0]
+ mov r1,#0
bic r1, r1, #0x0001 /* M_PCM_SYNC */
orr r1, r1, #0x4000 /* IPC_ACTIVE */
- orr r1, r1, #0x0002 /* A_IRDA_OFF */
- bic r1, r1, #0x0800 /* A_SWITCH */
- bic r1, r1, #0x8000 /* A_USB_ON */
strh r1,[r0]
/* Setup some clock domains */
diff --git a/board/trab/flash.c b/board/trab/flash.c
index 764c57b..2cccee6 100644
--- a/board/trab/flash.c
+++ b/board/trab/flash.c
@@ -83,6 +83,7 @@
switch (info->flash_id & FLASH_TYPEMASK) {
case (FLASH_AM320B & FLASH_TYPEMASK):
+ case (FLASH_MXLV320B & FLASH_TYPEMASK):
/* Boot sector type: 8 x 8 + N x 128 kB */
flashbase += (j < 8) ? 0x4000 : 0x20000;
break;
@@ -130,6 +131,8 @@
printf ("AMD "); break;
case (FLASH_MAN_FUJ & FLASH_VENDMASK):
printf ("FUJITSU "); break;
+ case (FLASH_MAN_MX & FLASH_VENDMASK):
+ printf ("MACRONIX "); break;
default: printf ("Unknown Vendor "); break;
}
@@ -137,6 +140,9 @@
case (FLASH_AM320B & FLASH_TYPEMASK):
printf ("2x Am29LV320DB (32Mbit)\n");
break;
+ case (FLASH_MXLV320B & FLASH_TYPEMASK):
+ printf ("2x MX29LV320DB (32Mbit)\n");
+ break;
case (FLASH_AM640U & FLASH_TYPEMASK):
printf ("2x Am29LV640D (64Mbit)\n");
break;
@@ -191,6 +197,7 @@
switch (info->flash_id & FLASH_VENDMASK) {
case (FLASH_MAN_AMD & FLASH_VENDMASK): break; /* OK */
case (FLASH_MAN_FUJ & FLASH_VENDMASK): break; /* OK */
+ case (FLASH_MAN_MX & FLASH_VENDMASK): break; /* OK */
default:
debug ("## flash_erase: unknown manufacturer\n");
return (ERR_UNKNOWN_FLASH_VENDOR);
@@ -502,6 +509,9 @@
case FUJ_MANUFACT:
info->flash_id = FLASH_MAN_FUJ;
break;
+ case MX_MANUFACT:
+ info->flash_id = FLASH_MAN_MX;
+ break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
@@ -532,6 +542,14 @@
addr[0] = 0x00F000F0; /* restore read mode */
break; /* => 16 MB */
+ case MX_ID_LV320B:
+ info->flash_id += FLASH_MXLV320B;
+ info->sector_count = 71;
+ info->size = 0x00800000;
+
+ addr[0] = 0x00FF00FF; /* restore read mode */
+ break; /* => 8 MB */
+
default:
debug ("## flash_init: unknown flash chip\n");
info->flash_id = FLASH_UNKNOWN;
diff --git a/board/xm250/Makefile b/board/xm250/Makefile
new file mode 100644
index 0000000..3572f72
--- /dev/null
+++ b/board/xm250/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2000-2004
+# 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 := xm250.o flash.o
+SOBJS := memsetup.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $^
+
+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/xm250/config.mk b/board/xm250/config.mk
new file mode 100644
index 0000000..8ce0c48
--- /dev/null
+++ b/board/xm250/config.mk
@@ -0,0 +1,35 @@
+#
+# (C) Copyright 2003-2004
+# 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
+#
+
+#
+# MicroSys XM250 board:
+#
+
+
+# This is the address where U-Boot lives in flash:
+#TEXT_BASE = 0
+
+# FIXME: armboot does only work correctly when being compiled
+# for the addresses _after_ relocation to RAM!! Otherwhise the
+# .bss segment is assumed in flash...
+TEXT_BASE = 0xA3F80000
diff --git a/board/xm250/flash.c b/board/xm250/flash.c
new file mode 100644
index 0000000..aab47a0
--- /dev/null
+++ b/board/xm250/flash.c
@@ -0,0 +1,536 @@
+/*
+ * (C) Copyright 2001
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2001-2004
+ * 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 <linux/byteorder/swab.h>
+
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/* Board support for 1 or 2 flash devices */
+#define FLASH_PORT_WIDTH32
+#undef FLASH_PORT_WIDTH16
+
+#ifdef FLASH_PORT_WIDTH16
+#define FLASH_PORT_WIDTH ushort
+#define FLASH_PORT_WIDTHV vu_short
+#define SWAP(x) __swab16(x)
+#else
+#define FLASH_PORT_WIDTH ulong
+#define FLASH_PORT_WIDTHV vu_long
+#define SWAP(x) __swab32(x)
+#endif
+
+/* Intel-compatible flash ID */
+#define INTEL_COMPAT 0x00890089
+#define INTEL_ALT 0x00B000B0
+
+/* Intel-compatible flash commands */
+#define INTEL_PROGRAM 0x00100010
+#define INTEL_ERASE 0x00200020
+#define INTEL_CLEAR 0x00500050
+#define INTEL_LOCKBIT 0x00600060
+#define INTEL_PROTECT 0x00010001
+#define INTEL_STATUS 0x00700070
+#define INTEL_READID 0x00900090
+#define INTEL_CONFIRM 0x00D000D0
+#define INTEL_RESET 0xFFFFFFFF
+
+/* Intel-compatible flash status bits */
+#define INTEL_FINISHED 0x00800080
+#define INTEL_OK 0x00800080
+
+#define FPW FLASH_PORT_WIDTH
+#define FPWV FLASH_PORT_WIDTHV
+
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (FPW *addr, flash_info_t *info);
+static int write_data (flash_info_t *info, ulong dest, FPW data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+void inline spin_wheel (void);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ int i;
+ ulong size = 0;
+
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+ switch (i) {
+ case 0:
+ flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
+ flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
+ break;
+ case 1:
+ flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
+ flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
+ break;
+ default:
+ panic ("configured to many flash banks!\n");
+ break;
+ }
+ size += flash_info[i].size;
+ }
+
+ /* Protect monitor and environment sectors
+ */
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_FLASH_BASE,
+ CFG_FLASH_BASE + monitor_flash_len - 1,
+ &flash_info[0] );
+
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+ for (i = 0; i < info->sector_count; i++) {
+ info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
+ info->protect[i] = 0;
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------
+ */
+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_INTEL:
+ printf ("INTEL ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F128J3A:
+ printf ("28F128J3A\n");
+ break;
+
+ case FLASH_28F640J3A:
+ printf ("28F640J3A\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 (FPW *addr, flash_info_t *info)
+{
+ volatile FPW value;
+
+ /* Write auto select command: read Manufacturer ID */
+ addr[0x5555] = (FPW) 0x00AA00AA;
+ addr[0x2AAA] = (FPW) 0x00550055;
+ addr[0x5555] = (FPW) 0x00900090;
+
+ mb ();
+ value = addr[0];
+
+ switch (value) {
+
+ case (FPW) INTEL_MANUFACT:
+ info->flash_id = FLASH_MAN_INTEL;
+ break;
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
+ return (0); /* no or unknown flash */
+ }
+
+ mb ();
+ value = addr[1]; /* device ID */
+
+ switch (value) {
+
+ case (FPW) INTEL_ID_28F128J3A:
+ info->flash_id += FLASH_28F128J3A;
+ info->sector_count = 128;
+ info->size = 0x02000000;
+ break; /* => 32 MB */
+
+ case (FPW) INTEL_ID_28F640J3A:
+ info->flash_id += FLASH_28F640J3A;
+ info->sector_count = 64;
+ info->size = 0x01000000;
+ break; /* => 16 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ break;
+ }
+
+ if (info->sector_count > CFG_MAX_FLASH_SECT) {
+ printf ("** ERROR: sector count %d > max (%d) **\n",
+ info->sector_count, CFG_MAX_FLASH_SECT);
+ info->sector_count = CFG_MAX_FLASH_SECT;
+ }
+
+ addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
+
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ int flag, prot, sect;
+ ulong type, start, 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;
+ }
+
+ type = (info->flash_id & FLASH_VENDMASK);
+ if ((type != FLASH_MAN_INTEL)) {
+ 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");
+ }
+
+ start = get_timer (0);
+ last = start;
+
+ /* 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 */
+ FPWV *addr = (FPWV *) (info->start[sect]);
+ FPW status;
+
+ printf ("Erasing sector %2d ... ", sect);
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ *addr = (FPW) 0x00500050; /* clear status register */
+ *addr = (FPW) 0x00200020; /* erase setup */
+ *addr = (FPW) 0x00D000D0; /* erase confirm */
+
+ while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
+ if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ *addr = (FPW) 0x00B000B0; /* suspend erase */
+ *addr = (FPW) 0x00FF00FF; /* reset to read mode */
+ rcode = 1;
+ break;
+ }
+ }
+
+ *addr = 0x00500050; /* clear status register cmd. */
+ *addr = 0x00FF00FF; /* resest to read mode */
+
+ printf (" done\n");
+ }
+ }
+ return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - Flash not identified
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp;
+ FPW data;
+ int count, i, l, rc, port_width;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ return 4;
+ }
+/* get lower word aligned address */
+#ifdef FLASH_PORT_WIDTH16
+ wp = (addr & ~1);
+ port_width = 2;
+#else
+ wp = (addr & ~3);
+ port_width = 4;
+#endif
+
+ /*
+ * 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 < port_width && cnt > 0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt == 0 && i < port_width; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+ return (rc);
+ }
+ wp += port_width;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ count = 0;
+ while (cnt >= port_width) {
+ data = 0;
+ for (i = 0; i < port_width; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_data (info, wp, SWAP (data))) != 0) {
+ return (rc);
+ }
+ wp += port_width;
+ cnt -= port_width;
+ if (count++ > 0x800) {
+ spin_wheel ();
+ count = 0;
+ }
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i < port_width; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ return (write_data (info, wp, SWAP (data)));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word or halfword to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_data (flash_info_t *info, ulong dest, FPW data)
+{
+ FPWV *addr = (FPWV *) dest;
+ ulong status;
+ int flag;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*addr & data) != data) {
+ printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts ();
+
+ *addr = (FPW) 0x00400040; /* write setup */
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ /* wait while polling the status register */
+ while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
+ if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
+ *addr = (FPW) 0x00FF00FF; /* restore read mode */
+ return (1);
+ }
+ }
+
+ *addr = (FPW) 0x00FF00FF; /* restore read mode */
+
+ return (0);
+}
+
+void inline spin_wheel (void)
+{
+ static int p = 0;
+ static char w[] = "\\/-";
+
+ printf ("\010%c", w[p]);
+ (++p == 3) ? (p = 0) : 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Set/Clear sector's lock bit, returns:
+ * 0 - OK
+ * 1 - Error (timeout, voltage problems, etc.)
+ */
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+ int i;
+ int rc = 0;
+ vu_long *addr = (vu_long *)(info->start[sector]);
+ int flag = disable_interrupts();
+
+ *addr = INTEL_CLEAR; /* Clear status register */
+ if (prot) { /* Set sector lock bit */
+ *addr = INTEL_LOCKBIT; /* Sector lock bit */
+ *addr = INTEL_PROTECT; /* set */
+ }
+ else { /* Clear sector lock bit */
+ *addr = INTEL_LOCKBIT; /* All sectors lock bits */
+ *addr = INTEL_CONFIRM; /* clear */
+ }
+
+ reset_timer_masked ();
+
+ while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
+ if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT) {
+ printf("Flash lock bit operation timed out\n");
+ rc = 1;
+ break;
+ }
+ }
+
+ if (*addr != INTEL_OK) {
+ printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
+ (uint)addr, (uint)*addr);
+ rc = 1;
+ }
+
+ if (!rc)
+ info->protect[sector] = prot;
+
+ /*
+ * Clear lock bit command clears all sectors lock bits, so
+ * we have to restore lock bits of protected sectors.
+ */
+ if (!prot)
+ {
+ for (i = 0; i < info->sector_count; i++)
+ {
+ if (info->protect[i])
+ {
+ reset_timer_masked ();
+ addr = (vu_long *)(info->start[i]);
+ *addr = INTEL_LOCKBIT; /* Sector lock bit */
+ *addr = INTEL_PROTECT; /* set */
+ while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
+ {
+ if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT)
+ {
+ printf("Flash lock bit operation timed out\n");
+ rc = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ *addr = INTEL_RESET; /* Reset to read array mode */
+
+ return rc;
+}
diff --git a/board/xm250/memsetup.S b/board/xm250/memsetup.S
new file mode 100644
index 0000000..f68e843
--- /dev/null
+++ b/board/xm250/memsetup.S
@@ -0,0 +1,519 @@
+/*
+ * Most of this taken from Redboot hal_platform_setup.h with cleanup
+ *
+ * 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
+/*
+ .macro SET_LED val
+ ldr r6, =CRADLE_LED_CLR_REG
+ ldr r7, =0
+ str r7, [r6]
+ ldr r6, =CRADLE_LED_SET_REG
+ ldr r7, =\val
+ str r7, [r6]
+ .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, =GRER0
+ ldr r1, =CFG_GRER0_VAL
+ str r1, [r0]
+
+ ldr r0, =GRER1
+ ldr r1, =CFG_GRER1_VAL
+ str r1, [r0]
+
+ ldr r0, =GRER2
+ ldr r1, =CFG_GRER2_VAL
+ str r1, [r0]
+
+ ldr r0, =GFER0
+ ldr r1, =CFG_GFER0_VAL
+ str r1, [r0]
+
+ ldr r0, =GFER1
+ ldr r1, =CFG_GFER1_VAL
+ str r1, [r0]
+
+ ldr r0, =GFER2
+ ldr r1, =CFG_GFER2_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]
+
+ /* SET_LED 1 */
+
+ 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) */
+
+
+/*********************************************************************
+ * Initlialize Memory Controller
+ *
+ * See PXA250 Operating System Developer's Guide
+ *
+ * pause for 200 uSecs- allow internal clocks to settle
+ * *Note: only need this if hard reset... doing it anyway for now
+ */
+
+ @ Step 1
+ @ ---- 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
+
+ /* SET_LED 2 */
+
+mem_init:
+ @ get memory controller base address
+ ldr r1, =MEMC_BASE
+
+
+@****************************************************************************
+@ Step 2
+@
+
+ @ Step 2a
+ @ 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]
+
+ @ Step 2b
+ @ 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]
+
+ /*SET_LED 3 */
+
+ @ Step 2c
+ @ fly-by-dma is defeatured on this part
+ @ write flycnfg
+ @ldr r2, =CFG_FLYCNFG_VAL
+ @str r2, [r1, #FLYCNFG_OFFSET]
+
+/* FIXME Does this sequence really make sense */
+#ifdef REDBOOT_WAY
+ @ Step 2d
+ @ get the mdrefr settings
+ ldr r3, =CFG_MDREFR_VAL
+
+ @ 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 *
+
+ /*SET_LED 4 */
+
+@****************************************************************************
+@ Step 3
+@
+@ NO SRAM
+
+ mov pc, r10
+
+
+@****************************************************************************
+@ Step 4
+@
+
+ @ 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 K0RUN for CPLD clock
+ @
+ orr r4, r4, #0x00002000
+
+ @ set K1RUN if bank 0 installed
+ @
+ orr r4, r4, #0x00010000
+
+ @ 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
+#else
+ @ Step 2d
+ @ get the mdrefr settings
+ ldr r4, =CFG_MDREFR_VAL
+
+ @ write back mdrefr
+ @
+ str r4, [r1, #MDREFR_OFFSET]
+
+ @ Step 4
+
+ @ set K0RUN for FLASH clock
+ @
+ orr r4, r4, #0x00002000
+
+ @ set K1RUN for bank DRAM 0
+ @
+ orr r4, r4, #0x00010000
+
+ @ set K2RUN for bank PLD
+ @
+ orr r4, r4, #0x00040000
+
+ @ 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
+#endif
+
+ @ Step 4d
+ @ 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 4e
+ @ 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
+
+ /*SET_LED 5 */
+
+ /* Why is this here??? */
+ mov r0, #0x78 @turn everything off
+ mcr p15, 0, r0, c1, c0, 0 @(caches off, MMU off, etc.)
+
+ @ Step 4f
+ @ 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 4g
+ @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 4h
+ @ write mdmrs
+ @
+ ldr r2, =CFG_MDMRS_VAL
+ str r2, [r1, #MDMRS_OFFSET]
+
+ @ Done Memory Init
+
+ /*SET_LED 6 */
+
+ @********************************************************************
+ @ 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]
+
+ @ Set interrupt mask register
+ @
+ ldr r1, =CFG_ICMR_VAL
+ ldr r2, =ICMR
+ str r1, [r2]
+
+ @ ********************************************************************
+ @ Disable the peripheral clocks, and set the core clock
+ @
+
+ @ Turn Off ALL on-chip peripheral clocks for re-configuration
+ @
+ ldr r1, =CKEN
+ mov r2, #0
+ str r2, [r1]
+
+ @ set core clocks
+ @
+ ldr r2, =CFG_CCCR_VAL
+ ldr r1, =CCCR
+ str r2, [r1]
+
+#ifdef ENABLE32KHZ
+ @ 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
+#endif
+
+ @ Turn on needed clocks
+ @
+ ldr r1, =CKEN
+ ldr r2, =CFG_CKEN_VAL
+ str r2, [r1]
+
+ /*SET_LED 7 */
+
+/* Is this needed???? */
+#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
+
+ /*SET_LED 8 */
+
+ mov pc, r10
+
+@ End memsetup
diff --git a/board/xm250/u-boot.lds b/board/xm250/u-boot.lds
new file mode 100644
index 0000000..e0b0514
--- /dev/null
+++ b/board/xm250/u-boot.lds
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2000-2004
+ * 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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/pxa/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+}
diff --git a/board/xm250/xm250.c b/board/xm250/xm250.c
new file mode 100644
index 0000000..2a4348d
--- /dev/null
+++ b/board/xm250/xm250.c
@@ -0,0 +1,91 @@
+/*
+ * (C) Copyright 2002
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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 <asm/arch/pxa-regs.h>
+#include <common.h>
+
+/* ------------------------------------------------------------------------- */
+
+/* local prototypes */
+
+inline void sleep (int i);
+
+inline void
+/**********************************************************/
+sleep (int i)
+/**********************************************************/
+{
+ while (i--) {
+ udelay (1000000);
+ }
+}
+
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+int
+/**********************************************************/
+board_post_init (void)
+/**********************************************************/
+{
+ return (0);
+}
+
+int
+/**********************************************************/
+board_init (void)
+/**********************************************************/
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ /* arch number of MicroSys XM250 */
+ gd->bd->bi_arch_number = 444;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0xa0000100;
+
+ return 0;
+}
+
+int
+/**********************************************************/
+dram_init (void)
+/**********************************************************/
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+ gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
+ gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
+ gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
+ gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
+
+ return (0);
+}