ppc4xx: Add NAND booting support for AMCC Acadia (405EZ) eval board

This patch adds NAND booting support for the AMCC Acadia eval board.

Please make sure to configure jumper J7 to position 2-3 when booting
from NOR, and to position 1-2 when booting for NAND.

I also added a board command to configure the I2C bootstrap EEPROM
values. Right now only 267MHz is support for booting either via NOR
or NAND FLASH. Here the usage:

=> bootstrap 267 nor	;to configure the board for 267MHz NOR booting
=> bootstrap 267 nand	;to configure the board for 267MHz NNAND booting

Signed-off-by: Stefan Roese <sr@denx.de>
diff --git a/MAKEALL b/MAKEALL
index 81f5dfc..67d39a7 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -75,22 +75,23 @@
 #########################################################################
 
 LIST_4xx="	\
-	acadia		ADCIOP		alpr		AP1000		\
-	AR405		ASH405		bamboo		bamboo_nand	\
-	bubinga		CANBT		CMS700		CPCI2DP		\
-	CPCI405		CPCI4052	CPCI405AB	CPCI405DT	\
-	CPCI440		CPCIISER4	CRAYL1		csb272		\
-	csb472		DASA_SIM	DP405		DU405		\
-	ebony		ERIC		EXBITGEN	G2000		\
-	HH405		HUB405		JSE		KAREF		\
-	katmai		luan		METROBOX	MIP405		\
-	MIP405T		ML2		ml300		ocotea		\
-	OCRTC		ORSG		p3p440		PCI405		\
-	pcs440ep	PIP405		PLU405		PMC405		\
-	PPChameleonEVB	sbc405		sc3		sequoia		\
-	sequoia_nand	taishan		VOH405		VOM405		\
-	W7OLMC		W7OLMG		walnut		WUH405		\
-	XPEDITE1K	yellowstone	yosemite	yucca		\
+	acadia		acadia_nand	ADCIOP		alpr		\
+	AP1000		AR405		ASH405		bamboo		\
+	bamboo_nand	bubinga		CANBT		CMS700		\
+	CPCI2DP		CPCI405		CPCI4052	CPCI405AB	\
+	CPCI405DT	CPCI440		CPCIISER4	CRAYL1		\
+	csb272		csb472		DASA_SIM	DP405		\
+	DU405		ebony		ERIC		EXBITGEN	\
+	G2000		HH405		HUB405		JSE		\
+	KAREF		katmai		luan		METROBOX	\
+	MIP405		MIP405T		ML2		ml300		\
+	ocotea		OCRTC		ORSG		p3p440		\
+	PCI405		pcs440ep	PIP405		PLU405		\
+	PMC405		PPChameleonEVB	sbc405		sc3		\
+	sequoia		sequoia_nand	taishan		VOH405		\
+	VOM405		W7OLMC		W7OLMG		walnut		\
+	WUH405		XPEDITE1K	yellowstone	yosemite	\
+	yucca								\
 "
 
 #########################################################################
diff --git a/Makefile b/Makefile
index 463757c..6b70dd5 100644
--- a/Makefile
+++ b/Makefile
@@ -1017,6 +1017,15 @@
 acadia_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx acadia amcc
 
+acadia_nand_config:	unconfig
+	@mkdir -p $(obj)include
+	@mkdir -p $(obj)nand_spl
+	@mkdir -p $(obj)board/amcc/acadia
+	@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
+	@$(MKCONFIG) -n $@ -a acadia ppc ppc4xx acadia amcc
+	@echo "TEXT_BASE = 0x01000000" > $(obj)board/amcc/acadia/config.tmp
+	@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
+
 ADCIOP_config:	unconfig
 	@$(MKCONFIG) $(@:_config=) ppc ppc4xx adciop esd
 
diff --git a/board/amcc/acadia/Makefile b/board/amcc/acadia/Makefile
index abcbf3e..ddbcb80 100644
--- a/board/amcc/acadia/Makefile
+++ b/board/amcc/acadia/Makefile
@@ -25,7 +25,7 @@
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	= $(BOARD).o cpr.o memory.o
+COBJS	= $(BOARD).o cmd_acadia.o cpr.o memory.o
 SOBJS	=
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/board/amcc/acadia/acadia.c b/board/amcc/acadia/acadia.c
index 3b63c8a..46d63e6 100644
--- a/board/amcc/acadia/acadia.c
+++ b/board/amcc/acadia/acadia.c
@@ -63,8 +63,14 @@
 	acadia_gpio_init();
 
 	/* Configure 405EZ for NAND usage */
-	mtsdr(sdrnand0, 0x80c00000);
-	mtsdr(sdrultra0, 0x8d110000);
+	mtsdr(sdrnand0, SDR_NAND0_NDEN | SDR_NAND0_NDAREN | SDR_NAND0_NDRBEN);
+	mfsdr(sdrultra0, reg);
+	reg &= ~SDR_ULTRA0_CSN_MASK;
+	reg |= (SDR_ULTRA0_CSNSEL0 >> CFG_NAND_CS) |
+		SDR_ULTRA0_NDGPIOBP |
+		SDR_ULTRA0_EBCRDYEN |
+		SDR_ULTRA0_NFSRSTEN;
+	mtsdr(sdrultra0, reg);
 
 	/* USB Host core needs this bit set */
 	mfsdr(sdrultra1, reg);
diff --git a/board/amcc/acadia/cmd_acadia.c b/board/amcc/acadia/cmd_acadia.c
new file mode 100644
index 0000000..fb7ea35
--- /dev/null
+++ b/board/amcc/acadia/cmd_acadia.c
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@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 <command.h>
+#include <i2c.h>
+
+static u8 boot_267_nor[] = {
+	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00,
+	0x14, 0xc0, 0x36, 0xcc, 0x00, 0x0c, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static u8 boot_267_nand[] = {
+	0xd0, 0x38, 0xc3, 0x50, 0x13, 0x88, 0x8e, 0x00,
+	0x14, 0xc0, 0x36, 0xcc, 0x00, 0x0c, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	u8 chip;
+	u8 *buf;
+	int cpu_freq;
+
+	if (argc < 3) {
+		printf("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	cpu_freq = simple_strtol(argv[1], NULL, 10);
+	if (cpu_freq != 267) {
+		printf("Unsupported cpu-frequency - only 267 supported\n");
+		return 1;
+	}
+
+	/* use 0x50 as I2C EEPROM address for now */
+	chip = 0x50;
+
+	if ((strcmp(argv[2], "nor") != 0) &&
+	    (strcmp(argv[2], "nand") != 0)) {
+		printf("Unsupported boot-device - only nor|nand support\n");
+		return 1;
+	}
+
+	if (strcmp(argv[2], "nand") == 0) {
+		switch (cpu_freq) {
+		case 267:
+			buf = boot_267_nand;
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (cpu_freq) {
+		case 267:
+			buf = boot_267_nor;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (i2c_write(chip, 0, 1, buf, 16) != 0)
+		printf("Error writing to EEPROM at address 0x%x\n", chip);
+	udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
+	if (i2c_write(chip, 0x10, 1, buf+16, 4) != 0)
+		printf("Error2 writing to EEPROM at address 0x%x\n", chip);
+
+	printf("Done\n");
+	printf("Please power-cycle the board for the changes to take effect\n");
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	bootstrap,	3,	0,	do_bootstrap,
+	"bootstrap - program the I2C bootstrap EEPROM\n",
+	"<cpu-freq> <nor|nand> - program the I2C bootstrap EEPROM\n"
+	);
diff --git a/board/amcc/acadia/config.mk b/board/amcc/acadia/config.mk
index c8566ec..af5a46c 100644
--- a/board/amcc/acadia/config.mk
+++ b/board/amcc/acadia/config.mk
@@ -21,6 +21,12 @@
 # MA 02111-1307 USA
 #
 
+#
+# AMCC 405EZ Reference Platform (Acadia) board
+#
+
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+
 ifndef TEXT_BASE
 TEXT_BASE = 0xFFFC0000
 endif
diff --git a/board/amcc/acadia/memory.c b/board/amcc/acadia/memory.c
index 5375d36..25904d3 100644
--- a/board/amcc/acadia/memory.c
+++ b/board/amcc/acadia/memory.c
@@ -39,6 +39,7 @@
 	return;
 }
 
+#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
 static void cram_bcr_write(u32 wr_val)
 {
 	wr_val <<= 2;
@@ -62,9 +63,12 @@
 
 	return;
 }
+#endif
 
 long int initdram(int board_type)
 {
+#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
+	int i;
 	u32 val;
 
 	/* 1. EBC need to program READY, CLK, ADV for ASync mode */
@@ -92,7 +96,12 @@
 
 	/* Config EBC to use RDY */
 	mfsdr(sdrultra0, val);
-	mtsdr(sdrultra0, val | 0x04000000);
+	mtsdr(sdrultra0, val | SDR_ULTRA0_EBCRDYEN);
+
+	/* Wait a short while, since for NAND booting this is too fast */
+	for (i=0; i<200000; i++)
+		;
+#endif
 
 	return (CFG_MBYTES_RAM << 20);
 }
diff --git a/board/amcc/acadia/u-boot-nand.lds b/board/amcc/acadia/u-boot-nand.lds
new file mode 100644
index 0000000..a5dae0e
--- /dev/null
+++ b/board/amcc/acadia/u-boot-nand.lds
@@ -0,0 +1,137 @@
+/*
+ * (C) Copyright 2007
+ * 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);
+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      :
+  {
+    /* WARNING - the following is hand-optimized to fit within	*/
+    /* the sector layout of our flash chips!	XXX FIXME XXX	*/
+
+    cpu/ppc4xx/start.o	(.text)
+
+    /* Align to next NAND block */
+    . = ALIGN(0x4000);
+    common/environment.o  (.ppcenv)
+    /* Keep some space here for redundant env and potential bad env blocks */
+    . = ALIGN(0x10000);
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _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(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 78de300..78d0042 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -155,7 +155,9 @@
 	 * NAND U-Boot image is started from offset 0
 	 */
 	.text
+#if defined(CONFIG_440)
 	bl	reconfig_tlb0
+#endif
 	GET_GOT
 	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
 	bl	board_init_f
@@ -857,6 +859,38 @@
 #endif /* CONFIG_405EZ */
 #endif
 
+#ifdef CONFIG_NAND_SPL
+	/*
+	 * Copy SPL from cache into internal SRAM
+	 */
+	li	r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
+	mtctr	r4
+	lis	r2,CFG_NAND_BOOT_SPL_SRC@h
+	ori	r2,r2,CFG_NAND_BOOT_SPL_SRC@l
+	lis	r3,CFG_NAND_BOOT_SPL_DST@h
+	ori	r3,r3,CFG_NAND_BOOT_SPL_DST@l
+spl_loop:
+	lwzu	r4,4(r2)
+	stwu	r4,4(r3)
+	bdnz	spl_loop
+
+	/*
+	 * Jump to code in RAM
+	 */
+	bl	00f
+00:	mflr	r10
+	lis	r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
+	ori	r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
+	sub	r10,r10,r3
+	addi	r10,r10,28
+	mtlr	r10
+	blr
+
+start_ram:
+	sync
+	isync
+#endif /* CONFIG_NAND_SPL */
+
 	/*----------------------------------------------------------------------- */
 	/* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
 	/*----------------------------------------------------------------------- */
@@ -967,12 +1001,16 @@
 	stw	r0, +12(r1)		/* Save return addr (underflow vect) */
 #endif /* !(CFG_INIT_DCACHE_CS	|| !CFG_TEM_STACK_OCM) */
 
+#ifdef CONFIG_NAND_SPL
+	bl	nand_boot		/* will not return */
+#else
 	GET_GOT			/* initialize GOT access			*/
 
 	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
 
 	/* NEVER RETURNS! */
 	bl	board_init_f	/* run first part of init code (from Flash)	*/
+#endif /* CONFIG_NAND_SPL */
 
 #endif	/* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
 	/*----------------------------------------------------------------------- */
@@ -1187,23 +1225,6 @@
 
 /* Cache functions.
 */
-invalidate_icache:
-	iccci	r0,r0			/* for 405, iccci invalidates the */
-	blr				/*   entire I cache */
-
-invalidate_dcache:
-	addi	r6,0,0x0000		/* clear GPR 6 */
-	/* Do loop for # of dcache congruence classes. */
-	lis	r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha	/* TBS for large sized cache */
-	ori	r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
-					/* NOTE: dccci invalidates both */
-	mtctr	r7			/* ways in the D cache */
-..dcloop:
-	dccci	0,r6			/* invalidate line */
-	addi	r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
-	bdnz	..dcloop
-	blr
-
 flush_dcache:
 	addis	r9,r0,0x0002		/* set mask for EE and CE msr bits */
 	ori	r9,r9,0x8000
@@ -1734,6 +1755,23 @@
 	lwz	3,0x0000(3)
 	blr
 
+invalidate_icache:
+	iccci	r0,r0			/* for 405, iccci invalidates the */
+	blr				/*   entire I cache */
+
+invalidate_dcache:
+	addi	r6,0,0x0000		/* clear GPR 6 */
+	/* Do loop for # of dcache congruence classes. */
+	lis	r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha	/* TBS for large sized cache */
+	ori	r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
+					/* NOTE: dccci invalidates both */
+	mtctr	r7			/* ways in the D cache */
+..dcloop:
+	dccci	0,r6			/* invalidate line */
+	addi	r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
+	bdnz	..dcloop
+	blr
+
 /**************************************************************************/
 /* PPC405EP specific stuff						  */
 /**************************************************************************/
diff --git a/include/configs/acadia.h b/include/configs/acadia.h
index c72d933..0f447b0 100644
--- a/include/configs/acadia.h
+++ b/include/configs/acadia.h
@@ -109,6 +109,7 @@
 /*-----------------------------------------------------------------------
  * FLASH related
  *----------------------------------------------------------------------*/
+#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
 #define CFG_FLASH_CFI			/* The flash is CFI compatible	*/
 #define CFG_FLASH_CFI_DRIVER		/* Use common CFI driver	*/
 
@@ -122,6 +123,12 @@
 #define CFG_FLASH_USE_BUFFER_WRITE 1	/* use buffered writes (20x faster)	*/
 #define CFG_FLASH_EMPTY_INFO		/* print 'E' for empty sector on flinfo */
 
+#define	_CFG_CMD_INCLUDE	(CFG_CMD_ALL)
+#else
+#define	CFG_NO_FLASH		1	/* No NOR on Acadia when NAND-booting	*/
+#define	_CFG_CMD_INCLUDE	((CFG_CMD_ALL) & ~(CFG_CMD_FLASH | CFG_CMD_IMLS))
+#endif
+
 #ifdef CFG_ENV_IS_IN_FLASH
 #define CFG_ENV_SECT_SIZE	0x40000 /* size of one complete sector	*/
 #define CFG_ENV_ADDR		(CFG_MONITOR_BASE-CFG_ENV_SECT_SIZE)
@@ -132,6 +139,63 @@
 #define CFG_ENV_SIZE_REDUND	(CFG_ENV_SIZE)
 #endif
 
+/*
+ * IPL (Initial Program Loader, integrated inside CPU)
+ * Will load first 4k from NAND (SPL) into cache and execute it from there.
+ *
+ * SPL (Secondary Program Loader)
+ * Will load special U-Boot version (NUB) from NAND and execute it. This SPL
+ * has to fit into 4kByte. It sets up the CPU and configures the SDRAM
+ * controller and the NAND controller so that the special U-Boot image can be
+ * loaded from NAND to SDRAM.
+ *
+ * NUB (NAND U-Boot)
+ * This NAND U-Boot (NUB) is a special U-Boot version which can be started
+ * from RAM. Therefore it mustn't (re-)configure the SDRAM controller.
+ *
+ * On 440EPx the SPL is copied to SDRAM before the NAND controller is
+ * set up. While still running from cache, I experienced problems accessing
+ * the NAND controller.	sr - 2006-08-25
+ */
+#define CFG_NAND_BOOT_SPL_SRC	0xfffff000	/* SPL location			*/
+#define CFG_NAND_BOOT_SPL_SIZE	(4 << 10)	/* SPL size			*/
+#define CFG_NAND_BOOT_SPL_DST	(CFG_OCM_DATA_ADDR + (12 << 10)) /* Copy SPL here*/
+#define CFG_NAND_U_BOOT_DST	0x01000000	/* Load NUB to this addr	*/
+#define CFG_NAND_U_BOOT_START	CFG_NAND_U_BOOT_DST /* Start NUB from this addr	*/
+#define CFG_NAND_BOOT_SPL_DELTA	(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)
+
+/*
+ * Define the partitioning of the NAND chip (only RAM U-Boot is needed here)
+ */
+#define CFG_NAND_U_BOOT_OFFS	(16 << 10)	/* Offset to RAM U-Boot image	*/
+#define CFG_NAND_U_BOOT_SIZE	(384 << 10)	/* Size of RAM U-Boot image	*/
+
+/*
+ * Now the NAND chip has to be defined (no autodetection used!)
+ */
+#define CFG_NAND_PAGE_SIZE	512		/* NAND chip page size		*/
+#define CFG_NAND_BLOCK_SIZE	(16 << 10)	/* NAND chip block size		*/
+#define CFG_NAND_PAGE_COUNT	32		/* NAND chip page count		*/
+#define CFG_NAND_BAD_BLOCK_POS	5		/* Location of bad block marker	*/
+#undef CFG_NAND_4_ADDR_CYCLE			/* No fourth addr used (<=32MB)	*/
+
+#define CFG_NAND_ECCSIZE	256
+#define CFG_NAND_ECCBYTES	3
+#define CFG_NAND_ECCSTEPS	(CFG_NAND_PAGE_SIZE / CFG_NAND_ECCSIZE)
+#define CFG_NAND_OOBSIZE	16
+#define CFG_NAND_ECCTOTAL	(CFG_NAND_ECCBYTES * CFG_NAND_ECCSTEPS)
+#define CFG_NAND_ECCPOS		{0, 1, 2, 3, 6, 7}
+
+#ifdef CFG_ENV_IS_IN_NAND
+/*
+ * For NAND booting the environment is embedded in the U-Boot image. Please take
+ * look at the file board/amcc/sequoia/u-boot-nand.lds for details.
+ */
+#define CFG_ENV_SIZE		CFG_NAND_BLOCK_SIZE
+#define CFG_ENV_OFFSET		(CFG_NAND_U_BOOT_OFFS + CFG_ENV_SIZE)
+#define CFG_ENV_OFFSET_REDUND	(CFG_ENV_OFFSET + CFG_ENV_SIZE)
+#endif
+
 /*-----------------------------------------------------------------------
  * RAM (CRAM)
  *----------------------------------------------------------------------*/
@@ -209,7 +273,11 @@
 	"update=protect off fffc0000 ffffffff;era fffc0000 ffffffff;"	\
 		"cp.b ${fileaddr} fffc0000 ${filesize};"		\
 		"setenv filesize;saveenv\0"				\
-	"upd=run load;run update\0"					\
+	"upd=run load update\0"						\
+	"nload=tftp 200000 acadia/u-boot-nand.bin\0"			\
+	"nupdate=nand erase 0 60000;nand write 200000 0 60000;"		\
+		"setenv filesize;saveenv\0"				\
+	"nupd=run nload nupdate\0"					\
 	"kozio=bootm ffc60000\0"					\
 	""
 #define CONFIG_BOOTCOMMAND	"run flash_self"
@@ -233,24 +301,24 @@
 
 #define CONFIG_SUPPORT_VFAT
 
-#define CONFIG_COMMANDS       (CONFIG_CMD_DFL	|	\
-			       CFG_CMD_ASKENV	|	\
-			       CFG_CMD_DHCP	|	\
-			       CFG_CMD_DTT	|	\
-			       CFG_CMD_DIAG	|	\
-			       CFG_CMD_EEPROM	|	\
-			       CFG_CMD_ELF	|	\
-			       CFG_CMD_FAT	|	\
-			       CFG_CMD_I2C	|	\
-			       CFG_CMD_IRQ	|	\
-			       CFG_CMD_MII	|	\
-			       CFG_CMD_NAND	|	\
-			       CFG_CMD_NET	|	\
-			       CFG_CMD_NFS	|	\
-			       CFG_CMD_PCI	|	\
-			       CFG_CMD_PING	|	\
-			       CFG_CMD_REGINFO	|	\
-			       CFG_CMD_USB)
+#define CONFIG_COMMANDS	((CONFIG_CMD_DFL & _CFG_CMD_INCLUDE)	|	\
+			 CFG_CMD_ASKENV	|				\
+			 CFG_CMD_DHCP	|				\
+			 CFG_CMD_DTT	|				\
+			 CFG_CMD_DIAG	|				\
+			 CFG_CMD_EEPROM	|				\
+			 CFG_CMD_ELF	|				\
+			 CFG_CMD_FAT	|				\
+			 CFG_CMD_I2C	|				\
+			 CFG_CMD_IRQ	|				\
+			 CFG_CMD_MII	|				\
+			 CFG_CMD_NAND	|				\
+			 CFG_CMD_NET	|				\
+			 CFG_CMD_NFS	|				\
+			 CFG_CMD_PCI	|				\
+			 CFG_CMD_PING	|				\
+			 CFG_CMD_REGINFO |				\
+			 CFG_CMD_USB)
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
@@ -312,12 +380,16 @@
 /*-----------------------------------------------------------------------
  * External Bus Controller (EBC) Setup
  *----------------------------------------------------------------------*/
-#define CFG_NAND_CS		3		/* NAND chip connected to CSx	*/
-
+#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+#define CFG_NAND_CS		3
 /* Memory Bank 0 (Flash) initialization						*/
 #define CFG_EBC_PB0AP		0x03337200
 #define CFG_EBC_PB0CR		0xfe0bc000
 
+/* Memory Bank 3 (NAND-FLASH) initialization					*/
+#define CFG_EBC_PB3AP		0x018003c0
+#define CFG_EBC_PB3CR		(CFG_NAND_ADDR | 0x1c000)
+
 /* Just initial configuration for CRAM. Will be changed in memory.c to sync mode*/
 /* Memory Bank 1 (CRAM) initialization						*/
 #define CFG_EBC_PB1AP		0x030400c0
@@ -326,10 +398,24 @@
 /* Memory Bank 2 (CRAM) initialization						*/
 #define CFG_EBC_PB2AP		0x030400c0
 #define CFG_EBC_PB2CR		0x020bc000
+#else
+#define CFG_NAND_CS		0		/* NAND chip connected to CSx	*/
+/* Memory Bank 0 (NAND-FLASH) initialization					*/
+#define CFG_EBC_PB0AP		0x018003c0
+#define CFG_EBC_PB0CR		(CFG_NAND_ADDR | 0x1c000)
 
-/* Memory Bank 3 (NAND-FLASH) initialization					*/
-#define CFG_EBC_PB3AP		0x018003c0
-#define CFG_EBC_PB3CR		(CFG_NAND_ADDR | 0x1c000)
+/*
+ * When NAND-booting the CRAM EBC setup must be done in sync mode, since the
+ * NAND-SPL already initialized the CRAM and EBC to sync mode.
+ */
+/* Memory Bank 1 (CRAM) initialization						*/
+#define CFG_EBC_PB1AP		0x9C0201C0
+#define CFG_EBC_PB1CR		0x000bc000
+
+/* Memory Bank 2 (CRAM) initialization						*/
+#define CFG_EBC_PB2AP		0x9C0201C0
+#define CFG_EBC_PB2CR		0x020bc000
+#endif
 
 /* Memory Bank 4 (CPLD) initialization						*/
 #define CFG_EBC_PB4AP		0x04006000
@@ -341,9 +427,9 @@
  * GPIO Setup
  *----------------------------------------------------------------------*/
 #define CFG_GPIO_CRAM_CLK	8
-#define CFG_GPIO_CRAM_WAIT	9
+#define CFG_GPIO_CRAM_WAIT	9		/* GPIO-In		*/
 #define CFG_GPIO_CRAM_ADV	10
-#define CFG_GPIO_CRAM_CRE	(32 + 21)
+#define CFG_GPIO_CRAM_CRE	(32 + 21)	/* GPIO-Out		*/
 
 /*-----------------------------------------------------------------------
  * Definitions for GPIO_0 setup (PPC405EZ specific)
@@ -365,10 +451,10 @@
  * GPIO0[28-30]	- Trace Outputs / PWM Inputs
  * GPIO0[31]	- PWM_8 I/O
  */
-#define CFG_GPIO0_TCR		0xC0000000
-#define CFG_GPIO0_OSRL		0x50000000
+#define CFG_GPIO0_TCR		0xC0A00000
+#define CFG_GPIO0_OSRL		0x50004400
 #define CFG_GPIO0_OSRH		0x02000055
-#define CFG_GPIO0_ISR1L		0x00000000
+#define CFG_GPIO0_ISR1L		0x00001000
 #define CFG_GPIO0_ISR1H		0x00000055
 #define CFG_GPIO0_TSRL		0x02000000
 #define CFG_GPIO0_TSRH		0x00000055
@@ -387,13 +473,13 @@
  * GPIO1[16]	- SPI_SS_1_N Output
  * GPIO1[17-20]	- Trace Output/External Interrupts IRQ0 - IRQ3 inputs
  */
-#define CFG_GPIO1_OSRH		0x55455555
+#define CFG_GPIO1_TCR		0xFFFF8414
 #define CFG_GPIO1_OSRL		0x40000110
-#define CFG_GPIO1_ISR1H		0x00000000
+#define CFG_GPIO1_OSRH		0x55455555
 #define CFG_GPIO1_ISR1L		0x15555445
-#define CFG_GPIO1_TSRH		0x00000000
+#define CFG_GPIO1_ISR1H		0x00000000
 #define CFG_GPIO1_TSRL		0x00000000
-#define CFG_GPIO1_TCR		0xFFFF8014
+#define CFG_GPIO1_TSRH		0x00000000
 
 /*
  * Internal Definitions
diff --git a/include/ppc405.h b/include/ppc405.h
index fffae4d..71ad12e 100644
--- a/include/ppc405.h
+++ b/include/ppc405.h
@@ -556,6 +556,11 @@
 #define sdricintstat	0x4510
 
 #define SDR_NAND0_NDEN		0x80000000
+#define SDR_NAND0_NDBTEN	0x40000000
+#define SDR_NAND0_NDBADR_MASK	0x30000000
+#define SDR_NAND0_NDBPG_MASK	0x0f000000
+#define SDR_NAND0_NDAREN	0x00800000
+#define SDR_NAND0_NDRBEN	0x00400000
 
 #define SDR_ULTRA0_NDGPIOBP	0x80000000
 #define SDR_ULTRA0_CSN_MASK	0x78000000
@@ -563,6 +568,9 @@
 #define SDR_ULTRA0_CSNSEL1	0x20000000
 #define SDR_ULTRA0_CSNSEL2	0x10000000
 #define SDR_ULTRA0_CSNSEL3	0x08000000
+#define SDR_ULTRA0_EBCRDYEN	0x04000000
+#define SDR_ULTRA0_SPISSINEN	0x02000000
+#define SDR_ULTRA0_NFSRSTEN	0x01000000
 
 #define SDR_ULTRA1_LEDNENABLE	0x40000000
 
diff --git a/nand_spl/board/amcc/acadia/Makefile b/nand_spl/board/amcc/acadia/Makefile
new file mode 100644
index 0000000..0d6828a
--- /dev/null
+++ b/nand_spl/board/amcc/acadia/Makefile
@@ -0,0 +1,104 @@
+#
+# (C) Copyright 2007
+# Stefan Roese, DENX Software Engineering, sr@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
+include $(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk
+
+LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds
+LDFLAGS	= -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
+AFLAGS	+= -DCONFIG_NAND_SPL
+CFLAGS	+= -DCONFIG_NAND_SPL
+
+SOBJS	= start.o resetvec.o
+COBJS	= gpio.o nand_boot.o nand_ecc.o memory.o ndfc.o
+
+SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+__OBJS	:= $(SOBJS) $(COBJS)
+LNDIR	:= $(OBJTREE)/nand_spl/board/$(BOARDDIR)
+
+nandobj	:= $(OBJTREE)/nand_spl/
+
+ALL	= $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin
+
+all:	$(obj).depend $(ALL)
+
+$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl
+	$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@
+
+$(nandobj)u-boot-spl.bin:	$(nandobj)u-boot-spl
+	$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+
+$(nandobj)u-boot-spl:	$(OBJS)
+	cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
+		-Map $(nandobj)u-boot-spl.map \
+		-o $(nandobj)u-boot-spl
+
+# create symbolic links for common files
+
+# from cpu directory
+$(obj)gpio.c:
+	@rm -f $(obj)gpio.c
+	ln -s $(SRCTREE)/cpu/ppc4xx/gpio.c $(obj)gpio.c
+
+$(obj)ndfc.c:
+	@rm -f $(obj)ndfc.c
+	ln -s $(SRCTREE)/cpu/ppc4xx/ndfc.c $(obj)ndfc.c
+
+$(obj)resetvec.S:
+	@rm -f $(obj)resetvec.S
+	ln -s $(SRCTREE)/cpu/ppc4xx/resetvec.S $(obj)resetvec.S
+
+$(obj)start.S:
+	@rm -f $(obj)start.S
+	ln -s $(SRCTREE)/cpu/ppc4xx/start.S $(obj)start.S
+
+# from board directory
+$(obj)memory.c:
+	@rm -f $(obj)memory.c
+	ln -s $(SRCTREE)/board/amcc/acadia/memory.c $(obj)memory.c
+
+# from nand_spl directory
+$(obj)nand_boot.c:
+	@rm -f $(obj)nand_boot.c
+	ln -s $(SRCTREE)/nand_spl/nand_boot.c $(obj)nand_boot.c
+
+# from drivers/nand directory
+$(obj)nand_ecc.c:
+	@rm -f $(obj)nand_ecc.c
+	ln -s $(SRCTREE)/drivers/nand/nand_ecc.c $(obj)nand_ecc.c
+
+#########################################################################
+
+$(obj)%.o:	$(obj)%.S
+	$(CC) $(AFLAGS) -c -o $@ $<
+
+$(obj)%.o:	$(obj)%.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/nand_spl/board/amcc/acadia/config.mk b/nand_spl/board/amcc/acadia/config.mk
new file mode 100644
index 0000000..55069b4
--- /dev/null
+++ b/nand_spl/board/amcc/acadia/config.mk
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2007
+# Stefan Roese, DENX Software Engineering, sr@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
+#
+#
+# AMCC 405EZ Reference Platform (Acadia) board
+#
+
+#
+# TEXT_BASE for SPL:
+#
+# On 4xx platforms the SPL is located at 0xfffff000...0xffffffff,
+# in the last 4kBytes of memory space in cache.
+# We will copy this SPL into internal SRAM in start.S. So we set
+# TEXT_BASE to starting address in internal SRAM here.
+#
+TEXT_BASE = 0xF8003000
+
+# PAD_TO used to generate a 16kByte binary needed for the combined image
+# -> PAD_TO = TEXT_BASE + 0x4000
+PAD_TO	= 0xF8007000
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
+
+ifeq ($(dbcr),1)
+PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
+endif
diff --git a/nand_spl/board/amcc/acadia/u-boot.lds b/nand_spl/board/amcc/acadia/u-boot.lds
new file mode 100644
index 0000000..018def1
--- /dev/null
+++ b/nand_spl/board/amcc/acadia/u-boot.lds
@@ -0,0 +1,63 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@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:common)
+SECTIONS
+{
+  .resetvec 0xF8003FFC :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  .text      :
+  {
+    start.o	(.text)
+    nand_boot.o	(.text)
+    ndfc.o	(.text)
+
+    *(.text)
+    *(.fixup)
+  }
+  _etext = .;
+
+  .data    :
+  {
+    *(.rodata*)
+    *(.data*)
+    *(.sdata*)
+    __got2_start = .;
+    *(.got2)
+    __got2_end = .;
+  }
+
+  _edata  =  .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss)
+   *(.bss)
+  }
+
+  _end = . ;
+}