Merge branch 'master' of git://git.denx.de/u-boot-ppc4xx
diff --git a/arch/powerpc/cpu/ppc4xx/fdt.c b/arch/powerpc/cpu/ppc4xx/fdt.c
index 15a184b..e99b2b0 100644
--- a/arch/powerpc/cpu/ppc4xx/fdt.c
+++ b/arch/powerpc/cpu/ppc4xx/fdt.c
@@ -59,14 +59,14 @@
 			*p++ = 0;
 			*p++ = bxcr & EBC_BXCR_BAS_MASK;
 			*p++ = EBC_BXCR_BANK_SIZE(bxcr);
+		}
+	}
+
 
 #ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE
-			/* Try to update reg property in nor flash node too */
-			fdt_fixup_nor_flash_size(blob, i,
-						 EBC_BXCR_BANK_SIZE(bxcr));
+	/* Update reg property in all nor flash nodes too */
+	fdt_fixup_nor_flash_size(blob);
 #endif
-		}
-	}
 
 	/* Some 405 PPC's have EBC as direct PLB child in the dts */
 	if (fdt_path_offset(blob, ebc_path) < 0)
diff --git a/board/amcc/ebony/flash.c b/board/amcc/ebony/flash.c
index 8fe3ba1..79d2c4c 100644
--- a/board/amcc/ebony/flash.c
+++ b/board/amcc/ebony/flash.c
@@ -34,6 +34,7 @@
 #include <common.h>
 #include <ppc4xx.h>
 #include <asm/processor.h>
+#include <asm/io.h>
 
 #undef DEBUG
 #ifdef DEBUG
@@ -71,6 +72,36 @@
  */
 static ulong flash_get_size(vu_long * addr, flash_info_t * info);
 
+/*
+ * Override the weak default mapping function with a board specific one
+ */
+u32 flash_get_bank_size(int cs, int idx)
+{
+	u8 reg = in_8((void *)CONFIG_SYS_FPGA_BASE);
+
+	if ((reg & BOOT_SMALL_FLASH) && !(reg & FLASH_ONBD_N)) {
+		/*
+		 * cs0: small flash (512KiB)
+		 * cs2: 2 * big flash (2 * 2MiB)
+		 */
+		if (cs == 0)
+			return flash_info[2].size;
+		if (cs == 2)
+			return flash_info[0].size + flash_info[1].size;
+	} else {
+		/*
+		 * cs0: 2 * big flash (2 * 2MiB)
+		 * cs2: small flash (512KiB)
+		 */
+		if (cs == 0)
+			return flash_info[0].size + flash_info[1].size;
+		if (cs == 2)
+			return flash_info[2].size;
+	}
+
+	return 0;
+}
+
 unsigned long flash_init(void)
 {
 	unsigned long total_b = 0;
diff --git a/common/fdt_support.c b/common/fdt_support.c
index aef4fe2..6f32e3f 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -591,11 +591,30 @@
 
 #ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE
 /*
+ * Provide a weak default function to return the flash bank size.
+ * There might be multiple non-identical flash chips connected to one
+ * chip-select, so we need to pass an index as well.
+ */
+u32 __flash_get_bank_size(int cs, int idx)
+{
+	extern flash_info_t flash_info[];
+
+	/*
+	 * As default, a simple 1:1 mapping is provided. Boards with
+	 * a different mapping need to supply a board specific mapping
+	 * routine.
+	 */
+	return flash_info[cs].size;
+}
+u32 flash_get_bank_size(int cs, int idx)
+	__attribute__((weak, alias("__flash_get_bank_size")));
+
+/*
  * This function can be used to update the size in the "reg" property
- * of the NOR FLASH device nodes. This is necessary for boards with
+ * of all NOR FLASH device nodes. This is necessary for boards with
  * non-fixed NOR FLASH sizes.
  */
-int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size)
+int fdt_fixup_nor_flash_size(void *blob)
 {
 	char compat[][16] = { "cfi-flash", "jedec-flash" };
 	int off;
@@ -607,19 +626,31 @@
 	for (i = 0; i < 2; i++) {
 		off = fdt_node_offset_by_compatible(blob, -1, compat[i]);
 		while (off != -FDT_ERR_NOTFOUND) {
+			int idx;
+
 			/*
-			 * Found one compatible node, now check if this one
-			 * has the correct CS
+			 * Found one compatible node, so fixup the size
+			 * int its reg properties
 			 */
 			prop = fdt_get_property_w(blob, off, "reg", &len);
 			if (prop) {
+				int tuple_size = 3 * sizeof(reg);
+
+				/*
+				 * There might be multiple reg-tuples,
+				 * so loop through them all
+				 */
+				len /= tuple_size;
 				reg = (u32 *)&prop->data[0];
-				if (reg[0] == cs) {
-					reg[2] = size;
+				for (idx = 0; idx < len; idx++) {
+					/*
+					 * Update size in reg property
+					 */
+					reg[2] = flash_get_bank_size(reg[0],
+								     idx);
 					fdt_setprop(blob, off, "reg", reg,
-						    3 * sizeof(u32));
-
-					return 0;
+						    tuple_size);
+					reg += tuple_size;
 				}
 			}
 
@@ -629,7 +660,7 @@
 		}
 	}
 
-	return -1;
+	return 0;
 }
 #endif
 
diff --git a/include/configs/CATcenter.h b/include/configs/CATcenter.h
index 229a513..002435e 100644
--- a/include/configs/CATcenter.h
+++ b/include/configs/CATcenter.h
@@ -105,6 +105,7 @@
 #define CONFIG_SYS_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
 
 
+#define CONFIG_PPC4xx_EMAC
 #undef CONFIG_EXT_PHY
 #define CONFIG_NET_MULTI	1
 
@@ -398,6 +399,7 @@
  * I2C EEPROM (CAT24WC16) for environment
  */
 #define CONFIG_HARD_I2C			/* I2c with hardware support */
+#define CONFIG_PPC4XX_I2C		/* use PPC4xx driver		*/
 #define CONFIG_SYS_I2C_SPEED		400000	/* I2C speed and slave address */
 #define CONFIG_SYS_I2C_SLAVE		0x7F
 
@@ -410,16 +412,6 @@
 					/* last 4 bits of the address	*/
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	10   /* and takes up to 10 msec */
 
-/*-----------------------------------------------------------------------
- * Cache Configuration
- */
-#define CONFIG_SYS_DCACHE_SIZE		16384	/* For AMCC 405 CPUs, older 405 ppc's	*/
-					/* have only 8kB, 16kB is save here	*/
-#define CONFIG_SYS_CACHELINE_SIZE	32	/* ...			*/
-#if defined(CONFIG_CMD_KGDB)
-#define CONFIG_SYS_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
-#endif
-
 /*
  * Init Memory Controller:
  *
@@ -570,17 +562,6 @@
 #define		DIMM_READ_ADDR 0xAB
 #define		DIMM_WRITE_ADDR 0xAA
 
-#define CPC0_PLLMR0  (CNTRL_DCR_BASE+0x0)  /* PLL mode 0 register		*/
-#define CPC0_BOOT    (CNTRL_DCR_BASE+0x1)  /* Chip Clock Status register	*/
-#define CPC0_CR1     (CNTRL_DCR_BASE+0x2)  /* Chip Control 1 register		*/
-#define CPC0_EPRCSR  (CNTRL_DCR_BASE+0x3)  /* EMAC PHY Rcv Clk Src register	*/
-#define CPC0_PLLMR1  (CNTRL_DCR_BASE+0x4)  /* PLL mode 1 register		*/
-#define CPC0_UCR     (CNTRL_DCR_BASE+0x5)  /* UART Control register		*/
-#define CPC0_SRR     (CNTRL_DCR_BASE+0x6)  /* Soft Reset register		*/
-#define CPC0_JTAGID  (CNTRL_DCR_BASE+0x7)  /* JTAG ID register			*/
-#define CPC0_SPARE   (CNTRL_DCR_BASE+0x8)  /* Spare DCR				*/
-#define CPC0_PCI     (CNTRL_DCR_BASE+0x9)  /* PCI Control register		*/
-
 /* Defines for CPC0_PLLMR1 Register fields */
 #define PLL_ACTIVE		0x80000000
 #define CPC0_PLLMR1_SSCS	0x80000000
diff --git a/include/configs/acadia.h b/include/configs/acadia.h
index bd3388f..8b01c70 100644
--- a/include/configs/acadia.h
+++ b/include/configs/acadia.h
@@ -120,7 +120,13 @@
 #define CONFIG_SYS_FLASH_EMPTY_INFO		/* print 'E' for empty sector on flinfo */
 
 #else
-#define	CONFIG_SYS_NO_FLASH		1	/* No NOR on Acadia when NAND-booting	*/
+/*
+ * No NOR-flash on Acadia when NAND-booting. We need to undef the
+ * NOR device-tree fixup code as well, since flash_info is not defined
+ * in this case.
+ */
+#define	CONFIG_SYS_NO_FLASH		1
+#undef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE
 #endif
 
 #ifdef CONFIG_ENV_IS_IN_FLASH
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 871ef45..fd94929 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -79,7 +79,7 @@
 void set_working_fdt_addr(void *addr);
 int fdt_resize(void *blob);
 
-int fdt_fixup_nor_flash_size(void *blob, int cs, u32 size);
+int fdt_fixup_nor_flash_size(void *blob);
 
 void fdt_fixup_mtdparts(void *fdt, void *node_info, int node_info_size);
 void fdt_del_node_and_alias(void *blob, const char *alias);
diff --git a/include/ppc4xx.h b/include/ppc4xx.h
index ee30a4c..5238d04 100644
--- a/include/ppc4xx.h
+++ b/include/ppc4xx.h
@@ -99,6 +99,16 @@
 
 #endif /* 440EP/EPX 440GR/GRX 440SP/SPE 460EX/GT/SX 405EX*/
 
+/*
+ * Define ns16550 register offset for all PPC4xx SoC's. Some
+ * mostly FPGA based PPC4xx implementations use a different
+ * offset. So let's give them a chance to define their offset
+ * in the board config header.
+ */
+#if !defined(CONFIG_SYS_NS16550_REG_SIZE)
+#define CONFIG_SYS_NS16550_REG_SIZE	1
+#endif
+
 #if defined(CONFIG_440)
 #include <ppc440.h>
 #else
diff --git a/post/cpu/ppc4xx/uart.c b/post/cpu/ppc4xx/uart.c
index be217fc..6b61cc1 100644
--- a/post/cpu/ppc4xx/uart.c
+++ b/post/cpu/ppc4xx/uart.c
@@ -4,6 +4,8 @@
  *
  * Author: Igor Lisitsin <igor@emcraft.com>
  *
+ * Copyright 2010, Stefan Roese, DENX Software Engineering, sr@denx.de
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -24,6 +26,9 @@
  */
 
 #include <common.h>
+#include <ppc4xx.h>
+#include <ns16550.h>
+#include <asm/io.h>
 
 /*
  * UART test
@@ -119,32 +124,23 @@
 #define UDIV_MAX        32
 #endif
 
-#define UART_RBR    0x00
-#define UART_THR    0x00
-#define UART_IER    0x01
-#define UART_IIR    0x02
-#define UART_FCR    0x02
-#define UART_LCR    0x03
-#define UART_MCR    0x04
-#define UART_LSR    0x05
-#define UART_MSR    0x06
-#define UART_SCR    0x07
-#define UART_DLL    0x00
-#define UART_DLM    0x01
+DECLARE_GLOBAL_DATA_PTR;
 
-/*
- * Line Status Register.
- */
-#define asyncLSRDataReady1            0x01
-#define asyncLSROverrunError1         0x02
-#define asyncLSRParityError1          0x04
-#define asyncLSRFramingError1         0x08
-#define asyncLSRBreakInterrupt1       0x10
-#define asyncLSRTxHoldEmpty1          0x20
-#define asyncLSRTxShiftEmpty1         0x40
-#define asyncLSRRxFifoError1          0x80
+static void uart_post_init_common(struct NS16550 *com_port, unsigned short bdiv)
+{
+	volatile char val;
 
-DECLARE_GLOBAL_DATA_PTR;
+	out_8(&com_port->lcr, 0x80);	/* set DLAB bit */
+	out_8(&com_port->dll, bdiv);	/* set baudrate divisor */
+	out_8(&com_port->dlm, bdiv >> 8); /* set baudrate divisor */
+	out_8(&com_port->lcr, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	out_8(&com_port->fcr, 0x00);	/* disable FIFO */
+	out_8(&com_port->mcr, 0x10);	/* enable loopback mode */
+	val = in_8(&com_port->lsr);	/* clear line status */
+	val = in_8(&com_port->rbr);	/* read receive buffer */
+	out_8(&com_port->scr, 0x00);	/* set scratchpad */
+	out_8(&com_port->ier, 0x00);	/* set interrupt enable reg */
+}
 
 #if defined(CONFIG_440) || defined(CONFIG_405EX)
 #if !defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
@@ -190,19 +186,18 @@
 }
 #endif
 
-static int uart_post_init (unsigned long dev_base)
+static int uart_post_init (struct NS16550 *com_port)
 {
 	unsigned long reg = 0;
 	unsigned long udiv;
 	unsigned short bdiv;
-	volatile char val;
 #ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
 	unsigned long tmp;
 #endif
 	int i;
 
 	for (i = 0; i < 3500; i++) {
-		if (in8 (dev_base + UART_LSR) & asyncLSRTxHoldEmpty1)
+		if (in_8(&com_port->lsr) & UART_LSR_THRE)
 			break;
 		udelay (100);
 	}
@@ -239,34 +234,24 @@
 	MTREG(UART3_SDR, reg);
 #endif
 
-	out8(dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8(dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8(dev_base + UART_DLM, bdiv >> 8);	/* set baudrate divisor */
-	out8(dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8(dev_base + UART_FCR, 0x00);	/* disable FIFO */
-	out8(dev_base + UART_MCR, 0x10);	/* enable loopback mode */
-	val = in8(dev_base + UART_LSR);		/* clear line status */
-	val = in8(dev_base + UART_RBR);		/* read receive buffer */
-	out8(dev_base + UART_SCR, 0x00);	/* set scratchpad */
-	out8(dev_base + UART_IER, 0x00);	/* set interrupt enable reg */
+	uart_post_init_common(com_port, bdiv);
 
 	return 0;
 }
 
 #else /* CONFIG_440 */
 
-static int uart_post_init (unsigned long dev_base)
+static int uart_post_init (struct NS16550 *com_port)
 {
 	unsigned long reg;
 	unsigned long tmp;
 	unsigned long clk;
 	unsigned long udiv;
 	unsigned short bdiv;
-	volatile char val;
 	int i;
 
 	for (i = 0; i < 3500; i++) {
-		if (in8 (dev_base + UART_LSR) & asyncLSRTxHoldEmpty1)
+		if (in_8(&com_port->lsr) & UART_LSR_THRE)
 			break;
 		udelay (100);
 	}
@@ -309,59 +294,51 @@
 	bdiv = (clk + tmp / 2) / tmp;
 #endif /* CONFIG_405EZ */
 
-	out8(dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8(dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8(dev_base + UART_DLM, bdiv >> 8);	/* set baudrate divisor */
-	out8(dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8(dev_base + UART_FCR, 0x00);	/* disable FIFO */
-	out8(dev_base + UART_MCR, 0x10);	/* enable loopback mode */
-	val = in8(dev_base + UART_LSR);	/* clear line status */
-	val = in8(dev_base + UART_RBR);	/* read receive buffer */
-	out8(dev_base + UART_SCR, 0x00);	/* set scratchpad */
-	out8(dev_base + UART_IER, 0x00);	/* set interrupt enable reg */
+	uart_post_init_common(com_port, bdiv);
 
-	return (0);
+	return 0;
 }
 #endif /* CONFIG_440 */
 
-static void uart_post_putc (unsigned long dev_base, char c)
+static void uart_post_putc (struct NS16550 *com_port, char c)
 {
 	int i;
 
-	out8 (dev_base + UART_THR, c);	/* put character out */
+	out_8(&com_port->thr, c);	/* put character out */
 
 	/* Wait for transfer completion */
 	for (i = 0; i < 3500; i++) {
-		if (in8 (dev_base + UART_LSR) & asyncLSRTxHoldEmpty1)
+		if (in_8(&com_port->lsr) & UART_LSR_THRE)
 			break;
 		udelay (100);
 	}
 }
 
-static int uart_post_getc (unsigned long dev_base)
+static int uart_post_getc (struct NS16550 *com_port)
 {
 	int i;
 
 	/* Wait for character available */
 	for (i = 0; i < 3500; i++) {
-		if (in8 (dev_base + UART_LSR) & asyncLSRDataReady1)
+		if (in_8(&com_port->lsr) & UART_LSR_DR)
 			break;
 		udelay (100);
 	}
-	return 0xff & in8 (dev_base + UART_RBR);
+
+	return 0xff & in_8(&com_port->rbr);
 }
 
-static int test_ctlr (unsigned long dev_base, int index)
+static int test_ctlr (struct NS16550 *com_port, int index)
 {
 	int res = -1;
 	char test_str[] = "*** UART Test String ***\r\n";
 	int i;
 
-	uart_post_init (dev_base);
+	uart_post_init (com_port);
 
 	for (i = 0; i < sizeof (test_str) - 1; i++) {
-		uart_post_putc (dev_base, test_str[i]);
-		if (uart_post_getc (dev_base) != test_str[i])
+		uart_post_putc (com_port, test_str[i]);
+		if (uart_post_getc (com_port) != test_str[i])
 			goto done;
 	}
 	res = 0;
@@ -377,8 +354,8 @@
 	int i, res = 0;
 	static unsigned long base[] = CONFIG_SYS_POST_UART_TABLE;
 
-	for (i = 0; i < sizeof (base) / sizeof (base[0]); i++) {
-		if (test_ctlr (base[i], i))
+	for (i = 0; i < ARRAY_SIZE(base); i++) {
+		if (test_ctlr((struct NS16550 *)base[i], i))
 			res = -1;
 	}
 	serial_reinit_all ();