Add port for the lpc2292sodimm evaluation board from EmbeddedArtists
diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c
index a5b6de7..60c1aa9 100644
--- a/cpu/arm720t/cpu.c
+++ b/cpu/arm720t/cpu.c
@@ -73,7 +73,7 @@
 	/* go to high speed */
 	IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73;
 #endif
-#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B)
+#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292)
 	disable_interrupts ();
 	/* Nothing more needed */
 #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
@@ -252,6 +252,7 @@
 	void icache_enable (void)
 	{
 	}
+#elif defined(CONFIG_LPC2292) /* just to satisfy the compiler */
 #else
 #error No icache/dcache enable/disable functions defined for this CPU type
 #endif
diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c
index da62502..8f32124 100644
--- a/cpu/arm720t/interrupts.c
+++ b/cpu/arm720t/interrupts.c
@@ -36,6 +36,12 @@
 #define TIMER_LOAD_VAL 0xffff
 /* macro to read the 16 bit timer */
 #define READ_TIMER (IO_TC1D & 0xffff)
+
+#ifdef CONFIG_LPC2292
+#undef READ_TIMER
+#define READ_TIMER (0xFFFFFFFF - GET32(T0TC))
+#endif
+
 #else
 #define IRQEN	(*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE))
 #define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL))
@@ -195,6 +201,13 @@
 	}
 #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
 	/* No do_irq() for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+
+    void (*pfnct)(void);
+
+    pfnct = (void (*)(void))VICVectAddr;
+
+    (*pfnct)();
 #else
 #error do_irq() not defined for this CPU type
 #endif
@@ -293,6 +306,13 @@
 
 	/* Start timer */
 	SET_REG( REG_TMOD, TM0_RUN);
+#elif defined(CONFIG_LPC2292)
+	PUT32(T0IR, 0);		/* disable all timer0 interrupts */
+	PUT32(T0TCR, 0);	/* disable timer0 */
+	PUT32(T0PR, CFG_SYS_CLK_FREQ / CFG_HZ);
+ 	PUT32(T0MCR, 0);
+	PUT32(T0TC, 0);
+	PUT32(T0TCR, 1);	/* enable timer0 */
 
 #else
 #error No interrupt_init() defined for this CPU type
@@ -309,7 +329,7 @@
  */
 
 
-#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO)
+#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) || defined(CONFIG_LPC2292)
 
 void reset_timer (void)
 {
@@ -337,7 +357,12 @@
 	tmo += get_timer (0);
 
 	while (get_timer_masked () < tmo)
+#ifdef CONFIG_LPC2292
+		/* GJ - not sure whether this is really needed or a misunderstanding */
+		__asm__ __volatile__(" nop");
+#else
 		/*NOP*/;
+#endif
 }
 
 void reset_timer_masked (void)
diff --git a/cpu/arm720t/serial.c b/cpu/arm720t/serial.c
index 054bab9..15c54af 100644
--- a/cpu/arm720t/serial.c
+++ b/cpu/arm720t/serial.c
@@ -123,4 +123,80 @@
 	}
 }
 
-#endif /* defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) */
+#elif defined(CONFIG_LPC2292)
+
+#include <asm/arch/hardware.h>
+
+void serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	unsigned short divisor = 0;
+
+	switch (gd->baudrate) {
+	case   1200:	divisor = 3072;	break;
+	case   9600:	divisor =  384;	break;
+	case  19200:	divisor =  192;	break;
+	case  38400:	divisor =   96;	break;
+	case  57600:	divisor =   64;	break;
+	case 115200:	divisor =   32;	break;
+	default:	hang ();	break;
+	}
+
+	/* init serial UART0 */
+	PUT8(U0LCR, 0);
+	PUT8(U0IER, 0);
+	PUT8(U0LCR, 0x80);	/* DLAB=1 */
+	PUT8(U0DLL, (unsigned char)(divisor & 0x00FF));
+	PUT8(U0DLM, (unsigned char)(divisor >> 8));
+	PUT8(U0LCR, 0x03);	/* 8N1, DLAB=0  */
+	PUT8(U0FCR, 1);		/* Enable RX and TX FIFOs */
+}
+
+int serial_init (void)
+{
+	unsigned long pinsel0;
+
+	serial_setbrg ();
+
+	pinsel0 = GET32(PINSEL0);
+	pinsel0 &= ~(0x00000003);
+	pinsel0 |= 5;
+	PUT32(PINSEL0, pinsel0);
+
+	return (0);
+}
+
+void serial_putc (const char c)
+{
+	if (c == '\n')
+	{
+		while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */
+		PUT8(U0THR, '\r');
+	}
+
+	while((GET8(U0LSR) & (1<<5)) == 0); /* Wait for empty U0THR */
+	PUT8(U0THR, c);
+}
+
+int serial_getc (void)
+{
+	while((GET8(U0LSR) & 1) == 0);
+	return GET8(U0RBR);
+}
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
+
+/* Test if there is a byte to read */
+int serial_tstc (void)
+{
+	return (GET8(U0LSR) & 1);
+}
+
+#endif
diff --git a/cpu/arm720t/start.S b/cpu/arm720t/start.S
index e66d109..96d5f54 100644
--- a/cpu/arm720t/start.S
+++ b/cpu/arm720t/start.S
@@ -43,7 +43,11 @@
 	ldr	pc, _software_interrupt
 	ldr	pc, _prefetch_abort
 	ldr	pc, _data_abort
+#ifdef CONFIG_LPC2292
+	.word	0xB4405F76 /* 2's complement of the checksum of the vectors */
+#else
 	ldr	pc, _not_used
+#endif
 	ldr	pc, _irq
 	ldr	pc, _fiq
 
@@ -123,6 +127,10 @@
 	bl	cpu_init_crit
 #endif
 
+#ifdef CONFIG_LPC2292
+	bl	lowlevel_init
+#endif
+
 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
 relocate:				/* relocate U-Boot to RAM	    */
 	adr	r0, _start		/* r0 <- current position of code   */
@@ -131,6 +139,7 @@
 	beq	stack_setup
 
 #if TEXT_BASE
+#ifndef CONFIG_LPC2292 /* already done in lowlevel_init */
 	ldr	r2, =0x0		/* Relocate the exception vectors   */
 	cmp	r1, r2			/* and associated data to address   */
 	ldmneia r0!, {r3-r10}		/* 0x0. Do nothing if TEXT_BASE is  */
@@ -138,6 +147,7 @@
 	ldmneia r0, {r3-r9}
 	stmneia r2, {r3-r9}
 	adrne	r0, _start		/* restore r0			    */
+#endif	/* !CONFIG_LPC2292 */
 #endif
 
 	ldr	r2, _armboot_start
@@ -206,6 +216,14 @@
 #define CLKCTL_49      0x4  /* 49.152 MHz */
 #define CLKCTL_73      0x6  /* 73.728 MHz */
 
+#elif defined(CONFIG_LPC2292)
+PLLCFG_ADR:	.word	PLLCFG
+PLLFEED_ADR:	.word	PLLFEED
+PLLCON_ADR:	.word	PLLCON
+PLLSTAT_ADR:	.word	PLLSTAT
+VPBDIV_ADR:	.word	VPBDIV
+MEMMAP_ADR:	.word	MEMMAP
+
 #endif
 
 cpu_init_crit:
@@ -306,6 +324,50 @@
 
 #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
 	/* No specific initialisation for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+	/* Set-up PLL */
+	mov	r3, #0xAA
+	mov	r4, #0x55
+	/* First disconnect and disable the PLL */	
+	ldr	r0, PLLCON_ADR
+	mov	r1, #0x00
+	str	r1, [r0]
+	ldr	r0, PLLFEED_ADR /* start feed sequence */
+	str	r3, [r0]
+	str	r4, [r0]	/* feed sequence done */	
+	/* Set new M and P values */
+	ldr	r0, PLLCFG_ADR
+	mov	r1, #0x23	/* M=4 and P=2 */
+	str	r1, [r0]
+	ldr	r0, PLLFEED_ADR /* start feed sequence */
+	str	r3, [r0]
+	str	r4, [r0]	/* feed sequence done */
+	/* Then enable the PLL */
+	ldr	r0, PLLCON_ADR
+	mov	r1, #0x01	/* PLL enable bit */
+	str	r1, [r0]
+	ldr	r0, PLLFEED_ADR /* start feed sequence */
+	str	r3, [r0]
+	str	r4, [r0]	/* feed sequence done */
+	/* Wait for the lock */	
+	ldr	r0, PLLSTAT_ADR
+	mov	r1, #0x400	/* lock bit */
+lock_loop:	
+	ldr	r2, [r0]
+	and	r2, r1, r2
+	cmp	r2, #0
+	beq	lock_loop
+	/* And finally connect the PLL */
+	ldr	r0, PLLCON_ADR
+	mov	r1, #0x03	/* PLL enable bit and connect bit */
+	str	r1, [r0]
+	ldr	r0, PLLFEED_ADR /* start feed sequence */
+	str	r3, [r0]
+	str	r4, [r0]	/* feed sequence done */		
+	/* Set-up VPBDIV register */
+	ldr	r0, VPBDIV_ADR
+	mov	r1, #0x01	/* VPB clock is same as process clock */
+	str	r1, [r0]
 #else
 #error No cpu_init_crit() defined for current CPU type
 #endif
@@ -321,6 +383,7 @@
 	str	r1, [r0]
 #endif
 
+#ifndef CONFIG_LPC2292
 	mov	ip, lr
 	/*
 	 * before relocating, we have to setup RAM timing
@@ -329,6 +392,7 @@
 	 */
 	bl	lowlevel_init
 	mov	lr, ip
+#endif
 
 	mov	pc, lr
 
@@ -537,6 +601,11 @@
  * on external peripherals such as watchdog timers, etc. */
 #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
 	/* No specific reset actions for IntegratorAP/CM720T as yet */
+#elif defined(CONFIG_LPC2292)
+	.align	5
+.globl reset_cpu
+reset_cpu:
+	mov	pc, r0
 #else
 #error No reset_cpu() defined for current CPU type
 #endif