[PATCH] Clean up 40EZ/Acadia support

This patch cleans up all the open issue of the preliminary
Acadia support.

Signed-off-by: Stefan Roese <sr@denx.de>
diff --git a/cpu/ppc4xx/gpio.c b/cpu/ppc4xx/gpio.c
new file mode 100644
index 0000000..dd84e58
--- /dev/null
+++ b/cpu/ppc4xx/gpio.c
@@ -0,0 +1,214 @@
+/*
+ * (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 <asm/processor.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+#if defined(CFG_440_GPIO_TABLE)
+gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_440_GPIO_TABLE;
+#endif
+
+#if defined(GPIO0_OSRL)
+/* Only some 4xx variants support alternate funtions on the GPIO's */
+void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
+{
+	u32 mask;
+	u32 mask2;
+	u32 val;
+	u32 offs = 0;
+	u32 offs2 = 0;
+	int pin2 = pin << 1;
+
+	if (pin >= GPIO_MAX) {
+		offs = 0x100;
+		pin -= GPIO_MAX;
+	}
+
+	if (pin >= GPIO_MAX/2) {
+		offs2 = 0x100;
+		pin2 = (pin - GPIO_MAX/2) << 1;
+	}
+
+	mask = 0x80000000 >> pin;
+	mask2 = 0xc0000000 >> (pin2 << 1);
+
+	/* first set TCR to 0 */
+	out32(GPIO0_TCR + offs, in32(GPIO0_TCR + offs) & ~mask);
+
+	if (in_out == GPIO_OUT) {
+		val = in32(GPIO0_OSRL + offs + offs2) & ~mask2;
+		switch (gpio_alt) {
+		case GPIO_ALT1:
+			val |= GPIO_ALT1_SEL >> pin2;
+			break;
+		case GPIO_ALT2:
+			val |= GPIO_ALT2_SEL >> pin2;
+			break;
+		case GPIO_ALT3:
+			val |= GPIO_ALT3_SEL >> pin2;
+			break;
+		}
+		out32(GPIO0_OSRL + offs + offs2, val);
+
+		/* setup requested output value */
+		if (out_val == GPIO_OUT_0)
+			out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~mask);
+		else if (out_val == GPIO_OUT_1)
+			out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) | mask);
+
+		/* now configure TCR to drive output if selected */
+		out32(GPIO0_TCR + offs, in32(GPIO0_TCR + offs) | mask);
+	} else {
+		val = in32(GPIO0_ISR1L + offs + offs2) & ~mask2;
+		val |= GPIO_IN_SEL >> pin2;
+		out32(GPIO0_ISR1L + offs + offs2, val);
+	}
+}
+#endif /* GPIO_OSRL */
+
+void gpio_write_bit(int pin, int val)
+{
+	u32 offs = 0;
+
+	if (pin >= GPIO_MAX) {
+		offs = 0x100;
+		pin -= GPIO_MAX;
+	}
+
+	if (val)
+		out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) | GPIO_VAL(pin));
+	else
+		out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~GPIO_VAL(pin));
+}
+
+#if defined(CFG_440_GPIO_TABLE)
+void gpio_set_chip_configuration(void)
+{
+	unsigned char i=0, j=0, offs=0, gpio_core;
+	unsigned long reg, core_add;
+
+	for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
+		j = 0;
+		offs = 0;
+		/* GPIO config of the GPIOs 0 to 31 */
+		for (i=0; i<GPIO_MAX; i++, j++) {
+			if (i == GPIO_MAX/2) {
+				offs = 4;
+				j = i-16;
+			}
+
+			core_add = gpio_tab[gpio_core][i].add;
+
+			if ((gpio_tab[gpio_core][i].in_out == GPIO_IN) ||
+			    (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
+
+				switch (gpio_tab[gpio_core][i].alt_nb) {
+				case GPIO_SEL:
+					break;
+
+				case GPIO_ALT1:
+					reg = in32(GPIO_IS1(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_IN_SEL >> (j*2));
+					out32(GPIO_IS1(core_add+offs), reg);
+					break;
+
+				case GPIO_ALT2:
+					reg = in32(GPIO_IS2(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_IN_SEL >> (j*2));
+					out32(GPIO_IS2(core_add+offs), reg);
+					break;
+
+				case GPIO_ALT3:
+					reg = in32(GPIO_IS3(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_IN_SEL >> (j*2));
+					out32(GPIO_IS3(core_add+offs), reg);
+					break;
+				}
+			}
+
+			if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) ||
+			    (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
+
+				switch (gpio_tab[gpio_core][i].alt_nb) {
+				case GPIO_SEL:
+					if (gpio_core == GPIO0) {
+						reg = in32(GPIO0_TCR) | (0x80000000 >> (j));
+						out32(GPIO0_TCR, reg);
+					}
+
+					if (gpio_core == GPIO1) {
+						reg = in32(GPIO1_TCR) | (0x80000000 >> (j));
+						out32(GPIO1_TCR, reg);
+					}
+
+					reg = in32(GPIO_OS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					out32(GPIO_OS(core_add+offs), reg);
+					reg = in32(GPIO_TS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					out32(GPIO_TS(core_add+offs), reg);
+					break;
+
+				case GPIO_ALT1:
+					reg = in32(GPIO_OS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_ALT1_SEL >> (j*2));
+					out32(GPIO_OS(core_add+offs), reg);
+					reg = in32(GPIO_TS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_ALT1_SEL >> (j*2));
+					out32(GPIO_TS(core_add+offs), reg);
+					break;
+
+				case GPIO_ALT2:
+					reg = in32(GPIO_OS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_ALT2_SEL >> (j*2));
+					out32(GPIO_OS(core_add+offs), reg);
+					reg = in32(GPIO_TS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_ALT2_SEL >> (j*2));
+					out32(GPIO_TS(core_add+offs), reg);
+					break;
+
+				case GPIO_ALT3:
+					reg = in32(GPIO_OS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_ALT3_SEL >> (j*2));
+					out32(GPIO_OS(core_add+offs), reg);
+					reg = in32(GPIO_TS(core_add+offs))
+						& ~(GPIO_MASK >> (j*2));
+					reg = reg | (GPIO_ALT3_SEL >> (j*2));
+					out32(GPIO_TS(core_add+offs), reg);
+					break;
+				}
+			}
+		}
+	}
+}
+#endif /* CFG_440_GPIO_TABLE */
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index a50d66e..de45ba7 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -2,6 +2,7 @@
  *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
  *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
  *  Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
+ *  Copyright (C) 2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -757,7 +758,6 @@
 #endif /* CONFIG_405EP */
 
 #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
-/* test-only... (clean up later when NAND booting is supported) */
 #if defined(CONFIG_405EZ)
 	/********************************************************************
 	 * Setup OCM - On Chip Memory - PPC405EZ uses OCM Controller V2
@@ -786,41 +786,7 @@
 	mtdcr	ocmdsisdpc,r4
 
 	isync
-
-#if defined(CONFIG_NAND_SPL)
-	/*
-	 * 405EZ can boot from NAND Flash.
-	 * If we are booting the SPL (Pre-loader), copy code from
-	 * the mapped 4K NAND Flash to the OCM
-	 */
-	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 OCM 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
-#else
-/* ...test-only */
+#else /* CONFIG_405EZ */
 	/********************************************************************
 	 * Setup OCM - On Chip Memory
 	 *******************************************************************/
@@ -828,14 +794,15 @@
 	lis	r0, 0x7FFF
 	ori	r0, r0, 0xFFFF
 	mfdcr	r3, ocmiscntl		/* get instr-side IRAM config */
-	mfdcr	r4, ocmdscntl	/* get data-side IRAM config */
-	and	r3, r3, r0	/* disable data-side IRAM */
-	and	r4, r4, r0	/* disable data-side IRAM */
-	mtdcr	ocmiscntl, r3	/* set instr-side IRAM config */
-	mtdcr	ocmdscntl, r4	/* set data-side IRAM config */
+	mfdcr	r4, ocmdscntl		/* get data-side IRAM config */
+	and	r3, r3, r0		/* disable data-side IRAM */
+	and	r4, r4, r0		/* disable data-side IRAM */
+	mtdcr	ocmiscntl, r3		/* set instr-side IRAM config */
+	mtdcr	ocmdscntl, r4		/* set data-side IRAM config */
 	isync
 
-	addis	r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
+	lis	r3,CFG_OCM_DATA_ADDR@h  /* OCM location */
+	ori	r3,r3,CFG_OCM_DATA_ADDR@l
 	mtdcr	ocmdsarc, r3
 	addis	r4, 0, 0xC000		/* OCM data area enabled */
 	mtdcr	ocmdscntl, r4