[U-Boot] [PATCH 1/2] LPC2468 support

Remco Poelstra
2009-04-24T11:57:35Z

This patch includes support for the LPC2468 processor from NXP.

Signed-off-by: Remco Poelstra <remco.poelstra+u-boot@duran-audio.com>
---
A working board example will be submitted when this patch is found to be OK.
This patch is against latest git.
The previous problem with PUTx vs. writex is solved.

From 75361079ed78fb40c2840b3bd74687153e486620 Mon Sep 17 00:00:00 2001
From: Remco Poelstra <remco.poelstra+u-boot@duran-audio.com>
Date: Fri, 24 Apr 2009 12:18:21 +0200
Subject: [PATCH] Support for LPC2468 processor from NXP

---
Makefile | 3 +
cpu/arm720t/cpu.c | 2 +-
cpu/arm720t/interrupts.c | 37 +++-
cpu/arm720t/lpc24xx/Makefile | 50 +++++
cpu/arm720t/lpc24xx/flash.c | 233 ++++++++++++++++++++
cpu/arm720t/lpc24xx/iap_entry.S | 7 +
cpu/arm720t/start.S | 11 +-
drivers/serial/Makefile | 1 +
drivers/serial/serial_lpc2468.c | 119 +++++++++++
include/asm-arm/arch-lpc24xx/hardware.h | 32 +++
include/asm-arm/arch-lpc24xx/immap.h | 351 +++++++++++++++++++++++++++++++
include/asm-arm/config.h | 4 +
include/flash.h | 1 +
13 files changed, 842 insertions(+), 9 deletions(-)
create mode 100644 cpu/arm720t/lpc24xx/Makefile
create mode 100644 cpu/arm720t/lpc24xx/flash.c
create mode 100644 cpu/arm720t/lpc24xx/iap_entry.S
create mode 100644 drivers/serial/serial_lpc2468.c
create mode 100644 include/asm-arm/arch-lpc24xx/hardware.h
create mode 100644 include/asm-arm/arch-lpc24xx/immap.h

diff --git a/Makefile b/Makefile
index e91c051..fb23ee6 100644
--- a/Makefile
+++ b/Makefile
@@ -2940,6 +2940,9 @@ B2_config : unconfig
## ARM720T Systems
#########################################################################

+LPC2468_config: unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm720t LPC2468 NULL lpc24xx
+
armadillo_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm720t armadillo

diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c
index 6c40903..b3a2853 100644
--- a/cpu/arm720t/cpu.c
+++ b/cpu/arm720t/cpu.c
@@ -75,7 +75,7 @@ int cleanup_before_linux (void)
/* go to high speed */
IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73;
#endif
-#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292)
+#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2000)
disable_interrupts ();
/* Nothing more needed */
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c
index 39ed345..d7aec27 100644
--- a/cpu/arm720t/interrupts.c
+++ b/cpu/arm720t/interrupts.c
@@ -29,17 +29,26 @@
#include <common.h>
#include <clps7111.h>
#include <asm/proc-armv/ptrace.h>
+#include <asm/io.h>
+#if defined(CONFIG_LPC2468)
+#include <asm/arch/immap.h>
+#else
#include <asm/hardware.h>
+#endif

#ifndef CONFIG_NETARM
+
+#if defined(CONFIG_LPC2292)
+#define TIMER_LOAD_VAL 0xffff
+#define READ_TIMER (0xFFFFFFFF - GET32(T0TC))
+#elif defined(CONFIG_LPC2468)
+#define TIMER_LOAD_VAL 0
+#define READ_TIMER (0xFFFFFFFF - 0xE0004008)
+#else
/* we always count down the max. */
#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
@@ -80,6 +89,14 @@ void do_irq (struct pt_regs *pt_regs)
pfnct = (void (*)(void))VICVectAddr;

(*pfnct)();
+#elif defined(CONFIG_LPC2468)
+ void (*pfnct) (void);
+ vic_2468_t *vic = &(((immap_t *)CONFIG_SYS_IMMAP)->ahb.vic);
+
+ pfnct = (void (*)(void))(&(vic->vicaddr));
+
+ (*pfnct) ();
+
#else
#error do_irq() not defined for this CPU type
#endif
@@ -112,6 +129,9 @@ static ulong lastdec;

int interrupt_init (void)
{
+#if defined(CONFIG_LPC2468)
+ timer_2468_t *timer0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.timer0);
+#endif

#if defined(CONFIG_NETARM)
/* disable all interrupts */
@@ -185,6 +205,13 @@ int interrupt_init (void)
PUT32(T0MCR, 0);
PUT32(T0TC, 0);
PUT32(T0TCR, 1); /* enable timer0 */
+#elif defined(CONFIG_LPC2468)
+ writel (0, &(timer0->ir)); /*disable all timer0 interupts */
+ writel (0, &(timer0->tcr)); /*disable timer0 */
+ writel (CFG_SYS_CLK_FREQ / CONFIG_SYS_HZ - 1, &(timer0->pr));
+ writel (0, &(timer0->mcr));
+ writel (0, &(timer0->tc));
+ writel (1, &(timer0->tcr));

#else
#error No interrupt_init() defined for this CPU type
@@ -201,7 +228,7 @@ int interrupt_init (void)
*/

-#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) || defined(CONFIG_LPC2292)
+#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) || defined(CONFIG_LPC2000)

void reset_timer (void)
{
diff --git a/cpu/arm720t/lpc24xx/Makefile b/cpu/arm720t/lpc24xx/Makefile
new file mode 100644
index 0000000..f091502
--- /dev/null
+++ b/cpu/arm720t/lpc24xx/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd at 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
+
+LIB = $(obj)lib$(SOC).a
+
+COBJS = flash.o
+SOBJS = $(obj)iap_entry.o
+
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+# this MUST be compiled as thumb code!
+$(SOBJS):
+ $(CC) $(AFLAGS) -march=armv4t -c -o $(SOBJS) iap_entry.S
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm720t/lpc24xx/flash.c b/cpu/arm720t/lpc24xx/flash.c
new file mode 100644
index 0000000..46a1a56
--- /dev/null
+++ b/cpu/arm720t/lpc24xx/flash.c
@@ -0,0 +1,233 @@
+/*
+ * (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com>
+ *
+ * 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/io.h>
+#include <asm/arch/immap.h>
+/* IAP commands use 32 bytes at the top of CPU internal sram, we
+ use 512 bytes below that */
+#define COPY_BUFFER_LOCATION 0x4000fde0
+
+#define IAP_LOCATION 0x7ffffff1
+#define IAP_CMD_PREPARE 50
+#define IAP_CMD_COPY 51
+#define IAP_CMD_ERASE 52
+#define IAP_CMD_CHECK 53
+#define IAP_CMD_ID 54
+#define IAP_CMD_VERSION 55
+#define IAP_CMD_COMPARE 56
+
+#define IAP_RET_CMD_SUCCESS 0
+
+static unsigned long command[5];
+static unsigned long result[2];
+
+extern void iap_entry (unsigned long *command, unsigned long *result);
+
+/*-----------------------------------------------------------------------
+ *
+ */
+int get_flash_sector (flash_info_t * info, ulong flash_addr)
+{
+ int i;
+
+ for (i = 1; i < (info->sector_count); i++) {
+ if (flash_addr < (info->start[i]))
+ break;
+ }
+
+ return (i - 1);
+}
+
+/*-----------------------------------------------------------------------
+ * This function assumes that flash_addr is aligned on 512 bytes boundary
+ * in flash. This function also assumes that prepare have been called
+ * for the sector in question.
+ */
+int lpc24xx_copy_buffer_to_flash (flash_info_t * info, ulong flash_addr)
+{
+ int first_sector;
+ int last_sector;
+
+ first_sector = get_flash_sector (info, flash_addr);
+ last_sector = get_flash_sector (info, flash_addr + 512 - 1);
+
+ /* prepare sectors for write */
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = first_sector;
+ command[2] = last_sector;
+ iap_entry (command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf ("IAP prepare failed\n");
+ return ERR_PROG_ERROR;
+ }
+
+ command[0] = IAP_CMD_COPY;
+ command[1] = flash_addr;
+ command[2] = COPY_BUFFER_LOCATION;
+ command[3] = 512;
+ command[4] = CFG_SYS_CLK_FREQ >> 10;
+ iap_entry (command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf ("IAP copy failed\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int lpc24xx_flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ int flag;
+ int prot;
+ int sect;
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+ flag = disable_interrupts ();
+
+ printf ("Erasing %d sectors starting at sector %2d.\n"
+ "This make take some time ... ", s_last - s_first + 1, s_first);
+
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = s_first;
+ command[2] = s_last;
+ iap_entry (command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf ("IAP prepare failed\n");
+ return ERR_PROTECTED;
+ }
+
+ command[0] = IAP_CMD_ERASE;
+ command[1] = s_first;
+ command[2] = s_last;
+ command[3] = CFG_SYS_CLK_FREQ >> 10;
+ iap_entry (command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf ("IAP erase failed\n");
+ return ERR_PROTECTED;
+ }
+
+ if (flag)
+ enable_interrupts ();
+
+ return ERR_OK;
+}
+
+int lpc24xx_write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ int first_copy_size;
+ int last_copy_size;
+ int first_block;
+ int last_block;
+ int nbr_mid_blocks;
+ sys_con_2468_t *sys_con=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.sys_con);
+ uchar memmap_value;
+ ulong i;
+ uchar *src_org;
+ uchar *dst_org;
+ int ret = ERR_OK;
+
+ src_org = src;
+ dst_org = (uchar *) addr;
+
+ first_block = addr / 512;
+ last_block = (addr + cnt) / 512;
+ nbr_mid_blocks = last_block - first_block - 1;
+
+ first_copy_size = 512 - (addr % 512);
+ last_copy_size = (addr + cnt) % 512;
+
+ debug ("\ncopy first block: (1) %lX -> %lX 0x200 bytes, "
+ "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX 0x200 bytes\n",
+ (ulong) (first_block * 512),
+ (ulong) COPY_BUFFER_LOCATION,
+ (ulong) src,
+ (ulong) (COPY_BUFFER_LOCATION + 512 - first_copy_size),
+ first_copy_size,
+ (ulong) COPY_BUFFER_LOCATION, (ulong) (first_block * 512));
+
+ /* copy first block */
+ memcpy ((void *)COPY_BUFFER_LOCATION, (void *)(first_block * 512), 512);
+ memcpy ((void *)(COPY_BUFFER_LOCATION + 512 - first_copy_size),
+ src, first_copy_size);
+ lpc24xx_copy_buffer_to_flash (info, first_block * 512);
+ src += first_copy_size;
+ addr += first_copy_size;
+
+ /* copy middle blocks */
+ for (i = 0; i < nbr_mid_blocks; i++) {
+ debug ("copy middle block: %lX -> %lX 512 bytes, "
+ "%lX -> %lX 512 bytes\n",
+ (ulong) src,
+ (ulong) COPY_BUFFER_LOCATION,
+ (ulong) COPY_BUFFER_LOCATION, (ulong) addr);
+ memcpy ((void *)COPY_BUFFER_LOCATION, src, 512);
+ lpc24xx_copy_buffer_to_flash (info, addr);
+ src += 512;
+ addr += 512;
+ }
+
+ if (last_copy_size > 0) {
+ debug ("copy last block: (1) %lX -> %lX 0x200 bytes, "
+ "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX x200 bytes\n",
+ (ulong) (last_block * 512),
+ (ulong) COPY_BUFFER_LOCATION,
+ (ulong) src,
+ (ulong) (COPY_BUFFER_LOCATION),
+ last_copy_size,
+ (ulong) COPY_BUFFER_LOCATION, (ulong) addr);
+ /* copy last block */
+ memcpy ((void *)COPY_BUFFER_LOCATION,
+ (void *)(last_block * 512), 512);
+ memcpy ((void *)COPY_BUFFER_LOCATION, src, last_copy_size);
+ lpc24xx_copy_buffer_to_flash (info, addr);
+ }
+
+ /* verify write */
+ memmap_value = readl(&(sys_con->memmap));
+
+ disable_interrupts ();
+
+ writel(01, &(sys_con->memmap)); /* we must make sure that initial 64
+ bytes are taken from flash when we
+ do the compare */
+
+ for (i = 0; i < cnt; i++) {
+ if (*dst_org != *src_org) {
+ printf ("Write failed. Byte %lX differs\n", i);
+ ret = ERR_PROG_ERROR;
+ break;
+ }
+ dst_org++;
+ src_org++;
+ }
+
+ writel(memmap_value, &(sys_con->memmap));
+ enable_interrupts ();
+
+ return ret;
+}
diff --git a/cpu/arm720t/lpc24xx/iap_entry.S b/cpu/arm720t/lpc24xx/iap_entry.S
new file mode 100644
index 0000000..c31d519
--- /dev/null
+++ b/cpu/arm720t/lpc24xx/iap_entry.S
@@ -0,0 +1,7 @@
+IAP_ADDRESS: .word 0x7FFFFFF1
+
+.globl iap_entry
+iap_entry:
+ ldr r2, IAP_ADDRESS
+ bx r2
+ mov pc, lr
diff --git a/cpu/arm720t/start.S b/cpu/arm720t/start.S
index 022b873..eca4d9f 100644
--- a/cpu/arm720t/start.S
+++ b/cpu/arm720t/start.S
@@ -127,7 +127,7 @@ reset:
bl cpu_init_crit
#endif

-#ifdef CONFIG_LPC2292
+#if defined(CONFIG_LPC2000)
bl lowlevel_init
#endif

@@ -368,6 +368,11 @@ lock_loop:
ldr r0, VPBDIV_ADR
mov r1, #0x01 /* VPB clock is same as process clock */
str r1, [r0]
+#elif defined(CONFIG_LPC2468)
+ ldr r0, =0x40008000 /*0x40000000 is internal SRAM,
+ 0x4000FFFF is end of SRAM*/
+ mov sp,r0
+ sub sl,sp,#0x2000
#else
#error No cpu_init_crit() defined for current CPU type
#endif
@@ -383,7 +388,7 @@ lock_loop:
str r1, [r0]
#endif

-#ifndef CONFIG_LPC2292
+#if !defined(CONFIG_LPC2000)
mov ip, lr
/*
* before relocating, we have to setup RAM timing
@@ -601,7 +606,7 @@ reset_cpu:
* 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)
+#elif defined(CONFIG_LPC2000)
.align 5
.globl reset_cpu
reset_cpu:
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index bb99a34..929fb5a 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -39,6 +39,7 @@ COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
COBJS-$(CONFIG_LPC2292_SERIAL) += serial_lpc2292.o
+COBJS-$(CONFIG_LPC2468_SERIAL) += serial_lpc2468.o
COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
COBJS-$(CONFIG_MX31_UART) += serial_mx31.o
COBJS-$(CONFIG_NETARM_SERIAL) += serial_netarm.o
diff --git a/drivers/serial/serial_lpc2468.c b/drivers/serial/serial_lpc2468.c
new file mode 100644
index 0000000..4b8f241
--- /dev/null
+++ b/drivers/serial/serial_lpc2468.c
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2002-2004
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw at its.tudelft.nl)
+ *
+ * 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/arch/immap.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void serial_setbrg (void)
+{
+ unsigned short divisor;
+ uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0);
+
+ switch (gd->baudrate) {
+ case 1200:
+ case 9600:
+ case 19200:
+ case 38400:
+ case 57600:
+ case 115200:
+ divisor = CFG_SYS_CLK_FREQ / (gd->baudrate * 16);
+ break;
+ default:
+ hang ();
+ break;
+ }
+
+ /* init serial UART0 */
+ writeb (0, &(uart0->iir_fcr)); /* Disable RX and TX FIFOs */
+ writeb (0, &(uart0->lcr));
+ writeb (0, &(uart0->ier_dlm));
+ writeb (0x80, &(uart0->lcr)); /* DLAB=1 */
+ writeb ((unsigned char)(divisor & 0x00FF), &(uart0->rbr_thr_dll));
+ writeb ((unsigned char)(divisor >> 8),&(uart0->ier_dlm));
+ writeb (0x03, &(uart0->lcr)); /* 8N1, DLAB=0 */
+ writeb (0x7, &(uart0->iir_fcr)); /* Enable RX and TX FIFOs */
+}
+
+int serial_init (void)
+{
+ unsigned long pinsel0;
+ pin_connect_2468_t *pin_connect=
+ &(((immap_t *)CONFIG_SYS_IMMAP)->apb.pin_connect);
+
+ /*enable uart #0 pins in GPIO (P0.2 = TxD0, P0.3 = RxD0) */
+ pinsel0 = readl (&(pin_connect->pinsel0));
+ pinsel0 &= ~(0x000000f0);
+ pinsel0 |= 0x00000050;
+ writel (pinsel0, &(pin_connect->pinsel0));
+
+ serial_setbrg ();
+
+ return (0);
+}
+
+void serial_putc (const char c)
+{
+ uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0);
+
+ if (c == '\n') {
+ /* Wait for empty U0THR */
+ while ((readb (&(uart0->lsr)) & (1 << 5)) == 0) ;
+ writeb ('\r', &(uart0->rbr_thr_dll));
+ }
+ /* Wait for empty U0THR */
+ while ((readb (&(uart0->lsr)) & (1 << 5)) == 0) ;
+ writeb (c, &(uart0->rbr_thr_dll));
+}
+
+int serial_getc (void)
+{
+ uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0);
+
+ while ((readb (&(uart0->lsr)) & 1) == 0) ;
+ return readb (&(uart0->rbr_thr_dll));
+}
+
+void serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+/* Test if there is a byte to read */
+int serial_tstc (void)
+{
+ uart_2468_t *uart0=&(((immap_t *)CONFIG_SYS_IMMAP)->apb.uart0);
+
+ return (readb (&(uart0->lsr)) & 1);
+}
diff --git a/include/asm-arm/arch-lpc24xx/hardware.h b/include/asm-arm/arch-lpc24xx/hardware.h
new file mode 100644
index 0000000..b42746e
--- /dev/null
+++ b/include/asm-arm/arch-lpc24xx/hardware.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/*
+ * Copyright (c) 2004 Cucy Systems (http://www.cucy.com)
+ * Curt Brune <curt@cucy.com>
+ *
+ * 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
+ */
+
+#if defined(CONFIG_LPC2468)
+#else
+#error No hardware file defined for this configuration
+#endif
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-lpc24xx/immap.h b/include/asm-arm/arch-lpc24xx/immap.h
new file mode 100644
index 0000000..d37e4f1
--- /dev/null
+++ b/include/asm-arm/arch-lpc24xx/immap.h
@@ -0,0 +1,351 @@
+/*
+ * (C) Copyright 2009 Duran Audio B.V.
+ *
+ * LPC2468 Internal Memory Map
+ *
+ * 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
+ *
+ */
+
+#ifndef __LPC24XX_IMMAP_H
+#define __LPC24XX_IMMAP_H
+
+#include <asm/types.h>
+#include <config.h>
+
+typedef struct watchdog_2468 {
+ u8 fixme[0x4000];
+} watchdog2468_t;
+
+typedef struct timer_2468 {
+ u32 ir;
+ u32 tcr;
+ u32 tc;
+ u32 pr;
+ u32 pc;
+ u32 mcr;
+ u32 mr0;
+ u32 mr1;
+ u32 mr2;
+ u32 mr3;
+ u32 ccr;
+ u32 cr0;
+ u32 cr1;
+ u32 cr2;
+ u32 cr3;
+ u32 emr;
+ u32 ctcr;
+ u8 notused[0x3fbc];
+} timer_2468_t;
+
+/*These two UART structs can probably be combined*/
+typedef struct uart_2468 {
+ u32 rbr_thr_dll;
+ u32 ier_dlm;
+ u32 iir_fcr;
+ u32 lcr;
+ u32 notused1;
+ u32 lsr;
+ u32 notused2;
+ u32 scr;
+ u32 acr;
+ u32 icr;
+ u32 fdr;
+ u32 notused3;
+ u32 ter;
+ u8 notused[0x3fcc];
+} uart_2468_t;
+
+typedef struct uart1_2468 {
+ u8 fixme[0x4000];
+} uart1_2468_t;
+
+typedef struct pwm0_2468 {
+ u8 fixme[0x4000];
+} pwm0_2468_t;
+
+typedef struct pwm1_2468 {
+ u8 fixme[0x4000];
+} pwm1_2468_t;
+
+typedef struct i2c0_2468 {
+ u8 fixme[0x4000];
+} i2c0_2468_t;
+
+typedef struct spi_2468 {
+ u8 fixme[0x4000];
+} spi_2468_t;
+
+typedef struct rtc_2468 {
+ u8 fixme[0x4000];
+} rtc_2468_t;
+
+typedef struct gpio_2468 {
+ u8 fixme[0x4000];
+} gpio_2468_t;
+
+typedef struct pin_connect_2468 {
+ u32 pinsel0;
+ u32 pinsel1;
+ u32 pinsel2;
+ u32 pinsel3;
+ u32 pinsel4;
+ u32 pinsel5;
+ u32 pinsel6;
+ u32 pinsel7;
+ u32 pinsel8;
+ u32 pinsel9;
+ u32 pinsel10;
+ u32 pinsel11;
+ u32 pinmode0;
+ u32 pinmode1;
+ u32 pinmode2;
+ u32 pinmode3;
+ u32 pinmode4;
+ u32 pinmode5;
+ u32 pinmode6;
+ u32 pinmode7;
+ u32 pinmode8;
+ u32 pinmode9;
+ u8 fixme[0x3fa8];
+} pin_connect_2468_t;
+
+typedef struct ssp1_2468 {
+ u8 fixme[0x4000];
+} ssp1_2468_t;
+
+typedef struct adc_2468 {
+ u8 fixme[0x4000];
+} adc_2468_t;
+
+typedef struct can_accept_ram_2468 {
+ u8 fixme[0x4000];
+} can_accept_ram_2468_t;
+
+typedef struct can_accept_filter_2468 {
+ u8 fixme[0x4000];
+} can_accept_filter_2468_t;
+
+typedef struct can_common_2468 {
+ u8 fixme[0x4000];
+} can_common_2468_t;
+
+typedef struct can1_2468 {
+ u8 fixme[0x4000];
+} can1_2468_t;
+
+typedef struct can2_2468 {
+ u8 fixme[0x4000];
+} can2_2468_t;
+
+typedef struct i2c1_2468 {
+ u8 fixme[0x4000];
+} i2c1_2468_t;
+
+typedef struct ssp0_2468 {
+ u8 fixme[0x4000];
+} ssp0_2468_t;
+
+typedef struct dac_2468 {
+ u8 fixme[0x4000];
+} dac_2468_t;
+
+typedef struct i2c2_2468 {
+ u8 fixme[0x4000];
+} i2c2_2468_t;
+
+typedef struct batt_ram_2468 {
+ u8 fixme[0x4000];
+} batt_ram_2468_t;
+
+typedef struct i2s_2468 {
+ u8 fixme[0x4000];
+} i2s_2468_t;
+
+typedef struct mmc_2468 {
+ u8 fixme[0x4000];
+} mmc_2468_t;
+
+typedef struct sys_con_2468 {
+ u8 notused1[0x40];
+ u32 memmap;
+ u8 notused2[0xfb];
+ u32 extint;
+ u32 extmode;
+ u32 extpolar;
+ u8 notused3[0x34];
+ u32 rsid;
+ u32 cspr;
+ u32 scs;
+ u8 notused4[0x3e71];
+} sys_con_2468_t;
+
+
+typedef struct mac_2468 {
+ u8 fixme[0x4000];
+} mac_2468_t;
+
+typedef struct gpdma__2468 {
+ u8 fixme[0x4000];
+} gpdma_2468_t;
+
+typedef struct ext_mem_2468 {
+ u8 fixme[0x4000];
+} ext_mem_2468_t;
+
+typedef struct usb_2468 {
+ u8 fixme[0x4000];
+} usb_2468_t;
+
+typedef struct lcd_2468 {
+ u8 fixme[0x4000];
+} lcd_2468_t;
+
+typedef struct vic_2468 {
+ u32 vicirqstat;
+ u32 vicfiqstat;
+ u32 vicrawintr;
+ u32 vicintselect;
+ u32 vicintenable;
+ u32 vicinenclr;
+ u32 vicsoftint;
+ u32 vicsoftintclr;
+ u32 vicprotect;
+ u32 vicswpriomask;
+ u8 notused1[0xd8];
+ u32 vicvectaddr0;
+ u32 vicvectaddr1;
+ u32 vicvectaddr2;
+ u32 vicvectaddr3;
+ u32 vicvectaddr4;
+ u32 vicvectaddr5;
+ u32 vicvectaddr6;
+ u32 vicvectaddr7;
+ u32 vicvectaddr8;
+ u32 vicvectaddr9;
+ u32 vicvectaddr10;
+ u32 vicvectaddr11;
+ u32 vicvectaddr12;
+ u32 vicvectaddr13;
+ u32 vicvectaddr14;
+ u32 vicvectaddr15;
+ u32 vicvectaddr16;
+ u32 vicvectaddr17;
+ u32 vicvectaddr18;
+ u32 vicvectaddr19;
+ u32 vicvectaddr20;
+ u32 vicvectaddr21;
+ u32 vicvectaddr22;
+ u32 vicvectaddr23;
+ u32 vicvectaddr24;
+ u32 vicvectaddr25;
+ u32 vicvectaddr26;
+ u32 vicvectaddr27;
+ u32 vicvectaddr28;
+ u32 vicvectaddr29;
+ u32 vicvectaddr30;
+ u32 vicvectaddr31;
+ u8 notused2[0x7f];
+ u32 vicvectprio0;
+ u32 vicvectprio1;
+ u32 vicvectprio2;
+ u32 vicvectprio3;
+ u32 vicvectprio4;
+ u32 vicvectprio5;
+ u32 vicvectprio6;
+ u32 vicvectprio7;
+ u32 vicvectprio8;
+ u32 vicvectprio9;
+ u32 vicvectprio10;
+ u32 vicvectprio11;
+ u32 vicvectprio12;
+ u32 vicvectprio13;
+ u32 vicvectprio14;
+ u32 vicvectprio15;
+ u32 vicvectprio16;
+ u32 vicvectprio17;
+ u32 vicvectprio18;
+ u32 vicvectprio19;
+ u32 vicvectprio20;
+ u32 vicvectprio21;
+ u32 vicvectprio22;
+ u32 vicvectprio23;
+ u32 vicvectprio24;
+ u32 vicvectprio25;
+ u32 vicvectprio26;
+ u32 vicvectprio27;
+ u32 vicvectprio28;
+ u32 vicvectprio29;
+ u32 vicvectprio30;
+ u32 vicvectprio31;
+ u8 notused3[0xc7f];
+ u32 vicaddr;
+} vic_2468_t;
+
+typedef struct apb_2468 {
+ watchdog2468_t watchdog;
+ timer_2468_t timer0;
+ timer_2468_t timer1;
+ uart_2468_t uart0;
+ uart1_2468_t uart1;
+ pwm0_2468_t pwm0;
+ pwm1_2468_t pwm1;
+ i2c0_2468_t i2c0;
+ spi_2468_t spi;
+ rtc_2468_t rtc;
+ gpio_2468_t gpio;
+ pin_connect_2468_t pin_connect;
+ ssp1_2468_t ssp1;
+ adc_2468_t adc;
+ can_accept_ram_2468_t can_accept_ram;
+ can_accept_filter_2468_t can_accept_filter;
+ can_common_2468_t can_comon;
+ can1_2468_t can1;
+ can2_2468_t can2;
+ u8 not_used1[0x10000];
+ i2c1_2468_t i2c1;
+ u8 notused2[0x8000];
+ ssp0_2468_t ssp0;
+ dac_2468_t dac;
+ timer_2468_t timer2;
+ timer_2468_t timer3;
+ uart_2468_t uart2;
+ uart_2468_t uart3;
+ i2c2_2468_t i2c2;
+ batt_ram_2468_t batt_ram;
+ i2s_2468_t i2s;
+ mmc_2468_t mmc;
+ u8 not_used3[0x16c000];
+ sys_con_2468_t sys_con;
+} apb_2468_t;
+
+typedef struct ahb_2468 {
+ mac_2468_t mac;
+ gpdma_2468_t gpdma;
+ ext_mem_2468_t ext_mem;
+ usb_2468_t usb;
+ lcd_2468_t lcd;
+ u8 notused1[0x1eb000];
+ vic_2468_t vic;
+} ahb_2468_t;
+
+typedef struct immap {
+ apb_2468_t apb;
+ u8 res1[0x1fc00000];
+ ahb_2468_t ahb;
+} immap_t;
+
+#endif
diff --git a/include/asm-arm/config.h b/include/asm-arm/config.h
index 049c44e..2d46a34 100644
--- a/include/asm-arm/config.h
+++ b/include/asm-arm/config.h
@@ -21,4 +21,8 @@
#ifndef _ASM_CONFIG_H_
#define _ASM_CONFIG_H_

+#if defined(CONFIG_LPC2292) || defined(CONFIG_LPC2468)
+#define CONFIG_LPC2000
+#endif
+
#endif
diff --git a/include/flash.h b/include/flash.h
index b016162..ac4a705 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -337,6 +337,7 @@ extern flash_info_t *flash_get_info(ulong base);
#define TOSH_ID_FVT160 0xC2 /* TC58FVT160 ID (16 M, top ) */
#define TOSH_ID_FVB160 0x43 /* TC58FVT160 ID (16 M, bottom ) */
#define PHILIPS_LPC2292 0x0401FF13 /* LPC2292 internal FLASH */
+#define PHILIPS_LPC2468 0x0603FF35 /* LPC2468 internal FLASH */

/*-----------------------------------------------------------------------
* Internal FLASH identification codes
--
1.6.2.4