summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/gcplus/Makefile49
-rw-r--r--board/gcplus/config.mk13
-rw-r--r--board/gcplus/flash.c440
-rw-r--r--board/gcplus/gcplus.c73
-rw-r--r--board/gcplus/memsetup.S77
-rw-r--r--board/gcplus/u-boot.lds57
6 files changed, 709 insertions, 0 deletions
diff --git a/board/gcplus/Makefile b/board/gcplus/Makefile
new file mode 100644
index 0000000..d0f7d1c
--- /dev/null
+++ b/board/gcplus/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# 2003 (c) MontaVista Software, Inc.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS := gcplus.o flash.o
+SOBJS := memsetup.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+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/gcplus/config.mk b/board/gcplus/config.mk
new file mode 100644
index 0000000..57326b8
--- /dev/null
+++ b/board/gcplus/config.mk
@@ -0,0 +1,13 @@
+#
+# ADS GCPlus board with SA1110 cpu
+#
+# The ADS GCPlus has 2 banks of 16 MiB SDRAM
+#
+# We use the ADS GCPlus Linux boot ROM to load U-Boot into SDRAM
+# at c020'0000 and then move ourself to c8f0'0000. Basically, just
+# install the U-Boot binary as you would the Linux zImage and then
+# reap the benfits of more convenient Linux development cycles, i.e.
+# bootp;tftp;bootm, repeat, etc.,.
+#
+
+TEXT_BASE = 0xc8f00000
diff --git a/board/gcplus/flash.c b/board/gcplus/flash.c
new file mode 100644
index 0000000..5455656
--- /dev/null
+++ b/board/gcplus/flash.c
@@ -0,0 +1,440 @@
+/*
+ * (C) Copyright 2001
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 2003 (c) MontaVista Software, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#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
+
+#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;
+ default:
+ panic("configured too 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_28F640J5:
+ printf("28F640J5\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; /* => 16 MB */
+ case (FPW) INTEL_ID_28F640J5:
+ info->flash_id += FLASH_28F640J5;
+ 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 = (FPW) 0x00500050; /* clear status register cmd. */
+ *addr = (FPW) 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 (%x)\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;
+}
diff --git a/board/gcplus/gcplus.c b/board/gcplus/gcplus.c
new file mode 100644
index 0000000..06b6098
--- /dev/null
+++ b/board/gcplus/gcplus.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * 2003-2004 (c) MontaVista Software, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <SA-1100.h>
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+int
+board_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->bd->bi_arch_number = 29; /* ADS GraphicsClientPlus Board */
+
+ gd->bd->bi_boot_params = 0xc000003c; /* Weird address? */
+
+ /* Most of the ADS GCPlus I/O is connected to Static nCS2.
+ * So I'm brute forcing nCS2 timiming here for worst case.
+ */
+ MSC1 &= ~0xFFFF;
+ MSC1 |= 0x8649;
+
+ /* Nothing is connected to Static nCS4 or nCS5. But I'm using
+ * nCS4 as a paranoia safe guard to force nCS2, nOE; nWE high
+ * after accessing I/O via (non-VLIO) nCS2. What can I say, I'm
+ * paranoid and lack decent tools to alleviate my fear. I sure
+ * do wish I had a logic analyzer. : (
+ */
+
+ MSC2 = 0xfff9fff9;
+
+ 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;
+
+ return (0);
+}
diff --git a/board/gcplus/memsetup.S b/board/gcplus/memsetup.S
new file mode 100644
index 0000000..02f5685
--- /dev/null
+++ b/board/gcplus/memsetup.S
@@ -0,0 +1,77 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ * 2003-2004 (c) MontaVista Software, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include "config.h"
+#include "version.h"
+
+
+ .globl memsetup
+memsetup:
+ /* The ADS GC+ for Linux Boot Rom Ver. 1.73 does memory init for us.
+ * However the darn thing leaves the MMU enabled before handing control
+ * over to us. So we need to disable the MMU and we use memsetup
+ * to do it.
+ */
+
+@ The following code segment was borrowed with gratitude from:
+@ linux-2.4.19-rmk7/arch/arm/boot/compressed/head-sa1100.S
+
+ @ Data cache might be active.
+ @ Be sure to flush kernel binary out of the cache,
+ @ whatever state it is, before it is turned off.
+ @ This is done by fetching through currently executed
+ @ memory to be sure we hit the same cache.
+ bic r2, pc, #0x1f
+ add r3, r2, #0x4000 @ 16 kb is quite enough...
+1: ldr r0, [r2], #32
+ teq r2, r3
+ bne 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
+
+ @ disabling MMU and caches
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ bic r0, r0, #0x0d @ clear WB, DC, MMU
+ bic r0, r0, #0x1000 @ clear Icache
+ mcr p15, 0, r0, c1, c0, 0
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ b 2f
+2:
+ nop
+ nop
+ nop
+ nop
+ nop
+
+
+ mov pc, lr
diff --git a/board/gcplus/u-boot.lds b/board/gcplus/u-boot.lds
new file mode 100644
index 0000000..f625b48
--- /dev/null
+++ b/board/gcplus/u-boot.lds
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * 2003 (c) MontaVista Software, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/sa1100/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 = .;
+}