ppc4xx: Use common NS16550 driver for PPC4xx UART

This patch removes the PPC4xx UART driver. Instead the common NS16550
driver is used, since all PPC4xx SoC's use this peripheral device.

The file 4xx_uart.c now only implements the UART clock calculation
function which also sets the SoC internal UART divisors.

All PPC4xx board config headers are changed to use this common NS16550
driver now.

Tested on these boards:
acadia, canyonlands, katmai, kilauea, sequoia, zeus

Signed-off-by: Stefan Roese <sr@denx.de>
diff --git a/arch/powerpc/cpu/ppc4xx/4xx_uart.c b/arch/powerpc/cpu/ppc4xx/4xx_uart.c
index 5eaeefe..2660aa8 100644
--- a/arch/powerpc/cpu/ppc4xx/4xx_uart.c
+++ b/arch/powerpc/cpu/ppc4xx/4xx_uart.c
@@ -2,6 +2,9 @@
  * (C) Copyright 2000-2006
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
+ * (C) Copyright 2010
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -51,14 +54,6 @@
 #include <watchdog.h>
 #include <asm/ppc4xx.h>
 
-#ifdef CONFIG_SERIAL_MULTI
-#include <serial.h>
-#endif
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-#include <malloc.h>
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
@@ -66,24 +61,6 @@
     defined(CONFIG_405EX) || defined(CONFIG_440)
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
-    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
-    defined(CONFIG_460EX) || defined(CONFIG_460GT)
-#define UART0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000300)
-#define UART1_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000400)
-#else
-#define UART0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000200)
-#define UART1_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000300)
-#endif
-
-#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
-#define UART2_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000600)
-#endif
-
-#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
-#define UART2_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000500)
-#define UART3_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000600)
-#endif
 
 #if defined(CONFIG_440GP)
 #define CR0_MASK        0x3fff0000
@@ -116,16 +93,14 @@
 #define MTREG(a, d)	mtsdr(a, d)
 #endif /* #if defined(CONFIG_440GP) */
 #elif defined(CONFIG_405EP) || defined(CONFIG_405EZ)
-#define UART0_BASE      0xef600300
-#define UART1_BASE      0xef600400
 #define UCR0_MASK       0x0000007f
 #define UCR1_MASK       0x00007f00
 #define UCR0_UDIV_POS   0
 #define UCR1_UDIV_POS   8
 #define UDIV_MAX        127
 #elif defined(CONFIG_405EX)
-#define UART0_BASE	0xef600200
-#define UART1_BASE	0xef600300
+#define MFREG(a, d)	mfsdr(a, d)
+#define MTREG(a, d)	mtsdr(a, d)
 #define CR0_MASK	0x000000ff
 #define CR0_EXTCLK_ENA	0x00800000
 #define CR0_UDIV_POS	0
@@ -133,223 +108,164 @@
 #define UART0_SDR	SDR0_UART0
 #define UART1_SDR	SDR0_UART1
 #else /* CONFIG_405GP || CONFIG_405CR */
-#define UART0_BASE      0xef600300
-#define UART1_BASE      0xef600400
 #define CR0_MASK        0x00001fff
 #define CR0_EXTCLK_ENA  0x000000c0
 #define CR0_UDIV_POS    1
 #define UDIV_MAX        32
 #endif
 
-/* using serial port 0 or 1 as U-Boot console ? */
-#if defined(CONFIG_UART1_CONSOLE)
-#define ACTING_UART0_BASE	UART1_BASE
-#define ACTING_UART1_BASE	UART0_BASE
-#else
-#define ACTING_UART0_BASE	UART0_BASE
-#define ACTING_UART1_BASE	UART1_BASE
-#endif
-
 #if defined(CONFIG_405EP) && defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
 #error "External serial clock not supported on AMCC PPC405EP!"
 #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
-
-/*-----------------------------------------------------------------------------+
-  | 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
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-/*-----------------------------------------------------------------------------+
-  | Fifo
-  +-----------------------------------------------------------------------------*/
-typedef struct {
-	char *rx_buffer;
-	ulong rx_put;
-	ulong rx_get;
-} serial_buffer_t;
-
-volatile static serial_buffer_t buf_info;
-#endif
-
-static void serial_init_common(u32 base, u32 udiv, u16 bdiv)
-{
-	PPC4xx_SYS_INFO sys_info;
-	u8 val;
-
-	get_sys_info(&sys_info);
-
-	/* Correct UART frequency in bd-info struct now that
-	 * the UART divisor is available
-	 */
-#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
-	gd->uart_clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
-#else
-	gd->uart_clk = sys_info.freqUART / udiv;
-#endif
-
-	out_8((u8 *)base + UART_LCR, 0x80);	/* set DLAB bit */
-	out_8((u8 *)base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out_8((u8 *)base + UART_DLM, bdiv >> 8); /* set baudrate divisor */
-	out_8((u8 *)base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out_8((u8 *)base + UART_FCR, 0x00);	/* disable FIFO */
-	out_8((u8 *)base + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in_8((u8 *)base + UART_LSR);	/* clear line status */
-	val = in_8((u8 *)base + UART_RBR);	/* read receive buffer */
-	out_8((u8 *)base + UART_SCR, 0x00);	/* set scratchpad */
-	out_8((u8 *)base + UART_IER, 0x00);	/* set interrupt enable reg */
-}
-
-#if (defined(CONFIG_440) || defined(CONFIG_405EX)) &&	\
-    !defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
-static void serial_divs (int baudrate, unsigned long *pudiv,
-			 unsigned short *pbdiv)
+#if (defined(CONFIG_405EX) || defined(CONFIG_405EZ) ||	\
+     defined(CONFIG_440)) && !defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
+/*
+ * For some SoC's, the cpu clock is on divider chain A, UART on
+ * divider chain B ... so cpu clock is irrelevant. Get the
+ * "optimized" values that are subject to the 1/2 opb clock
+ * constraint.
+ */
+static u16 serial_bdiv(int baudrate, u32 *udiv)
 {
 	sys_info_t sysinfo;
-	unsigned long div;		/* total divisor udiv * bdiv */
-	unsigned long umin;		/* minimum udiv	*/
-	unsigned short diff;		/* smallest diff */
-	unsigned long udiv;		/* best udiv */
-	unsigned short idiff;		/* current diff */
-	unsigned short ibdiv;		/* current bdiv */
-	unsigned long i;
-	unsigned long est;		/* current estimate */
+	u32 div;		/* total divisor udiv * bdiv */
+	u32 umin;		/* minimum udiv	*/
+	u16 diff;		/* smallest diff */
+	u16 idiff;		/* current diff */
+	u16 ibdiv;		/* current bdiv */
+	u32 i;
+	u32 est;		/* current estimate */
+	u32 max;
+#if defined(CONFIG_405EZ)
+	u32 cpr_pllc;
+	u32 plloutb;
+	u32 reg;
+#endif
 
 	get_sys_info(&sysinfo);
 
-	udiv = 32;			/* Assume lowest possible serial clk */
-	div = sysinfo.freqPLB / (16 * baudrate); /* total divisor */
-	umin = sysinfo.pllOpbDiv << 1;	/* 2 x OPB divisor */
-	diff = 32;			/* highest possible */
-
-	/* i is the test udiv value -- start with the largest
-	 * possible (32) to minimize serial clock and constrain
-	 * search to umin.
-	 */
-	for (i = 32; i > umin; i--) {
-		ibdiv = div / i;
-		est = i * ibdiv;
-		idiff = (est > div) ? (est-div) : (div-est);
-		if (idiff == 0) {
-			udiv = i;
-			break;      /* can't do better */
-		} else if (idiff < diff) {
-			udiv = i;       /* best so far */
-			diff = idiff;   /* update lowest diff*/
-		}
-	}
-
-	*pudiv = udiv;
-	*pbdiv = div / udiv;
-}
-
-#elif defined(CONFIG_405EZ)
-
-static void serial_divs (int baudrate, unsigned long *pudiv,
-			 unsigned short *pbdiv)
-{
-	sys_info_t sysinfo;
-	unsigned long div;		/* total divisor udiv * bdiv */
-	unsigned long umin;		/* minimum udiv	*/
-	unsigned short diff;		/* smallest diff */
-	unsigned long udiv;		/* best udiv */
-	unsigned short idiff;		/* current diff */
-	unsigned short ibdiv;		/* current bdiv */
-	unsigned long i;
-	unsigned long est;		/* current estimate */
-	unsigned long plloutb;
-	unsigned long cpr_pllc;
-	u32 reg;
-
+#if defined(CONFIG_405EZ)
 	/* check the pll feedback source */
 	mfcpr(CPR0_PLLC, cpr_pllc);
-
-	get_sys_info(&sysinfo);
-
 	plloutb = ((CONFIG_SYS_CLK_FREQ * ((cpr_pllc & PLLC_SRC_MASK) ?
 					   sysinfo.pllFwdDivB : sysinfo.pllFwdDiv) *
 		    sysinfo.pllFbkDiv) / sysinfo.pllFwdDivB);
-	udiv = 256;			/* Assume lowest possible serial clk */
 	div = plloutb / (16 * baudrate); /* total divisor */
 	umin = (plloutb / get_OPB_freq()) << 1;	/* 2 x OPB divisor */
-	diff = 256;			/* highest possible */
+	max = 256;			/* highest possible */
+#else /* 405EZ */
+	div = sysinfo.freqPLB / (16 * baudrate); /* total divisor */
+	umin = sysinfo.pllOpbDiv << 1;	/* 2 x OPB divisor */
+	max = 32;			/* highest possible */
+#endif /* 405EZ */
 
-	/* i is the test udiv value -- start with the largest
-	 * possible (256) to minimize serial clock and constrain
+	*udiv = diff = max;
+
+	/*
+	 * i is the test udiv value -- start with the largest
+	 * possible (max) to minimize serial clock and constrain
 	 * search to umin.
 	 */
-	for (i = 256; i > umin; i--) {
+	for (i = max; i > umin; i--) {
 		ibdiv = div / i;
 		est = i * ibdiv;
-		idiff = (est > div) ? (est-div) : (div-est);
+		idiff = (est > div) ? (est - div) : (div - est);
 		if (idiff == 0) {
-			udiv = i;
-			break;      /* can't do better */
+			*udiv = i;
+			break;		/* can't do better */
 		} else if (idiff < diff) {
-			udiv = i;       /* best so far */
-			diff = idiff;   /* update lowest diff*/
+			*udiv = i;	/* best so far */
+			diff = idiff;	/* update lowest diff*/
 		}
 	}
 
-	*pudiv = udiv;
+#if defined(CONFIG_405EZ)
 	mfcpr(CPR0_PERD0, reg);
 	reg &= ~0x0000ffff;
-	reg |= ((udiv - 0) << 8) | (udiv - 0);
+	reg |= ((*udiv - 0) << 8) | (*udiv - 0);
 	mtcpr(CPR0_PERD0, reg);
-	*pbdiv = div / udiv;
-}
-#endif /* defined(CONFIG_440) && !defined(CONFIG_SYS_EXT_SERIAL_CLK) */
-
-/*
- * Minimal serial functions needed to use one of the SMC ports
- * as serial console interface.
- */
-
-#if defined(CONFIG_440)
-int serial_init_dev(unsigned long base)
-{
-	unsigned long reg;
-	unsigned long udiv;
-	unsigned short bdiv;
-#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
-	unsigned long tmp;
 #endif
 
+	return div / *udiv;
+}
+#endif /* #if (defined(CONFIG_405EP) ... */
+
+/*
+ * This function returns the UART clock used by the common
+ * NS16550 driver. Additionally the SoC internal divisors for
+ * optimal UART baudrate are configured.
+ */
+int get_serial_clock(void)
+{
+	u32 clk;
+	u32 udiv;
+#if defined(CONFIG_405CR) || defined(CONFIG_405EP) || defined(CONFIG_405GP)
+	u32 tmp;
+#endif
+#if !defined(CONFIG_405EZ)
+	u32 reg;
+#endif
+#if !defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
+	PPC4xx_SYS_INFO sys_info;
+#endif
+
+	/*
+	 * Programming of the internal divisors is SoC specific.
+	 * Let's handle this in some #ifdef's for the SoC's.
+	 */
+
+#if defined(CONFIG_405CR) || defined(CONFIG_405GP)
+	tmp = 0;
+	reg = mfdcr(CPC0_CR0) & ~CR0_MASK;
+#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
+	clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
+	udiv = 1;
+	reg |= CR0_EXTCLK_ENA;
+#else /* CONFIG_SYS_EXT_SERIAL_CLOCK */
+	clk = gd->cpu_clk;
+#ifdef CONFIG_SYS_405_UART_ERRATA_59
+	udiv = 31;			/* Errata 59: stuck at 31 */
+#else /* CONFIG_SYS_405_UART_ERRATA_59 */
+	tmp = CONFIG_SYS_BASE_BAUD * 16;
+	udiv = (clk + tmp / 2) / tmp;
+	if (udiv > UDIV_MAX)                    /* max. n bits for udiv */
+		udiv = UDIV_MAX;
+#endif /* CONFIG_SYS_405_UART_ERRATA_59 */
+#endif /* CONFIG_SYS_EXT_SERIAL_CLOCK */
+	reg |= (udiv - 1) << CR0_UDIV_POS;	/* set the UART divisor */
+	mtdcr (CPC0_CR0, reg);
+#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
+	clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
+#else
+	clk = CONFIG_SYS_BASE_BAUD * 16;
+#endif
+#endif /* CONFIG_405CR */
+
+#if defined(CONFIG_405EP)
+	reg = mfdcr(CPC0_UCR) & ~(UCR0_MASK | UCR1_MASK);
+	clk = gd->cpu_clk;
+	tmp = CONFIG_SYS_BASE_BAUD * 16;
+	udiv = (clk + tmp / 2) / tmp;
+	if (udiv > UDIV_MAX)                    /* max. n bits for udiv */
+		udiv = UDIV_MAX;
+	reg |= udiv << UCR0_UDIV_POS;	        /* set the UART divisor */
+	reg |= udiv << UCR1_UDIV_POS;	        /* set the UART divisor */
+	mtdcr(CPC0_UCR, reg);
+	clk = CONFIG_SYS_BASE_BAUD * 16;
+#endif /* CONFIG_405EP */
+
+#if defined(CONFIG_405EX) || defined(CONFIG_440)
 	MFREG(UART0_SDR, reg);
 	reg &= ~CR0_MASK;
 
 #ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
 	reg |= CR0_EXTCLK_ENA;
 	udiv = 1;
-	tmp  = gd->baudrate * 16;
-	bdiv = (CONFIG_SYS_EXT_SERIAL_CLOCK + tmp / 2) / tmp;
-#else
-	/* For 440, the cpu clock is on divider chain A, UART on divider
-	 * chain B ... so cpu clock is irrelevant. Get the "optimized"
-	 * values that are subject to the 1/2 opb clock constraint
-	 */
-	serial_divs (gd->baudrate, &udiv, &bdiv);
-#endif
+	clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
+#else /* CONFIG_SYS_EXT_SERIAL_CLOCK */
+	clk = gd->baudrate * serial_bdiv(gd->baudrate, &udiv) * 16;
+#endif /* CONFIG_SYS_EXT_SERIAL_CLOCK */
 
 	reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS;	/* set the UART divisor */
 
@@ -367,514 +283,23 @@
 #if defined(UART3_SDR)
 	MTREG(UART3_SDR, reg);
 #endif
+#endif /* CONFIG_405EX ... */
 
-	serial_init_common(base, udiv, bdiv);
-
-	return (0);
-}
-
-#else /* !defined(CONFIG_440) */
-
-int serial_init_dev (unsigned long base)
-{
-	unsigned long reg;
-	unsigned long tmp;
-	unsigned long clk;
-	unsigned long udiv;
-	unsigned short bdiv;
-
-#ifdef CONFIG_405EX
-	clk = tmp = 0;
-	mfsdr(UART0_SDR, reg);
-	reg &= ~CR0_MASK;
-#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
-	reg |= CR0_EXTCLK_ENA;
-	udiv = 1;
-	tmp  = gd->baudrate * 16;
-	bdiv = (CONFIG_SYS_EXT_SERIAL_CLOCK + tmp / 2) / tmp;
-#else
-	serial_divs(gd->baudrate, &udiv, &bdiv);
-#endif
-	reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS;  /* set the UART divisor */
+#if defined(CONFIG_405EZ)
+	clk = gd->baudrate * serial_bdiv(gd->baudrate, &udiv) * 16;
+#endif /* CONFIG_405EZ */
 
 	/*
-	 * Configure input clock to baudrate generator for all
-	 * available serial ports here
+	 * Correct UART frequency in bd-info struct now that
+	 * the UART divisor is available
 	 */
-	mtsdr(UART0_SDR, reg);
-
-#if defined(UART1_SDR)
-	mtsdr(UART1_SDR, reg);
-#endif
-
-#elif defined(CONFIG_405EZ)
-	serial_divs(gd->baudrate, &udiv, &bdiv);
-	clk = tmp = reg = 0;
-#else
-#ifdef CONFIG_405EP
-	reg = mfdcr(CPC0_UCR) & ~(UCR0_MASK | UCR1_MASK);
-	clk = gd->cpu_clk;
-	tmp = CONFIG_SYS_BASE_BAUD * 16;
-	udiv = (clk + tmp / 2) / tmp;
-	if (udiv > UDIV_MAX)                    /* max. n bits for udiv */
-		udiv = UDIV_MAX;
-	reg |= (udiv) << UCR0_UDIV_POS;	        /* set the UART divisor */
-	reg |= (udiv) << UCR1_UDIV_POS;	        /* set the UART divisor */
-	mtdcr (CPC0_UCR, reg);
-#else /* CONFIG_405EP */
-	reg = mfdcr(CPC0_CR0) & ~CR0_MASK;
 #ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
-	clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
-	udiv = 1;
-	reg |= CR0_EXTCLK_ENA;
+	gd->uart_clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
 #else
-	clk = gd->cpu_clk;
-#ifdef CONFIG_SYS_405_UART_ERRATA_59
-	udiv = 31;			/* Errata 59: stuck at 31 */
-#else
-	tmp = CONFIG_SYS_BASE_BAUD * 16;
-	udiv = (clk + tmp / 2) / tmp;
-	if (udiv > UDIV_MAX)                    /* max. n bits for udiv */
-		udiv = UDIV_MAX;
-#endif
-#endif
-	reg |= (udiv - 1) << CR0_UDIV_POS;	/* set the UART divisor */
-	mtdcr (CPC0_CR0, reg);
-#endif /* CONFIG_405EP */
-	tmp = gd->baudrate * udiv * 16;
-	bdiv = (clk + tmp / 2) / tmp;
-#endif /* CONFIG_405EX */
-
-	serial_init_common(base, udiv, bdiv);
-
-	return (0);
-}
-
-#endif /* if defined(CONFIG_440) */
-
-void serial_setbrg_dev(unsigned long base)
-{
-	serial_init_dev(base);
-}
-
-void serial_putc_dev(unsigned long base, const char c)
-{
-	int i;
-
-	if (c == '\n')
-		serial_putc_dev(base, '\r');
-
-	/* check THRE bit, wait for transmiter available */
-	for (i = 1; i < 3500; i++) {
-		if ((in_8((u8 *)base + UART_LSR) & 0x20) == 0x20)
-			break;
-		udelay (100);
-	}
-
-	out_8((u8 *)base + UART_THR, c);	/* put character out */
-}
-
-void serial_puts_dev (unsigned long base, const char *s)
-{
-	while (*s)
-		serial_putc_dev (base, *s++);
-}
-
-int serial_getc_dev (unsigned long base)
-{
-	unsigned char status = 0;
-
-	while (1) {
-#if defined(CONFIG_HW_WATCHDOG)
-		WATCHDOG_RESET ();	/* Reset HW Watchdog, if needed */
-#endif	/* CONFIG_HW_WATCHDOG */
-
-		status = in_8((u8 *)base + UART_LSR);
-		if ((status & asyncLSRDataReady1) != 0x0)
-			break;
-
-		if ((status & ( asyncLSRFramingError1 |
-				asyncLSROverrunError1 |
-				asyncLSRParityError1  |
-				asyncLSRBreakInterrupt1 )) != 0) {
-			out_8((u8 *)base + UART_LSR,
-			      asyncLSRFramingError1 |
-			      asyncLSROverrunError1 |
-			      asyncLSRParityError1  |
-			      asyncLSRBreakInterrupt1);
-		}
-	}
-
-	return (0x000000ff & (int) in_8((u8 *)base));
-}
-
-int serial_tstc_dev (unsigned long base)
-{
-	unsigned char status;
-
-	status = in_8((u8 *)base + UART_LSR);
-	if ((status & asyncLSRDataReady1) != 0x0)
-		return (1);
-
-	if ((status & ( asyncLSRFramingError1 |
-			asyncLSROverrunError1 |
-			asyncLSRParityError1  |
-			asyncLSRBreakInterrupt1 )) != 0) {
-		out_8((u8 *)base + UART_LSR,
-		      asyncLSRFramingError1 |
-		      asyncLSROverrunError1 |
-		      asyncLSRParityError1  |
-		      asyncLSRBreakInterrupt1);
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
-
-void serial_isr (void *arg)
-{
-	int space;
-	int c;
-	const int rx_get = buf_info.rx_get;
-	int rx_put = buf_info.rx_put;
-
-	if (rx_get <= rx_put)
-		space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
-	else
-		space = rx_get - rx_put;
-
-	while (serial_tstc_dev (ACTING_UART0_BASE)) {
-		c = serial_getc_dev (ACTING_UART0_BASE);
-		if (space) {
-			buf_info.rx_buffer[rx_put++] = c;
-			space--;
-		}
-		if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO)
-			rx_put = 0;
-		if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) {
-			/* Stop flow by setting RTS inactive */
-			out_8((u8 *)ACTING_UART0_BASE + UART_MCR,
-			      in_8((u8 *)ACTING_UART0_BASE + UART_MCR) &
-			      (0xFF ^ 0x02));
-		}
-	}
-	buf_info.rx_put = rx_put;
-}
-
-void serial_buffered_init (void)
-{
-	serial_puts ("Switching to interrupt driven serial input mode.\n");
-	buf_info.rx_buffer = malloc (CONFIG_SERIAL_SOFTWARE_FIFO);
-	buf_info.rx_put = 0;
-	buf_info.rx_get = 0;
-
-	if (in_8((u8 *)ACTING_UART0_BASE + UART_MSR) & 0x10)
-		serial_puts ("Check CTS signal present on serial port: OK.\n");
-	else
-		serial_puts ("WARNING: CTS signal not present on serial port.\n");
-
-	irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ ,
-			      serial_isr /*interrupt_handler_t *handler */ ,
-			      (void *) &buf_info /*void *arg */ );
-
-	/* Enable "RX Data Available" Interrupt on UART */
-	out_8(ACTING_UART0_BASE + UART_IER, 0x01);
-	/* Set DTR active */
-	out_8(ACTING_UART0_BASE + UART_MCR,
-	      in_8((u8 *)ACTING_UART0_BASE + UART_MCR) | 0x01);
-	/* Start flow by setting RTS active */
-	out_8(ACTING_UART0_BASE + UART_MCR,
-	      in_8((u8 *)ACTING_UART0_BASE + UART_MCR) | 0x02);
-	/* Setup UART FIFO: RX trigger level: 4 byte, Enable FIFO */
-	out_8(ACTING_UART0_BASE + UART_FCR, (1 << 6) | 1);
-}
-
-void serial_buffered_putc (const char c)
-{
-	/* Wait for CTS */
-#if defined(CONFIG_HW_WATCHDOG)
-	while (!(in_8((u8 *)ACTING_UART0_BASE + UART_MSR) & 0x10))
-		WATCHDOG_RESET ();
-#else
-	while (!(in_8((u8 *)ACTING_UART0_BASE + UART_MSR) & 0x10));
-#endif
-	serial_putc (c);
-}
-
-void serial_buffered_puts (const char *s)
-{
-	serial_puts (s);
-}
-
-int serial_buffered_getc (void)
-{
-	int space;
-	int c;
-	int rx_get = buf_info.rx_get;
-	int rx_put;
-
-#if defined(CONFIG_HW_WATCHDOG)
-	while (rx_get == buf_info.rx_put)
-		WATCHDOG_RESET ();
-#else
-	while (rx_get == buf_info.rx_put);
-#endif
-	c = buf_info.rx_buffer[rx_get++];
-	if (rx_get == CONFIG_SERIAL_SOFTWARE_FIFO)
-		rx_get = 0;
-	buf_info.rx_get = rx_get;
-
-	rx_put = buf_info.rx_put;
-	if (rx_get <= rx_put)
-		space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
-	else
-		space = rx_get - rx_put;
-
-	if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) {
-		/* Start flow by setting RTS active */
-		out_8(ACTING_UART0_BASE + UART_MCR,
-		      in_8((u8 *)ACTING_UART0_BASE + UART_MCR) | 0x02);
-	}
-
-	return c;
-}
-
-int serial_buffered_tstc (void)
-{
-	return (buf_info.rx_get != buf_info.rx_put) ? 1 : 0;
-}
-
-#endif	/* CONFIG_SERIAL_SOFTWARE_FIFO */
-
-#if defined(CONFIG_CMD_KGDB)
-/*
-  AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port
-  number 0 or number 1
-  - if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 :
-  configuration has been already done
-  - if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 :
-  configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE
-*/
-#if (CONFIG_KGDB_SER_INDEX & 2)
-void kgdb_serial_init (void)
-{
-	u8 val;
-	u16 br_reg;
-
-	get_clocks ();
-	br_reg = (((((gd->cpu_clk / 16) / 18) * 10) / CONFIG_KGDB_BAUDRATE) +
-		  5) / 10;
-	/*
-	 * Init onboard 16550 UART
-	 */
-	out_8((u8 *)ACTING_UART1_BASE + UART_LCR, 0x80);	/* set DLAB bit */
-	out_8((u8 *)ACTING_UART1_BASE + UART_DLL, (br_reg & 0x00ff)); /* set divisor for 9600 baud */
-	out_8((u8 *)ACTING_UART1_BASE + UART_DLM, ((br_reg & 0xff00) >> 8)); /* set divisor for 9600 baud */
-	out_8((u8 *)ACTING_UART1_BASE + UART_LCR, 0x03);	/* line control 8 bits no parity */
-	out_8((u8 *)ACTING_UART1_BASE + UART_FCR, 0x00);	/* disable FIFO */
-	out_8((u8 *)ACTING_UART1_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in_8((u8 *)ACTING_UART1_BASE + UART_LSR);		/* clear line status */
-	val = in_8((u8 *)ACTING_UART1_BASE + UART_RBR);		/* read receive buffer */
-	out_8((u8 *)ACTING_UART1_BASE + UART_SCR, 0x00);	/* set scratchpad */
-	out_8((u8 *)ACTING_UART1_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
-}
-
-void putDebugChar (const char c)
-{
-	if (c == '\n')
-		serial_putc ('\r');
-
-	out_8((u8 *)ACTING_UART1_BASE + UART_THR, c);	/* put character out */
-
-	/* check THRE bit, wait for transfer done */
-	while ((in_8((u8 *)ACTING_UART1_BASE + UART_LSR) & 0x20) != 0x20);
-}
-
-void putDebugStr (const char *s)
-{
-	while (*s)
-		serial_putc (*s++);
-}
-
-int getDebugChar (void)
-{
-	unsigned char status = 0;
-
-	while (1) {
-		status = in_8((u8 *)ACTING_UART1_BASE + UART_LSR);
-		if ((status & asyncLSRDataReady1) != 0x0)
-			break;
-
-		if ((status & (asyncLSRFramingError1 |
-			       asyncLSROverrunError1 |
-			       asyncLSRParityError1  |
-			       asyncLSRBreakInterrupt1 )) != 0) {
-			out_8((u8 *)ACTING_UART1_BASE + UART_LSR,
-			      asyncLSRFramingError1 |
-			      asyncLSROverrunError1 |
-			      asyncLSRParityError1  |
-			      asyncLSRBreakInterrupt1);
-		}
-	}
-
-	return (0x000000ff & (int) in_8((u8 *)ACTING_UART1_BASE));
-}
-
-void kgdb_interruptible (int yes)
-{
-	return;
-}
-
-#else	/* ! (CONFIG_KGDB_SER_INDEX & 2) */
-
-void kgdb_serial_init (void)
-{
-	serial_printf ("[on serial] ");
-}
-
-void putDebugChar (int c)
-{
-	serial_putc (c);
-}
-
-void putDebugStr (const char *str)
-{
-	serial_puts (str);
-}
-
-int getDebugChar (void)
-{
-	return serial_getc ();
-}
-
-void kgdb_interruptible (int yes)
-{
-	return;
-}
-#endif	/* (CONFIG_KGDB_SER_INDEX & 2) */
+	get_sys_info(&sys_info);
+	gd->uart_clk = sys_info.freqUART / udiv;
 #endif
 
-
-#if defined(CONFIG_SERIAL_MULTI)
-int serial0_init(void)
-{
-	return (serial_init_dev(UART0_BASE));
+	return clk;
 }
-
-int serial1_init(void)
-{
-	return (serial_init_dev(UART1_BASE));
-}
-
-void serial0_setbrg (void)
-{
-	serial_setbrg_dev(UART0_BASE);
-}
-
-void serial1_setbrg (void)
-{
-	serial_setbrg_dev(UART1_BASE);
-}
-
-void serial0_putc(const char c)
-{
-	serial_putc_dev(UART0_BASE,c);
-}
-
-void serial1_putc(const char c)
-{
-	serial_putc_dev(UART1_BASE, c);
-}
-
-void serial0_puts(const char *s)
-{
-	serial_puts_dev(UART0_BASE, s);
-}
-
-void serial1_puts(const char *s)
-{
-	serial_puts_dev(UART1_BASE, s);
-}
-
-int serial0_getc(void)
-{
-	return(serial_getc_dev(UART0_BASE));
-}
-
-int serial1_getc(void)
-{
-	return(serial_getc_dev(UART1_BASE));
-}
-
-int serial0_tstc(void)
-{
-	return (serial_tstc_dev(UART0_BASE));
-}
-
-int serial1_tstc(void)
-{
-	return (serial_tstc_dev(UART1_BASE));
-}
-
-struct serial_device serial0_device =
-{
-	"serial0",
-	"UART0",
-	serial0_init,
-	NULL,
-	serial0_setbrg,
-	serial0_getc,
-	serial0_tstc,
-	serial0_putc,
-	serial0_puts,
-};
-
-struct serial_device serial1_device =
-{
-	"serial1",
-	"UART1",
-	serial1_init,
-	NULL,
-	serial1_setbrg,
-	serial1_getc,
-	serial1_tstc,
-	serial1_putc,
-	serial1_puts,
-};
-#else
-/*
- * Wrapper functions
- */
-int serial_init(void)
-{
-	return serial_init_dev(ACTING_UART0_BASE);
-}
-
-void serial_setbrg(void)
-{
-	serial_setbrg_dev(ACTING_UART0_BASE);
-}
-
-void serial_putc(const char c)
-{
-	serial_putc_dev(ACTING_UART0_BASE, c);
-}
-
-void serial_puts(const char *s)
-{
-	serial_puts_dev(ACTING_UART0_BASE, s);
-}
-
-int serial_getc(void)
-{
-	return serial_getc_dev(ACTING_UART0_BASE);
-}
-
-int serial_tstc(void)
-{
-	return serial_tstc_dev(ACTING_UART0_BASE);
-}
-#endif /* CONFIG_SERIAL_MULTI */
-
 #endif	/* CONFIG_405GP || CONFIG_405CR */
diff --git a/arch/powerpc/include/asm/ppc405cr.h b/arch/powerpc/include/asm/ppc405cr.h
index 176c427..01078f7 100644
--- a/arch/powerpc/include/asm/ppc405cr.h
+++ b/arch/powerpc/include/asm/ppc405cr.h
@@ -24,7 +24,12 @@
 #define CONFIG_SDRAM_PPC4xx_IBM_SDRAM	/* IBM SDRAM controller */
 
 /* Memory mapped register */
-#define GPIO0_BASE	0xef600700
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0400)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
 
 /* DCR's */
 #define DCP0_CFGADDR	0x0014		/* Decompression controller addr reg */
diff --git a/arch/powerpc/include/asm/ppc405ep.h b/arch/powerpc/include/asm/ppc405ep.h
index e0b6a85..9691604 100644
--- a/arch/powerpc/include/asm/ppc405ep.h
+++ b/arch/powerpc/include/asm/ppc405ep.h
@@ -24,7 +24,12 @@
 #define CONFIG_SDRAM_PPC4xx_IBM_SDRAM	/* IBM SDRAM controller */
 
 /* Memory mapped register */
-#define GPIO0_BASE	0xef600700
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0400)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
 
 /* DCR */
 #define OCM0_ISCNTL	0x0019	/* OCM I-side control reg */
diff --git a/arch/powerpc/include/asm/ppc405ex.h b/arch/powerpc/include/asm/ppc405ex.h
index 880d53a..36d3149 100644
--- a/arch/powerpc/include/asm/ppc405ex.h
+++ b/arch/powerpc/include/asm/ppc405ex.h
@@ -26,7 +26,12 @@
 #define CONFIG_NAND_NDFC
 
 /* Memory mapped register */
-#define GPIO0_BASE		0xef600800
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0200)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0800)
 
 /* SDR */
 #define SDR0_SDCS0		0x0060
diff --git a/arch/powerpc/include/asm/ppc405ez.h b/arch/powerpc/include/asm/ppc405ez.h
index 9192c62..cb8e994 100644
--- a/arch/powerpc/include/asm/ppc405ez.h
+++ b/arch/powerpc/include/asm/ppc405ez.h
@@ -24,8 +24,13 @@
 #define CONFIG_NAND_NDFC
 
 /* Memory mapped register */
-#define GPIO0_BASE	0xef600700
-#define GPIO1_BASE	0xef600800
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0400)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
+#define GPIO1_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0800)
 
 /* DCR register */
 #define OCM0_PLBCR1	0x0020	/* OCM PLB3 Bank 1 Config */
diff --git a/arch/powerpc/include/asm/ppc405gp.h b/arch/powerpc/include/asm/ppc405gp.h
index 79f930b..91beeb8 100644
--- a/arch/powerpc/include/asm/ppc405gp.h
+++ b/arch/powerpc/include/asm/ppc405gp.h
@@ -24,7 +24,12 @@
 #define CONFIG_SDRAM_PPC4xx_IBM_SDRAM	/* IBM SDRAM controller */
 
 /* Memory mapped register */
-#define GPIO0_BASE	0xef600700
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0400)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
 
 /* DCR's */
 #define DCP0_CFGADDR	0x0014		/* Decompression controller addr reg */
diff --git a/arch/powerpc/include/asm/ppc440ep_gr.h b/arch/powerpc/include/asm/ppc440ep_gr.h
index 0fd4019..dfd1532 100644
--- a/arch/powerpc/include/asm/ppc440ep_gr.h
+++ b/arch/powerpc/include/asm/ppc440ep_gr.h
@@ -28,9 +28,19 @@
 /*
  * Some SoC specific registers (not common for all 440 SoC's)
  */
-#define GPIO0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000B00)
-#define GPIO1_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000C00)
 
+/* Memory mapped registers */
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0400)
+#define CONFIG_SYS_NS16550_COM3	(CONFIG_SYS_PERIPHERAL_BASE + 0x0500)
+#define CONFIG_SYS_NS16550_COM4	(CONFIG_SYS_PERIPHERAL_BASE + 0x0600)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0b00)
+#define GPIO1_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0c00)
+
+/* SDR's */
 #define SDR0_PCI0	0x0300
 #define SDR0_SDSTP2	0x4001
 #define SDR0_SDSTP3	0x4003
diff --git a/arch/powerpc/include/asm/ppc440epx_grx.h b/arch/powerpc/include/asm/ppc440epx_grx.h
index e0d7e3f..252f35b 100644
--- a/arch/powerpc/include/asm/ppc440epx_grx.h
+++ b/arch/powerpc/include/asm/ppc440epx_grx.h
@@ -30,9 +30,15 @@
  */
 
 /* Memory mapped registers */
-#define SPI0_MODE		0xef600090
-#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x00000B00)
-#define GPIO1_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x00000C00)
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define SPI0_MODE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0090)
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0400)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0b00)
+#define GPIO1_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0c00)
 
 /* DCR */
 #define CPM0_ER			0x00b0
diff --git a/arch/powerpc/include/asm/ppc440gp.h b/arch/powerpc/include/asm/ppc440gp.h
index 0c95e91..3ebe2a1 100644
--- a/arch/powerpc/include/asm/ppc440gp.h
+++ b/arch/powerpc/include/asm/ppc440gp.h
@@ -26,7 +26,14 @@
 /*
  * Some SoC specific registers (not common for all 440 SoC's)
  */
-#define GPIO0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000700)
+
+/* Memory mapped register */
+#define CONFIG_SYS_PERIPHERAL_BASE	0xe0000000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0200)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
 
 #define SDR0_PCI0	0x0300
 
diff --git a/arch/powerpc/include/asm/ppc440gx.h b/arch/powerpc/include/asm/ppc440gx.h
index 157e467..6f8581b 100644
--- a/arch/powerpc/include/asm/ppc440gx.h
+++ b/arch/powerpc/include/asm/ppc440gx.h
@@ -26,8 +26,16 @@
 /*
  * Some SoC specific registers (not common for all 440 SoC's)
  */
-#define GPIO0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000700)
 
+/* Memory mapped register */
+#define CONFIG_SYS_PERIPHERAL_BASE	0xe0000000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0200)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
+
+/* SDR's */
 #define SDR0_PCI0	0x0300
 
 #define SDR0_SDSTP2	0x4001
diff --git a/arch/powerpc/include/asm/ppc440sp.h b/arch/powerpc/include/asm/ppc440sp.h
index eb7e1d9..4387495 100644
--- a/arch/powerpc/include/asm/ppc440sp.h
+++ b/arch/powerpc/include/asm/ppc440sp.h
@@ -26,8 +26,16 @@
 /*
  * Some SoC specific registers (not common for all 440 SoC's)
  */
-#define GPIO0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000700)
 
+/* Memory mapped register */
+#define CONFIG_SYS_PERIPHERAL_BASE	0xf0000000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0200)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
+
+/* SDR's */
 #define SDR0_PCI0	0x0300
 #define SDR0_SDSTP2	0x0022
 #define SDR0_SDSTP3	0x0023
diff --git a/arch/powerpc/include/asm/ppc440spe.h b/arch/powerpc/include/asm/ppc440spe.h
index 05fe104..bad9a40 100644
--- a/arch/powerpc/include/asm/ppc440spe.h
+++ b/arch/powerpc/include/asm/ppc440spe.h
@@ -27,8 +27,15 @@
  * Some SoC specific registers (not common for all 440 SoC's)
  */
 
-#define GPIO0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000700)
+/* Memory mapped register */
+#define CONFIG_SYS_PERIPHERAL_BASE	0xa0000000 /* Internal Peripherals */
 
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0200)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
+
+/* SDR's */
 #define SDR0_PCI0	0x0300
 #define SDR0_SDSTP2	0x0022
 #define SDR0_SDSTP3	0x0023
diff --git a/arch/powerpc/include/asm/ppc460ex_gt.h b/arch/powerpc/include/asm/ppc460ex_gt.h
index 04c3fbe..732fcac 100644
--- a/arch/powerpc/include/asm/ppc460ex_gt.h
+++ b/arch/powerpc/include/asm/ppc460ex_gt.h
@@ -29,8 +29,16 @@
  * Some SoC specific registers
  */
 
-#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x00000B00)
-#define GPIO1_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x00000C00)
+/* Memory mapped registers */
+#define CONFIG_SYS_PERIPHERAL_BASE	0xef600000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0400)
+#define CONFIG_SYS_NS16550_COM3	(CONFIG_SYS_PERIPHERAL_BASE + 0x0500)
+#define CONFIG_SYS_NS16550_COM4	(CONFIG_SYS_PERIPHERAL_BASE + 0x0600)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0b00)
+#define GPIO1_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0c00)
 
 /* DCR */
 #define AHB_TOP			0x00a4
diff --git a/arch/powerpc/include/asm/ppc460sx.h b/arch/powerpc/include/asm/ppc460sx.h
index cb72e28..f93ef0e 100644
--- a/arch/powerpc/include/asm/ppc460sx.h
+++ b/arch/powerpc/include/asm/ppc460sx.h
@@ -23,7 +23,13 @@
 
 #define CONFIG_SDRAM_PPC4xx_IBM_DDR2	/* IBM DDR(2) controller */
 
-#define GPIO0_BASE	(CONFIG_SYS_PERIPHERAL_BASE + 0x00000700)
+/* Memory mapped registers */
+#define CONFIG_SYS_PERIPHERAL_BASE	0xa0000000 /* Internal Peripherals */
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_PERIPHERAL_BASE + 0x0200)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+
+#define GPIO0_BASE		(CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
 
 #define SDR0_SRST0_DMC			0x00200000
 
diff --git a/arch/powerpc/include/asm/ppc4xx.h b/arch/powerpc/include/asm/ppc4xx.h
index 15be343..87a16ec 100644
--- a/arch/powerpc/include/asm/ppc4xx.h
+++ b/arch/powerpc/include/asm/ppc4xx.h
@@ -202,6 +202,22 @@
 #define GPT0_DCT0		0x00000110
 #define GPT0_DCIS		0x0000011C
 
+#if 0 // test-only
+/*
+ * All PPC4xx share the same NS16550 UART(s). Only base addresses
+ * may differ. We define here the integration of the common NS16550
+ * driver for all PPC4xx SoC's. The board config header must specify
+ * on which UART the console should be located via CONFIG_CONS_INDEX.
+ */
+#if 0 /* test-only */
+#define CONFIG_SERIAL_MULTI
+#endif
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	1
+#define CONFIG_SYS_NS16550_CLK		get_serial_clock()
+#endif
+
 #if defined(CONFIG_440)
 #include <asm/ppc440.h>
 #else