[U-Boot] [PATCH-ARM v2] Add support for Embest SBC2440-II Board

kevin.morfitt at fearnside-systems.co.uk kevin.morfitt at fearnside-systems.co.uk
Tue May 26 12:38:02 CEST 2009


Implementation based on the existing u-boot support for S3C2410-based boards. u-boot programmed into NOR flash.

Tested on an SBC2440-II Board using tftp to copy the files from a server and programming them into NAND flash.

MAKEALL used to build all LIST_ARM9 targets only - no other architectures built as the changes only affect ARM9-based boards.

Changes since v1:
- removed all network-related parameters from board config file as requested by Ben Warren

Signed-off-by: Kevin Morfitt <kevin.morfitt at fearnside-systems.co.uk>
---
 MAKEALL                                |    1 +
 Makefile                               |    3 +
 board/embest/sbc2440ii/Makefile        |   55 +++++++
 board/embest/sbc2440ii/config.mk       |   25 ++++
 board/embest/sbc2440ii/lowlevel_init.S |  219 ++++++++++++++++++++++++++++
 board/embest/sbc2440ii/sbc2440ii.c     |  127 ++++++++++++++++
 board/embest/sbc2440ii/u-boot.lds      |   56 +++++++
 common/serial.c                        |    4 +-
 cpu/arm920t/s3c24x0/speed.c            |   83 ++++++++---
 cpu/arm920t/s3c24x0/timer.c            |    6 +-
 cpu/arm920t/s3c24x0/usb.c              |    6 +-
 cpu/arm920t/s3c24x0/usb_ohci.c         |    2 +
 cpu/arm920t/start.S                    |   35 ++++--
 drivers/i2c/s3c24x0_i2c.c              |   18 +++
 drivers/mtd/nand/Makefile              |    2 +-
 drivers/mtd/nand/s3c2410_nand.c        |  223 ++++++++++++++++++++++++-----
 drivers/rtc/s3c24x0_rtc.c              |    2 +
 drivers/serial/serial_s3c24x0.c        |    2 +
 include/common.h                       |    3 +-
 include/configs/sbc2440ii.h            |  246 ++++++++++++++++++++++++++++++++
 include/s3c2440.h                      |  231 ++++++++++++++++++++++++++++++
 include/s3c24x0.h                      |   83 +++++++++++
 22 files changed, 1356 insertions(+), 76 deletions(-)
 create mode 100644 board/embest/sbc2440ii/Makefile
 create mode 100644 board/embest/sbc2440ii/config.mk
 create mode 100644 board/embest/sbc2440ii/lowlevel_init.S
 create mode 100644 board/embest/sbc2440ii/sbc2440ii.c
 create mode 100644 board/embest/sbc2440ii/u-boot.lds
 create mode 100644 include/configs/sbc2440ii.h
 create mode 100644 include/s3c2440.h

diff --git a/MAKEALL b/MAKEALL
index c98d03a..e7235e4 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -515,6 +515,7 @@ LIST_ARM9="			\
 	omap5912osk		\
 	omap730p2		\
 	sbc2410x		\
+	sbc2440ii		\
 	scb9328			\
 	smdk2400		\
 	smdk2410		\
diff --git a/Makefile b/Makefile
index 81a5cd0..38f79c2 100644
--- a/Makefile
+++ b/Makefile
@@ -2876,6 +2876,9 @@ omap730p2_cs3boot_config :	unconfig
 sbc2410x_config: unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0
 
+sbc2440ii_config: unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm920t sbc2440ii embest s3c24x0
+
 scb9328_config	:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm920t scb9328 NULL imx
 
diff --git a/board/embest/sbc2440ii/Makefile b/board/embest/sbc2440ii/Makefile
new file mode 100644
index 0000000..85a56fa
--- /dev/null
+++ b/board/embest/sbc2440ii/Makefile
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# Modified for EMBEST SBC2440-II board with S3C2440 (ARM920T) cpu by:
+# (C) Copyright 2009
+# Kevin Morfitt, Fearnside Systems Ltd, <kevin.morfitt at fearnside-systems.co.uk>
+#
+# 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$(BOARD).a
+
+COBJS	:= sbc2440ii.o
+SOBJS	:= lowlevel_init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/embest/sbc2440ii/config.mk b/board/embest/sbc2440ii/config.mk
new file mode 100644
index 0000000..def11d8
--- /dev/null
+++ b/board/embest/sbc2440ii/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj at denx.de>
+# David Mueller, ELSOFT AG, <d.mueller at elsoft.ch>
+#
+# SAMSUNG SMDK2410 board with S3C2410X (ARM920T) cpu
+#
+# see http://www.samsung.com/ for more information on SAMSUNG
+#
+# Modified for EMBEST SBC2440-II board with S3C2440 (ARM920T) cpu by:
+# (C) Copyright 2009
+# Kevin Morfitt, Fearnside Systems Ltd, <kevin.morfitt at fearnside-systems.co.uk>
+
+#
+# SBC2440-II has 1 bank of 64 MB DRAM
+#
+# 3000'0000 to 3800'0000
+#
+# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
+#
+# we load ourself to 33F8'0000
+#
+# download area is 3000'0000
+
+TEXT_BASE = 0x33F80000
diff --git a/board/embest/sbc2440ii/lowlevel_init.S b/board/embest/sbc2440ii/lowlevel_init.S
new file mode 100644
index 0000000..90de392
--- /dev/null
+++ b/board/embest/sbc2440ii/lowlevel_init.S
@@ -0,0 +1,219 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw at its.tudelft.nl) and
+ *                     Jan-Derk Bakker (J.D.Bakker at its.tudelft.nl)
+ *
+ * Modified for the Samsung SMDK2410 by
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller at elsoft.ch>
+ *
+ * Modified for the friendly-arm SBC-2410X by
+ * (C) Copyright 2005
+ * JinHua Luo, GuangDong Linux Center, <luo.jinhua at gd-linux.com>
+ *
+ * Modified for the Embest SBC2440-II by
+ * (C) Copyright 2009
+ * Kevin Morfitt, Fearnside Systems Ltd, <kevin.morfitt at fearnside-systems.co.uk>
+ *
+ * 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 <config.h>
+#include <version.h>
+
+/*
+ * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
+ *
+ * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar at sec.samsung.com>
+ */
+
+#define BWSCON		0x48000000
+
+#define DW8		(0x0)
+#define DW16		(0x1)
+#define DW32		(0x2)
+#define WAIT		(0x1 << 2)
+#define UBLB		(0x1 << 3)
+
+#define B1_BWSCON	(DW16)
+#define B2_BWSCON	(DW16)
+#define B3_BWSCON	(DW16 + WAIT + UBLB)
+#define B4_BWSCON	(DW16)
+#define B5_BWSCON	(DW16)
+#define B6_BWSCON	(DW32)
+#define B7_BWSCON	(DW32)
+#define BWSCON_VAL	((B1_BWSCON <<  4) + (B2_BWSCON <<  8) + \
+			(B3_BWSCON << 12) + (B4_BWSCON << 16) + \
+			(B5_BWSCON << 20) + (B6_BWSCON << 24) + \
+			(B7_BWSCON << 28))
+
+#define B0_TACS		0x0
+#define B0_TCOS		0x0
+#define B0_TACC		0x7
+#define B0_TCOH		0x0
+#define B0_TAH		0x0
+#define B0_TACP		0x0
+#define B0_PMC		0x0
+#define BANKCON0_VAL	((B0_TACS << 13) + (B0_TCOS << 11) + (B0_TACC <<  8) + \
+			(B0_TCOH <<  6) + (B0_TAH  <<  4) + (B0_TACP <<  2) + \
+			B0_PMC)
+
+#define B1_TACS		0x0
+#define B1_TCOS		0x0
+#define B1_TACC		0x7
+#define B1_TCOH		0x0
+#define B1_TAH		0x0
+#define B1_TACP		0x0
+#define B1_PMC		0x0
+#define BANKCON1_VAL	((B1_TACS << 13) + (B1_TCOS << 11) + (B1_TACC <<  8) + \
+			(B1_TCOH <<   6) + (B1_TAH  <<  4) + (B1_TACP <<  2) + \
+			B1_PMC)
+
+#define B2_TACS		0x0
+#define B2_TCOS		0x0
+#define B2_TACC		0x7
+#define B2_TCOH		0x0
+#define B2_TAH		0x0
+#define B2_TACP		0x0
+#define B2_PMC		0x0
+#define BANKCON2_VAL	((B2_TACS << 13) + (B2_TCOS << 11) + (B2_TACC << 8) + \
+			(B2_TCOH <<  6) + (B2_TAH  <<  4) + (B2_TACP << 2) + \
+			B2_PMC)
+
+#define B3_TACS		0x0	/* 0clk */
+#define B3_TCOS		0x3	/* 4clk */
+#define B3_TACC		0x7	/* 14clk */
+#define B3_TCOH		0x1	/* 1clk */
+#define B3_TAH		0x3	/* 4clk */
+#define B3_TACP		0x3	/* 6clk */
+#define B3_PMC		0x0	/* 16data */
+#define BANKCON3_VAL	((B3_TACS << 13) + (B3_TCOS << 11) + (B3_TACC << 8) + \
+			(B3_TCOH <<  6) + (B3_TAH  <<  4) + (B3_TACP << 2) + \
+			B3_PMC)
+
+#define B4_TACS		0x0
+#define B4_TCOS		0x0
+#define B4_TACC		0x7
+#define B4_TCOH		0x0
+#define B4_TAH		0x0
+#define B4_TACP		0x0
+#define B4_PMC		0x0
+#define BANKCON4_VAL	((B4_TACS << 13) + (B4_TCOS << 11) + (B4_TACC << 8) + \
+			(B4_TCOH <<  6) + (B4_TAH  <<  4) + (B4_TACP << 2) + \
+			B4_PMC)
+
+#define B5_TACS		0x0
+#define B5_TCOS		0x0
+#define B5_TACC		0x7
+#define B5_TCOH		0x0
+#define B5_TAH		0x0
+#define B5_TACP		0x0
+#define B5_PMC		0x0
+#define BANKCON5_VAL	((B5_TACS << 13) + (B5_TCOS << 11) + (B5_TACC << 8) + \
+			(B5_TCOH <<  6) + (B5_TAH  <<  4) + (B5_TACP << 2) + \
+			B5_PMC)
+
+#define B6_MT		0x3	/* SDRAM */
+#define B6_TRCD		0x2
+#define B6_SCAN		0x1	/* 9bit */
+#define BANKCON6_VAL	((B6_MT << 15) + (B6_TRCD << 2) + B6_SCAN)
+
+#define B7_MT		0x3	/* SDRAM */
+#define B7_TRCD		0x2	/* 4clk */
+#define B7_SCAN		0x1	/* 9bit */
+#define BANKCON7_VAL	((B7_MT << 15) + (B7_TRCD << 2) + B7_SCAN)
+
+/* REFRESH parameter */
+#define REFEN		0x1	/* Refresh enable */
+#define TREFMD		0x0	/* CBR(CAS before RAS)/Auto refresh */
+#define TRP		0x0	/* 2clk */
+#define TRC		0x3	/* 7clk */
+#define TCHR		0x2	/* 3clk */
+#define REFCNT		1259
+#define REFRESH_VAL	((REFEN << 23) + (TREFMD << 22) + (TRP << 20) + \
+			(TRC   << 18) + (TCHR   << 16) + REFCNT)
+
+/* BANKSIZE parameter */
+#define BURST_EN	1	/* Enable burst mode */
+#define SCKE_EN		1	/* Enable SDRAM power-down mode */
+#define SCLK_EN		1	/* SCLK is active only during the access */
+#define BK67MAP		2	/* 128M/128M */
+#define BANKSIZE_VAL	((BURST_EN << 7) + (SCKE_EN << 5) + \
+			(SCLK_EN  << 4) + BK67MAP)
+
+/* MRSRB6 parameter */
+#define WBL6		0	/* Burst */
+#define TM6		0	/* Modem register set */
+#define CL6		3	/* Latency is 3 clocks */
+#define BT6		0	/* Sequential */
+#define BL6		0
+#define MRSRB6_VAL	((WBL6 << 9) + (TM6 << 7) + (CL6 << 4) + \
+			(BT6  << 3) + BL6)
+
+/* MRSRB7 parameter */
+#define WBL7		0	/* Burst */
+#define TM7		0	/* Modem register set */
+#define CL7		3	/* Latency is 3 clocks */
+#define BT7		0	/* Sequential */
+#define BL7		0
+#define MRSRB7_VAL	((WBL7 << 9) + (TM7 << 7) + (CL7 << 4) + \
+			(BT7 << 3) + BL7)
+
+/**************************************/
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+.globl lowlevel_init
+lowlevel_init:
+	/* memory control configuration */
+	/* make r0 relative the current location so that it */
+	/* reads SMRDATA out of FLASH rather than memory ! */
+	ldr     r0, =SMRDATA
+	ldr	r1, _TEXT_BASE
+	sub	r0, r0, r1
+	ldr	r1, =BWSCON	/* Bus Width Status Controller */
+	add     r2, r0, #13*4
+0:
+	ldr     r3, [r0], #4
+	str     r3, [r1], #4
+	cmp     r2, r0
+	bne     0b
+
+	/* everything is fine now */
+	mov	pc, lr
+
+	.ltorg
+/* the literal pools origin */
+
+SMRDATA:
+	.word BWSCON_VAL
+	.word BANKCON0_VAL
+	.word BANKCON1_VAL
+	.word BANKCON2_VAL
+	.word BANKCON3_VAL
+	.word BANKCON4_VAL
+	.word BANKCON5_VAL
+	.word BANKCON6_VAL
+	.word BANKCON7_VAL
+	.word REFRESH_VAL
+	.word BANKSIZE_VAL
+	.word MRSRB6_VAL
+	.word MRSRB7_VAL
diff --git a/board/embest/sbc2440ii/sbc2440ii.c b/board/embest/sbc2440ii/sbc2440ii.c
new file mode 100644
index 0000000..e0432d5
--- /dev/null
+++ b/board/embest/sbc2440ii/sbc2440ii.c
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger at sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller at elsoft.ch>
+ *
+ * (C) Copyright 2005
+ * JinHua Luo, GuangDong Linux Center, <luo.jinhua at gd-linux.com>
+ *
+ * Modified for the Embest SBC2440-II by
+ * (C) Copyright 2009
+ * Kevin Morfitt, Fearnside Systems Ltd, <kevin.morfitt at fearnside-systems.co.uk>
+ *
+ * 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 <s3c2440.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Configure the PLLs for MPLL = 400MHz, UPLL = 48MHz
+	The clock frequency ratios are set to 1:4:8 ie:
+		PCLK = 50MHz
+		HCLK = 100MHz
+		FCLK = 400MHz
+ */
+/* The MPLL values. */
+#define M_MDIV	0x5C
+#define M_PDIV	1
+#define M_SDIV	1
+
+/* The UPLL values. */
+#define U_MDIV	0x38
+#define U_PDIV	2
+#define U_SDIV	2
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+static inline void pll_settle_delay(unsigned long loops)
+{
+	__asm__ volatile ("1:\n"
+			  "subs %0, %1, #1\n"
+			  "bne 1b" : "=r" (loops) : "0" (loops));
+}
+
+int board_init(void)
+{
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+	/* to reduce PLL lock time, adjust the LOCKTIME register */
+	clk_power->LOCKTIME = 0xFFFFFFFF;
+
+	/* configure UPLL */
+	clk_power->UPLLCON = ((U_MDIV << 12) + (U_PDIV << 4) + U_SDIV);
+
+	/* some delay between UPLL and MPLL */
+	pll_settle_delay(8000);
+
+	/* configure MPLL */
+	clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
+
+	/* configure the GPIO */
+	gpio->GPACON = 0x007FFFFF;
+	gpio->GPBCON = 0x00055555;
+	gpio->GPBUP  = 0x000007FF;
+	gpio->GPBDAT = 0x000001C0;		/* Switch on LED1. */
+	gpio->GPCCON = 0xAAAAAAAA;
+	gpio->GPCUP  = 0x0000FFFF;
+	gpio->GPDCON = 0xAAAAAAAA;
+	gpio->GPDUP  = 0x0000FFFF;
+	gpio->GPECON = 0xAAAAA800;
+	gpio->GPEUP  = 0x00001FFF;
+	gpio->GPFCON = 0x000055AA;
+	gpio->GPFUP  = 0x000000FF;
+	gpio->GPGCON = 0xFD95FFBA;
+	gpio->GPGUP  = 0x0000FFFF;
+	gpio->GPHCON = 0x0002FAAA;
+	gpio->GPHUP  = 0x000007FF;
+	gpio->GPJCON = 0x02FAAAAA;
+	gpio->GPJUP  = 0x00001FFF;
+
+	gpio->EXTINT0  = 0x22222222;
+	gpio->EXTINT1  = 0x22222222;
+	gpio->EXTINT2  = 0x22222222;
+	gpio->EINTMASK = 0x00FFFFF0;
+
+	/* arch number of SBC2440-II Board */
+   gd->bd->bi_arch_number = MACH_TYPE_SBC2440II;
+
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = 0x30000100;
+
+	icache_enable();
+	dcache_enable();
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	return 0;
+}
diff --git a/board/embest/sbc2440ii/u-boot.lds b/board/embest/sbc2440ii/u-boot.lds
new file mode 100644
index 0000000..3b79776
--- /dev/null
+++ b/board/embest/sbc2440ii/u-boot.lds
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj 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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm920t/start.o	(.text)
+	  *(.text)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(.rodata) }
+
+	. = ALIGN(4);
+	.data : { *(.data) }
+
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss (NOLOAD) : { *(.bss) }
+	_end = .;
+}
diff --git a/common/serial.c b/common/serial.c
index 09385d0..fe8799c 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -58,7 +58,7 @@ struct serial_device *__default_serial_console (void)
 #else
 		return &serial0_device;
 #endif
-#elif defined(CONFIG_S3C2410)
+#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
 #if defined(CONFIG_SERIAL1)
 	return &s3c24xx_serial0_device;
 #elif defined(CONFIG_SERIAL2)
@@ -131,7 +131,7 @@ void serial_initialize (void)
 #if defined (CONFIG_STUART)
 	serial_register(&serial_stuart_device);
 #endif
-#if defined(CONFIG_S3C2410)
+#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
 	serial_register(&s3c24xx_serial0_device);
 	serial_register(&s3c24xx_serial1_device);
 	serial_register(&s3c24xx_serial2_device);
diff --git a/cpu/arm920t/s3c24x0/speed.c b/cpu/arm920t/s3c24x0/speed.c
index e0dca62..064e22e 100644
--- a/cpu/arm920t/s3c24x0/speed.c
+++ b/cpu/arm920t/s3c24x0/speed.c
@@ -30,12 +30,15 @@
  */
 
 #include <common.h>
-#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
+    defined(CONFIG_S3C2440) || defined(CONFIG_TRAB)
 
 #if defined(CONFIG_S3C2400)
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 
 #define MPLL 0
@@ -53,49 +56,81 @@
 
 static ulong get_PLLCLK(int pllreg)
 {
-    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
-    ulong r, m, p, s;
-
-    if (pllreg == MPLL)
-	r = clk_power->MPLLCON;
-    else if (pllreg == UPLL)
-	r = clk_power->UPLLCON;
-    else
-	hang();
-
-    m = ((r & 0xFF000) >> 12) + 8;
-    p = ((r & 0x003F0) >> 4) + 2;
-    s = r & 0x3;
-
-    return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+	ulong r, m, p, s;
+
+	if (pllreg == MPLL)
+		r = clk_power->MPLLCON;
+	else if (pllreg == UPLL)
+		r = clk_power->UPLLCON;
+	else
+		hang();
+
+	m = ((r & 0xFF000) >> 12) + 8;
+	p = ((r & 0x003F0) >> 4) + 2;
+	s = r & 0x3;
+
+#ifdef CONFIG_S3C2440
+	if (pllreg == MPLL)
+		return (2 * CONFIG_SYS_CLK_FREQ * m) / (p << s);
+	else
+		return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
+#else
+	return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
+#endif
 }
 
 /* return FCLK frequency */
 ulong get_FCLK(void)
 {
-    return(get_PLLCLK(MPLL));
+	return get_PLLCLK(MPLL);
 }
 
 /* return HCLK frequency */
 ulong get_HCLK(void)
 {
-    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
-
-    return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+
+#ifdef CONFIG_S3C2440
+	switch (clk_power->CLKDIVN & 0x6) {
+	default:
+	case 0:
+		return get_FCLK();
+	case 2:
+		return get_FCLK()/2;
+	case 4:
+		return (clk_power->CAMDIVN & (1<<9)) ?
+			get_FCLK()/8 : get_FCLK()/4;
+	case 6:
+		return (clk_power->CAMDIVN & (1<<8)) ?
+			get_FCLK()/6 : get_FCLK()/3;
+	}
+#else
+	return (clk_power->CLKDIVN & 0x2) ?
+		get_FCLK()/2 : get_FCLK();
+#endif
 }
 
 /* return PCLK frequency */
 ulong get_PCLK(void)
 {
-    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
 
-    return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
+	return (clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK();
 }
 
 /* return UCLK frequency */
 ulong get_UCLK(void)
 {
-    return(get_PLLCLK(UPLL));
+#ifdef CONFIG_S3C2440
+	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+
+	return (clk_power->CLKDIVN & (1<<3)) ?
+		get_PLLCLK(UPLL)/2 : get_PLLCLK(UPLL);
+#else
+	return get_PLLCLK(UPLL);
+#endif
 }
 
-#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
+#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || \
+	defined (CONFIG_S3C2440) || defined (CONFIG_TRAB) */
diff --git a/cpu/arm920t/s3c24x0/timer.c b/cpu/arm920t/s3c24x0/timer.c
index f0a09cd..134d644 100644
--- a/cpu/arm920t/s3c24x0/timer.c
+++ b/cpu/arm920t/s3c24x0/timer.c
@@ -30,12 +30,15 @@
  */
 
 #include <common.h>
-#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
+    defined(CONFIG_S3C2440) || defined(CONFIG_TRAB)
 
 #if defined(CONFIG_S3C2400)
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 
 int timer_load_val = 0;
@@ -177,6 +180,7 @@ ulong get_tbclk (void)
 	tbclk = timer_load_val * 100;
 #elif defined(CONFIG_SBC2410X) || \
       defined(CONFIG_SMDK2410) || \
+      defined(CONFIG_SBC2440II) || \
       defined(CONFIG_VCMA9)
 	tbclk = CONFIG_SYS_HZ;
 #else
diff --git a/cpu/arm920t/s3c24x0/usb.c b/cpu/arm920t/s3c24x0/usb.c
index 9ccf575..962ef0d 100644
--- a/cpu/arm920t/s3c24x0/usb.c
+++ b/cpu/arm920t/s3c24x0/usb.c
@@ -24,12 +24,16 @@
 #include <common.h>
 
 #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
-# if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
+# if defined(CONFIG_S3C2400) || \
+     defined(CONFIG_S3C2410) || \
+     defined(CONFIG_S3C2440)
 
 #if defined(CONFIG_S3C2400)
 # include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 # include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 
 int usb_cpu_init (void)
diff --git a/cpu/arm920t/s3c24x0/usb_ohci.c b/cpu/arm920t/s3c24x0/usb_ohci.c
index 7838014..6a46eed 100644
--- a/cpu/arm920t/s3c24x0/usb_ohci.c
+++ b/cpu/arm920t/s3c24x0/usb_ohci.c
@@ -42,6 +42,8 @@
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 
 #include <malloc.h>
diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S
index 475cdaf..7e9e6f8 100644
--- a/cpu/arm920t/start.S
+++ b/cpu/arm920t/start.S
@@ -132,20 +132,30 @@ copyex:
 	bne	copyex
 #endif
 
-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
+#if defined(CONFIG_S3C2400) || \
+    defined(CONFIG_S3C2410) || \
+    defined(CONFIG_S3C2440)
 	/* turn off the watchdog */
 
 # if defined(CONFIG_S3C2400)
-#  define pWTCON		0x15300000
-#  define INTMSK		0x14400008	/* Interupt-Controller base addresses */
+#  define pWTCON	0x15300000
+#  define INTMSK	0x14400008	/* Interupt-Controller base addresses */
 #  define CLKDIVN	0x14800014	/* clock divisor register */
 #else
-#  define pWTCON		0x53000000
-#  define INTMSK		0x4A000008	/* Interupt-Controller base addresses */
+#  define pWTCON	0x53000000
+#  define INTMSK	0x4A000008	/* Interupt-Controller base addresses */
 #  define INTSUBMSK	0x4A00001C
 #  define CLKDIVN	0x4C000014	/* clock divisor register */
 # endif
 
+# if defined(CONFIG_S3C2440)
+#  define INTSMASK	0xffff
+#  define CLKDIVVAL	0x5
+#else
+#  define INTSMASK	0x3ff
+#  define CLKDIVVAL	0x3
+# endif
+
 	ldr     r0, =pWTCON
 	mov     r1, #0x0
 	str     r1, [r0]
@@ -156,8 +166,8 @@ copyex:
 	mov	r1, #0xffffffff
 	ldr	r0, =INTMSK
 	str	r1, [r0]
-# if defined(CONFIG_S3C2410)
-	ldr	r1, =0x3ff
+# if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+	ldr	r1, =INTSMASK
 	ldr	r0, =INTSUBMSK
 	str	r1, [r0]
 # endif
@@ -165,9 +175,16 @@ copyex:
 	/* FCLK:HCLK:PCLK = 1:2:4 */
 	/* default FCLK is 120 MHz ! */
 	ldr	r0, =CLKDIVN
-	mov	r1, #3
+	mov	r1, #CLKDIVVAL
 	str	r1, [r0]
-#endif	/* CONFIG_S3C2400 || CONFIG_S3C2410 */
+
+#ifdef CONFIG_S3C2440
+	/* Set asynchronous bus mode */
+	mrc	p15, 0, r1, c1, c0, 0	/* read ctrl register */
+	orr	r1, r1, #0xc0000000		/* Asynchronous */
+	mcr	p15, 0, r1, c1, c0, 0	/* write ctrl register */
+#endif	/* CONFIG_S3C2440 */
+#endif	/* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_S3C2440 */
 
 	/*
 	 * we do sys-critical inits only at reboot,
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index f0c1aa3..28bf314 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -31,6 +31,8 @@
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 #include <i2c.h>
 
@@ -66,6 +68,9 @@ static int GetI2CSDA(void)
 #ifdef CONFIG_S3C2400
 	return (gpio->PGDAT & 0x0020) >> 5;
 #endif
+#ifdef CONFIG_S3C2440
+	return (gpio->GPEDAT & 0x8000) >> 15;
+#endif
 }
 
 #if 0
@@ -85,6 +90,9 @@ static void SetI2CSCL(int x)
 #ifdef CONFIG_S3C2400
 	gpio->PGDAT = (gpio->PGDAT & ~0x0040) | (x&1) << 6;
 #endif
+#ifdef CONFIG_S3C2440
+	gpio->GPEDAT = (gpio->GPEDAT & ~0x4000) | (x&1) << 14;
+#endif
 }
 
 
@@ -142,6 +150,9 @@ void i2c_init (int speed, int slaveadd)
 #ifdef CONFIG_S3C2400
 		ulong old_gpecon = gpio->PGCON;
 #endif
+#ifdef CONFIG_S3C2440
+		ulong old_gpecon = gpio->GPECON;
+#endif
 		/* bus still busy probably by (most) previously interrupted transfer */
 
 #ifdef CONFIG_S3C2410
@@ -152,6 +163,10 @@ void i2c_init (int speed, int slaveadd)
 		/* set I2CSDA and I2CSCL (PG5, PG6) to GPIO */
 		gpio->PGCON = (gpio->PGCON & ~0x00003c00) | 0x00001000;
 #endif
+#ifdef CONFIG_S3C2440
+		/* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
+		gpio->GPECON = (gpio->GPECON & ~0xF0000000) | 0x10000000;
+#endif
 
 		/* toggle I2CSCL until bus idle */
 		SetI2CSCL (0);
@@ -174,6 +189,9 @@ void i2c_init (int speed, int slaveadd)
 #ifdef CONFIG_S3C2400
 		gpio->PGCON = old_gpecon;
 #endif
+#ifdef CONFIG_S3C2440
+		gpio->GPECON = old_gpecon;
+#endif
 	}
 
 	/* calculate prescaler and divisor values */
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 471cd6b..190abeb 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -41,7 +41,7 @@ COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
 COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
 COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o
-COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.c
+COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
 COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 endif
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c
index d27a625..8438a89 100644
--- a/drivers/mtd/nand/s3c2410_nand.c
+++ b/drivers/mtd/nand/s3c2410_nand.c
@@ -20,46 +20,93 @@
 
 #include <common.h>
 
-#if 0
-#define DEBUGN	printf
+#include <nand.h>
+#ifndef CONFIG_S3C2440
+	#include <s3c2410.h>
 #else
-#define DEBUGN(x, args ...) {}
+	#include <s3c2440.h>
 #endif
-
-#include <nand.h>
-#include <s3c2410.h>
 #include <asm/io.h>
 
 #define __REGb(x)	(*(volatile unsigned char *)(x))
 #define __REGi(x)	(*(volatile unsigned int *)(x))
+#define __REGl(x)	(*(volatile unsigned long *)(x))
 
 #define	NF_BASE		0x4e000000
 #define	NFCONF		__REGi(NF_BASE + 0x0)
-#define	NFCMD		__REGb(NF_BASE + 0x4)
-#define	NFADDR		__REGb(NF_BASE + 0x8)
-#define	NFDATA		__REGb(NF_BASE + 0xc)
-#define	NFSTAT		__REGb(NF_BASE + 0x10)
-#define NFECC0		__REGb(NF_BASE + 0x14)
-#define NFECC1		__REGb(NF_BASE + 0x15)
-#define NFECC2		__REGb(NF_BASE + 0x16)
-
-#define S3C2410_NFCONF_EN          (1<<15)
-#define S3C2410_NFCONF_512BYTE     (1<<14)
-#define S3C2410_NFCONF_4STEP       (1<<13)
-#define S3C2410_NFCONF_INITECC     (1<<12)
-#define S3C2410_NFCONF_nFCE        (1<<11)
-#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
-#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
-#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
+
+#ifdef CONFIG_S3C2440
+	#define NFCONT		__REGb(NF_BASE + 0x4)
+	#define NFCMD		__REGb(NF_BASE + 0x8)
+	#define NFADDR		__REGb(NF_BASE + 0xc)
+	#define NFDATA		__REGb(NF_BASE + 0x10)
+	#define NFSTAT		__REGb(NF_BASE + 0x20)
+	#define NFMECC0		__REGl(NF_BASE + 0x2c)
+
+	#define S3C2440_NFCONT_EN		(1<<0)
+	#define S3C2440_NFCONT_nFCE		(1<<1)
+	#define S3C2440_NFCONT_INITECC		(1<<4)
+	#define S3C2440_NFCONT_MAINECCLOCK	(1<<5)
+	#define S3C2440_NFCONT_SPAREECCLOCK	(1<<6)
+	#define S3C2440_NFCONT_RNBMODE		(1<<8)
+	#define S3C2440_NFCONT_RNBINT		(1<<9)
+	#define S3C2440_NFCONT_ILLEGALINT	(1<<10)
+	#define S3C2440_NFCONT_SOFTLOCK		(1<<12)
+	#define S3C2440_NFCONT_LOCKTIGHT	(1<<13)
+
+	#define S3C2440_NFCONF_TACLS(x)		((x)<<12)
+	#define S3C2440_NFCONF_TWRPH0(x)	((x)<<8)
+	#define S3C2440_NFCONF_TWRPH1(x)	((x)<<4)
+#else
+	#define NFCMD		__REGb(NF_BASE + 0x4)
+	#define NFADDR		__REGb(NF_BASE + 0x8)
+	#define NFDATA		__REGb(NF_BASE + 0xc)
+	#define NFSTAT		__REGb(NF_BASE + 0x10)
+	#define NFECC0		__REGb(NF_BASE + 0x14)
+	#define NFECC1		__REGb(NF_BASE + 0x15)
+	#define NFECC2		__REGb(NF_BASE + 0x16)
+
+	#define S3C2410_NFCONF_EN          (1<<15)
+	#define S3C2410_NFCONF_512BYTE     (1<<14)
+	#define S3C2410_NFCONF_4STEP       (1<<13)
+	#define S3C2410_NFCONF_INITECC     (1<<12)
+	#define S3C2410_NFCONF_nFCE        (1<<11)
+	#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
+	#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
+	#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
+#endif
 
 #define S3C2410_ADDR_NALE 4
 #define S3C2410_ADDR_NCLE 8
 
+
+#ifdef CONFIG_S3C2410_NAND_HWECC
+/* new oob placement block for use with hardware ecc generation
+ */
+static struct nand_ecclayout nand_hw_eccoob = {
+	.eccbytes = 3,
+	.eccpos = {0, 1, 2},
+	.oobfree = { {8, 8} }
+};
+#endif
+
+static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	if (chip == -1) {
+		debugX(1, "Negating nFCE\n");
+		NFCONT |= S3C2440_NFCONT_nFCE;
+	} else {
+		debugX(1, "Asserting nFCE\n");
+		NFCONT &= ~S3C2440_NFCONT_nFCE;
+	}
+}
+
+#ifndef CONFIG_S3C2440
 static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
 	struct nand_chip *chip = mtd->priv;
 
-	DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
+	debugX(1, "hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
 
 	if (ctrl & NAND_CTRL_CHANGE) {
 		ulong IO_ADDR_W = NF_BASE;
@@ -80,27 +127,58 @@ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 	if (cmd != NAND_CMD_NONE)
 		writeb(cmd, chip->IO_ADDR_W);
 }
+#else
+static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	debugX(1, "hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE) {
+		debugX(1, "NFCMD = 0x%08X\n", cmd);
+		NFCMD = cmd;
+	}
+
+	if (ctrl & NAND_ALE) {
+		debugX(1, "NFADDR = 0x%08X\n", cmd);
+		NFADDR = cmd;
+	}
+}
+#endif
 
 static int s3c2410_dev_ready(struct mtd_info *mtd)
 {
-	DEBUGN("dev_ready\n");
+	debugX(1, "dev_ready\n");
 	return (NFSTAT & 0x01);
 }
 
 #ifdef CONFIG_S3C2410_NAND_HWECC
 void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 {
-	DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
+	debugX(2, "s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
+#ifndef CONFIG_S3C2440
 	NFCONF |= S3C2410_NFCONF_INITECC;
+#else
+	NFCONT |= S3C2440_NFCONT_INITECC;
+#endif
 }
 
 static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 				      u_char *ecc_code)
 {
+#ifndef CONFIG_S3C2440
 	ecc_code[0] = NFECC0;
 	ecc_code[1] = NFECC1;
 	ecc_code[2] = NFECC2;
-	DEBUGN("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
+#else
+	unsigned long ecc = NFMECC0;
+
+	ecc_code[0] = ecc;
+	ecc_code[1] = ecc >> 8;
+	ecc_code[2] = ecc >> 16;
+#endif
+	debugX(2, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
 		mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
 
 	return 0;
@@ -109,12 +187,53 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
 				     u_char *read_ecc, u_char *calc_ecc)
 {
-	if (read_ecc[0] == calc_ecc[0] &&
-	    read_ecc[1] == calc_ecc[1] &&
-	    read_ecc[2] == calc_ecc[2])
-		return 0;
+	unsigned int diff0, diff1, diff2;
+	unsigned int bit, byte;
+
+	debugX(2, "s3c2410_nand_correct_data:\n");
+
+	diff0 = read_ecc[0] ^ calc_ecc[0];
+	diff1 = read_ecc[1] ^ calc_ecc[1];
+	diff2 = read_ecc[2] ^ calc_ecc[2];
+
+	debugX(3, "rd %02x%02x%02x calc %02x%02x%02x diff %02x%02x%02x\n",
+		read_ecc[0], read_ecc[1], read_ecc[2],
+		calc_ecc[0], calc_ecc[1], calc_ecc[2],
+		diff0, diff1, diff2);
+
+	if (diff0 == 0 && diff1 == 0 && diff2 == 0)
+		return 0;		/* ECC is ok */
+
+	/* Can we correct this ECC (ie, one row and column change).
+	 * Note, this is similar to the 256 error code on smartmedia */
+
+	if (((diff0 ^ (diff0 >> 1)) & 0x55) == 0x55 &&
+	    ((diff1 ^ (diff1 >> 1)) & 0x55) == 0x55 &&
+	    ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) {
+		/* calculate the bit position of the error */
+
+		bit  = ((diff2 >> 3) & 1) |
+		       ((diff2 >> 4) & 2) |
+		       ((diff2 >> 5) & 4);
+
+		/* calculate the byte position of the error */
+		byte = ((diff2 << 7) & 0x100) |
+		       ((diff1 << 0) & 0x80)  |
+		       ((diff1 << 1) & 0x40)  |
+		       ((diff1 << 2) & 0x20)  |
+		       ((diff1 << 3) & 0x10)  |
+		       ((diff0 >> 4) & 0x08)  |
+		       ((diff0 >> 3) & 0x04)  |
+		       ((diff0 >> 2) & 0x02)  |
+		       ((diff0 >> 1) & 0x01);
+
+		debugX(2, "correcting error bit %d, byte %d\n", bit, byte);
+
+		dat[byte] ^= (1 << bit);
+		return 1;
+	}
 
-	printf("s3c2410_nand_correct_data: not implemented\n");
+	debugX(2, "Failed to correct ECC error\n");
 	return -1;
 }
 #endif
@@ -125,11 +244,12 @@ int board_nand_init(struct nand_chip *nand)
 	u_int8_t tacls, twrph0, twrph1;
 	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
 
-	DEBUGN("board_nand_init()\n");
+	debugX(1, "board_nand_init()\n");
 
 	clk_power->CLKCON |= (1 << 4);
 
 	/* initialize hardware */
+#ifndef CONFIG_S3C2440
 	twrph0 = 3; twrph1 = 0; tacls = 0;
 
 	cfg = S3C2410_NFCONF_EN;
@@ -141,20 +261,49 @@ int board_nand_init(struct nand_chip *nand)
 
 	/* initialize nand_chip data structure */
 	nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e00000c;
+#else
+	twrph0 = 3; twrph1 = 1; tacls = 0;
+
+	cfg = S3C2440_NFCONF_TACLS(tacls);
+	cfg |= S3C2440_NFCONF_TWRPH0(twrph0);
+	cfg |= S3C2440_NFCONF_TWRPH1(twrph1);
+	NFCONF = cfg;
+
+	cfg = S3C2440_NFCONT_EN;
+	cfg |= S3C2440_NFCONT_nFCE;
+	NFCONT = cfg;
+
+	/* initialize nand_chip data structure */
+	nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;
+#endif
 
 	/* read_buf and write_buf are default */
 	/* read_byte and write_byte are default */
 
+	nand->select_chip  = s3c2410_nand_select_chip;
+	nand->chip_delay   = 50;
+
 	/* hwcontrol always must be implemented */
 	nand->cmd_ctrl = s3c2410_hwcontrol;
 
 	nand->dev_ready = s3c2410_dev_ready;
 
 #ifdef CONFIG_S3C2410_NAND_HWECC
-	nand->ecc.hwctl = s3c2410_nand_enable_hwecc;
-	nand->ecc.calculate = s3c2410_nand_calculate_ecc;
-	nand->ecc.correct = s3c2410_nand_correct_data;
-	nand->ecc.mode = NAND_ECC_HW3_512;
+	nand->ecc.correct		= s3c2410_nand_correct_data;
+	nand->ecc.hwctl		= s3c2410_nand_enable_hwecc;
+	nand->ecc.calculate	= s3c2410_nand_calculate_ecc;
+	nand->ecc.mode = NAND_ECC_HW;
+	/* change the behaviour depending on whether we are using
+	 * the large or small page nand device */
+	if (nand->page_shift > 10) {
+		nand->ecc.size		= 256;
+		nand->ecc.bytes	= 3;
+	} else {
+		nand->ecc.size		= 512;
+		nand->ecc.bytes	= 3;
+		nand->ecc.layout	= &nand_hw_eccoob;
+	}
+	debugX(2, "ecc: size: %d bytes: %d\n", nand->ecc.size, nand->ecc.bytes);
 #else
 	nand->ecc.mode = NAND_ECC_SOFT;
 #endif
@@ -165,7 +314,7 @@ int board_nand_init(struct nand_chip *nand)
 	nand->options = 0;
 #endif
 
-	DEBUGN("end of nand_init\n");
+	debugX(1, "end of nand_init\n");
 
 	return 0;
 }
diff --git a/drivers/rtc/s3c24x0_rtc.c b/drivers/rtc/s3c24x0_rtc.c
index 0d3372f..8f7559b 100644
--- a/drivers/rtc/s3c24x0_rtc.c
+++ b/drivers/rtc/s3c24x0_rtc.c
@@ -34,6 +34,8 @@
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 
 #include <rtc.h>
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index 6d69c43..52d5895 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -23,6 +23,8 @@
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/include/common.h b/include/common.h
index 30fff7d..161277f 100644
--- a/include/common.h
+++ b/include/common.h
@@ -490,7 +490,8 @@ ulong	get_OPB_freq (void);
 ulong	get_PCI_freq (void);
 #endif
 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
-	defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400)
+    defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400) || \
+    defined(CONFIG_S3C2440)
 void	s3c2410_irq(void);
 #define ARM920_IRQ_CALLBACK s3c2410_irq
 ulong	get_FCLK (void);
diff --git a/include/configs/sbc2440ii.h b/include/configs/sbc2440ii.h
new file mode 100644
index 0000000..a292727
--- /dev/null
+++ b/include/configs/sbc2440ii.h
@@ -0,0 +1,246 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger at sysgo.de>
+ * Gary Jennejohn <gj at denx.de>
+ * David Mueller <d.mueller at elsoft.ch>
+ *
+ * Modified for the friendly-arm SBC-2410X by
+ * (C) Copyright 2005
+ * JinHua Luo, GuangDong Linux Center, <luo.jinhua at gd-linux.com>
+ *
+ * Modified for the Embest SBC2440-II by
+ * (C) Copyright 2009
+ * Kevin Morfitt, Fearnside Systems Ltd, <kevin.morfitt at fearnside-systems.co.uk>
+ *
+ * Configuation settings for the friendly-arm SBC-2410X board.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+
+#define CONFIG_IDENT_STRING	" for Embest SBC2440-II"
+
+/*
+ * If we are developing, we might want to start armboot from ram
+ * so we MUST NOT initialize critical regs like mem-timing ...
+ */
+#undef CONFIG_SKIP_LOWLEVEL_INIT	/* undef for developing */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARM920T		1	/* This is an ARM920T Core	*/
+#define CONFIG_S3C2440		1	/* in a SAMSUNG S3C2440 SoC     */
+#define CONFIG_SBC2440II	1	/* on an Embest SBC-2440-II Board  */
+
+/*
+ * input clock of PLL - the SBC2440-II has 12MHz input clock
+ */
+#define CONFIG_SYS_CLK_FREQ	12000000
+
+
+#define USE_920T_MMU		1
+#undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128*1024)
+/*
+ * size in bytes reserved for initial data
+ */
+#define CONFIG_SYS_GBL_DATA_SIZE	128
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_DRIVER_CS8900	1	/* we have a CS8900 on-board */
+#define CS8900_BASE		0x19000300
+#define CS8900_BUS16		1 /* the Linux driver does accesses as shorts */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_S3C24X0_SERIAL
+#define CONFIG_SERIAL1          1	/* we use SERIAL 1 on SBC2440-II */
+
+/************************************************************
+ * RTC
+ ************************************************************/
+#define CONFIG_RTC_S3C24X0	1
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE		115200
+
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+
+
+/*
+ * Command line configuration.
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_ELF
+
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_NAND
+#define CONFIG_JFFS2_NAND
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_JFFS2
+#define CONFIG_JFFS2_CMDLINE
+#define MTDIDS_DEFAULT		"nand0=sbc2440-II-nand"
+#define MTDPARTS_DEFAULT \
+	"mtdparts=sbc2440-II-nand:2m(kernel),62m(rootfs)"
+#define CONFIG_EXTRA_ENV_SETTINGS	"autostart=yes"
+
+#define CONFIG_BOOTDELAY		3
+#define CONFIG_BOOTARGS \
+"noinitrd root=/dev/mtdblock1 rootfstype=jffs2 init=/linuxrc console=ttySAC0"
+#define CONFIG_LOADADDR			30008000
+/*#define CONFIG_BOOTFILE		"elinos-lart" */
+#define CONFIG_BOOTCOMMAND		"nboot 30008000 0 0"
+/*#define CONFIG_NFSBOOTCOMMAND	NFS_BOOTARGS*/
+
+#if defined(CONFIG_CMD_KGDB)
+/*
+ * speed to run kgdb serial port
+ */
+#define CONFIG_KGDB_BAUDRATE	115200
+/*
+ * which serial port to use
+ */
+#define CONFIG_KGDB_SER_INDEX	1
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP	/* undef to save memory		*/
+#define CONFIG_SYS_PROMPT	"[ SBC2440-II ]# "
+#define CONFIG_SYS_CBSIZE	256
+#define CONFIG_SYS_PBSIZE 	(CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
+#define CONFIG_SYS_MAXARGS	16
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+
+#define CONFIG_SYS_MEMTEST_START	0x30000000
+#define CONFIG_SYS_MEMTEST_END		0x33F00000
+
+#undef CONFIG_SYS_CLKS_IN_HZ	/* everything, incl board info, in Hz */
+
+#define CONFIG_SYS_LOAD_ADDR	0x33000000	/* default load address	*/
+
+/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
+/* it to wrap 100 times (total 1562500) to get 1 sec. */
+#define CONFIG_SYS_HZ			1562500
+
+/* valid baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE	(128*1024)	/* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ	(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ	(4*1024)	/* FIQ stack */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS	1	   /* we have 1 bank of DRAM */
+#define PHYS_SDRAM_1		0x30000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE	0x04000000 /* 64 MB */
+
+#define PHYS_FLASH_1		0x00000000 /* Flash Bank #1 */
+
+#define CONFIG_SYS_FLASH_BASE	PHYS_FLASH_1
+#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_FLASH_BASE
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment and organization
+ */
+
+#define CONFIG_ENV_IS_IN_FLASH	1
+#define CONFIG_ENV_SIZE		0x10000	/* Total Size of Environment Sector */
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1	/* max number of memory banks */
+#define PHYS_FLASH_SIZE			0x00200000 /* 2MB */
+#define CONFIG_SYS_MAX_FLASH_SECT	(35)
+#define CONFIG_ENV_ADDR \
+	(CONFIG_SYS_FLASH_BASE + PHYS_FLASH_SIZE - CONFIG_ENV_SIZE)
+
+/*-----------------------------------------------------------------------
+ * FLASH driver setup
+ */
+#define CONFIG_SYS_FLASH_CFI			1
+#define CONFIG_FLASH_CFI_DRIVER			1
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE	1
+
+/* timeout values are in ticks */
+#define CONFIG_SYS_FLASH_ERASE_TOUT	(20*CONFIG_SYS_HZ)
+#define CONFIG_SYS_FLASH_WRITE_TOUT	(20*CONFIG_SYS_HZ)
+
+/*-----------------------------------------------------------------------
+ * NAND flash settings
+ */
+#if defined(CONFIG_CMD_NAND)
+	#define CONFIG_NAND_S3C2410
+	#define CONFIG_SYS_NAND_BASE		0x4e00000c
+	#define CONFIG_SYS_MAX_NAND_DEVICE	1
+	#define SECTORSIZE 			512
+/*	#define CONFIG_S3C2410_NAND_HWECC*/
+#endif	/* CONFIG_CMD_NAND */
+
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2   "> "
+
+#define CONFIG_CMDLINE_EDITING
+
+#ifdef CONFIG_CMDLINE_EDITING
+#undef CONFIG_AUTO_COMPLETE
+#else
+#define CONFIG_AUTO_COMPLETE
+#endif
+
+#endif	/* __CONFIG_H */
diff --git a/include/s3c2440.h b/include/s3c2440.h
new file mode 100644
index 0000000..df2eb7a
--- /dev/null
+++ b/include/s3c2440.h
@@ -0,0 +1,231 @@
+/*
+ * (C) Copyright 2003
+ * David Müller ELSOFT AG Switzerland. d.mueller at elsoft.ch
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * Modified for the Embest SBC2440-II by
+ * (C) Copyright 2009
+ * Kevin Morfitt, Fearnside Systems Ltd, <kevin.morfitt at fearnside-systems.co.uk>
+ *
+ * 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
+ */
+
+/************************************************
+ * NAME	    : s3c2440.h
+ * Version  : 24.10.2008
+ *
+ * Based on S3C2440X User's manual Rev 1.3
+ ************************************************/
+
+#ifndef __S3C2440_H__
+#define __S3C2440_H__
+
+#define S3C24X0_UART_CHANNELS	3
+#define S3C24X0_SPI_CHANNELS	2
+
+/* S3C2410 only supports 512 Byte HW ECC */
+#define S3C2410_ECCSIZE		512
+#define S3C2410_ECCBYTES	3
+
+typedef enum {
+	S3C24X0_UART0,
+	S3C24X0_UART1,
+	S3C24X0_UART2
+} S3C24X0_UARTS_NR;
+
+/* S3C2440 device base addresses */
+#define S3C24X0_MEMCTL_BASE		0x48000000
+#define S3C24X0_USB_HOST_BASE		0x49000000
+#define S3C24X0_INTERRUPT_BASE		0x4A000000
+#define S3C24X0_DMA_BASE		0x4B000000
+#define S3C24X0_CLOCK_POWER_BASE	0x4C000000
+#define S3C24X0_LCD_BASE		0x4D000000
+#define S3C2440_NAND_BASE		0x4E000000
+#define S3C24X0_UART_BASE		0x50000000
+#define S3C24X0_TIMER_BASE		0x51000000
+#define S3C24X0_USB_DEVICE_BASE		0x52000140
+#define S3C24X0_WATCHDOG_BASE		0x53000000
+#define S3C24X0_I2C_BASE		0x54000000
+#define S3C24X0_I2S_BASE		0x55000000
+#define S3C24X0_GPIO_BASE		0x56000000
+#define S3C24X0_RTC_BASE		0x57000000
+#define S3C2410_ADC_BASE		0x58000000
+#define S3C24X0_SPI_BASE		0x59000000
+#define S3C2410_SDI_BASE		0x5A000000
+
+
+/* include common stuff */
+#include <s3c24x0.h>
+
+
+static inline S3C24X0_MEMCTL *S3C24X0_GetBase_MEMCTL(void)
+{
+	return (S3C24X0_MEMCTL * const)S3C24X0_MEMCTL_BASE;
+}
+static inline S3C24X0_USB_HOST *S3C24X0_GetBase_USB_HOST(void)
+{
+	return (S3C24X0_USB_HOST * const)S3C24X0_USB_HOST_BASE;
+}
+static inline S3C24X0_INTERRUPT *S3C24X0_GetBase_INTERRUPT(void)
+{
+	return (S3C24X0_INTERRUPT * const)S3C24X0_INTERRUPT_BASE;
+}
+static inline S3C24X0_DMAS *S3C24X0_GetBase_DMAS(void)
+{
+	return (S3C24X0_DMAS * const)S3C24X0_DMA_BASE;
+}
+static inline S3C24X0_CLOCK_POWER *S3C24X0_GetBase_CLOCK_POWER(void)
+{
+	return (S3C24X0_CLOCK_POWER * const)S3C24X0_CLOCK_POWER_BASE;
+}
+static inline S3C24X0_LCD *S3C24X0_GetBase_LCD(void)
+{
+	return (S3C24X0_LCD * const)S3C24X0_LCD_BASE;
+}
+static inline S3C2440_NAND *S3C2440_GetBase_NAND(void)
+{
+	return (S3C2440_NAND * const)S3C2440_NAND_BASE;
+}
+static inline S3C24X0_UART *S3C24X0_GetBase_UART(S3C24X0_UARTS_NR nr)
+{
+	return (S3C24X0_UART * const)(S3C24X0_UART_BASE + (nr * 0x4000));
+}
+static inline S3C24X0_TIMERS *S3C24X0_GetBase_TIMERS(void)
+{
+	return (S3C24X0_TIMERS * const)S3C24X0_TIMER_BASE;
+}
+static inline S3C24X0_USB_DEVICE *S3C24X0_GetBase_USB_DEVICE(void)
+{
+	return (S3C24X0_USB_DEVICE * const)S3C24X0_USB_DEVICE_BASE;
+}
+static inline S3C24X0_WATCHDOG *S3C24X0_GetBase_WATCHDOG(void)
+{
+	return (S3C24X0_WATCHDOG * const)S3C24X0_WATCHDOG_BASE;
+}
+static inline S3C24X0_I2C *S3C24X0_GetBase_I2C(void)
+{
+	return (S3C24X0_I2C * const)S3C24X0_I2C_BASE;
+}
+static inline S3C24X0_I2S *S3C24X0_GetBase_I2S(void)
+{
+	return (S3C24X0_I2S * const)S3C24X0_I2S_BASE;
+}
+static inline S3C24X0_GPIO *S3C24X0_GetBase_GPIO(void)
+{
+	return (S3C24X0_GPIO * const)S3C24X0_GPIO_BASE;
+}
+static inline S3C24X0_RTC *S3C24X0_GetBase_RTC(void)
+{
+	return (S3C24X0_RTC * const)S3C24X0_RTC_BASE;
+}
+static inline S3C2410_ADC *S3C2410_GetBase_ADC(void)
+{
+	return (S3C2410_ADC * const)S3C2410_ADC_BASE;
+}
+static inline S3C24X0_SPI *S3C24X0_GetBase_SPI(void)
+{
+	return (S3C24X0_SPI * const)S3C24X0_SPI_BASE;
+}
+static inline S3C2410_SDI *S3C2410_GetBase_SDI(void)
+{
+	return (S3C2410_SDI * const)S3C2410_SDI_BASE;
+}
+
+
+/* ISR */
+#define pISR_RESET		(*(unsigned *)(_ISR_STARTADDRESS+0x0))
+#define pISR_UNDEF		(*(unsigned *)(_ISR_STARTADDRESS+0x4))
+#define pISR_SWI		(*(unsigned *)(_ISR_STARTADDRESS+0x8))
+#define pISR_PABORT		(*(unsigned *)(_ISR_STARTADDRESS+0xC))
+#define pISR_DABORT		(*(unsigned *)(_ISR_STARTADDRESS+0x10))
+#define pISR_RESERVED		(*(unsigned *)(_ISR_STARTADDRESS+0x14))
+#define pISR_IRQ		(*(unsigned *)(_ISR_STARTADDRESS+0x18))
+#define pISR_FIQ		(*(unsigned *)(_ISR_STARTADDRESS+0x1C))
+
+#define pISR_EINT0		(*(unsigned *)(_ISR_STARTADDRESS+0x20))
+#define pISR_EINT1		(*(unsigned *)(_ISR_STARTADDRESS+0x24))
+#define pISR_EINT2		(*(unsigned *)(_ISR_STARTADDRESS+0x28))
+#define pISR_EINT3		(*(unsigned *)(_ISR_STARTADDRESS+0x2C))
+#define pISR_EINT4_7		(*(unsigned *)(_ISR_STARTADDRESS+0x30))
+#define pISR_EINT8_23		(*(unsigned *)(_ISR_STARTADDRESS+0x34))
+#define pISR_BAT_FLT		(*(unsigned *)(_ISR_STARTADDRESS+0x3C))
+#define pISR_TICK		(*(unsigned *)(_ISR_STARTADDRESS+0x40))
+#define pISR_WDT		(*(unsigned *)(_ISR_STARTADDRESS+0x44))
+#define pISR_TIMER0		(*(unsigned *)(_ISR_STARTADDRESS+0x48))
+#define pISR_TIMER1		(*(unsigned *)(_ISR_STARTADDRESS+0x4C))
+#define pISR_TIMER2		(*(unsigned *)(_ISR_STARTADDRESS+0x50))
+#define pISR_TIMER3		(*(unsigned *)(_ISR_STARTADDRESS+0x54))
+#define pISR_TIMER4		(*(unsigned *)(_ISR_STARTADDRESS+0x58))
+#define pISR_UART2		(*(unsigned *)(_ISR_STARTADDRESS+0x5C))
+#define pISR_NOTUSED		(*(unsigned *)(_ISR_STARTADDRESS+0x60))
+#define pISR_DMA0		(*(unsigned *)(_ISR_STARTADDRESS+0x64))
+#define pISR_DMA1		(*(unsigned *)(_ISR_STARTADDRESS+0x68))
+#define pISR_DMA2		(*(unsigned *)(_ISR_STARTADDRESS+0x6C))
+#define pISR_DMA3		(*(unsigned *)(_ISR_STARTADDRESS+0x70))
+#define pISR_SDI		(*(unsigned *)(_ISR_STARTADDRESS+0x74))
+#define pISR_SPI0		(*(unsigned *)(_ISR_STARTADDRESS+0x78))
+#define pISR_UART1		(*(unsigned *)(_ISR_STARTADDRESS+0x7C))
+#define pISR_USBD		(*(unsigned *)(_ISR_STARTADDRESS+0x84))
+#define pISR_USBH		(*(unsigned *)(_ISR_STARTADDRESS+0x88))
+#define pISR_IIC		(*(unsigned *)(_ISR_STARTADDRESS+0x8C))
+#define pISR_UART0		(*(unsigned *)(_ISR_STARTADDRESS+0x90))
+#define pISR_SPI1		(*(unsigned *)(_ISR_STARTADDRESS+0x94))
+#define pISR_RTC		(*(unsigned *)(_ISR_STARTADDRESS+0x98))
+#define pISR_ADC		(*(unsigned *)(_ISR_STARTADDRESS+0xA0))
+
+
+/* PENDING BIT */
+#define BIT_EINT0		(0x1)
+#define BIT_EINT1		(0x1<<1)
+#define BIT_EINT2		(0x1<<2)
+#define BIT_EINT3		(0x1<<3)
+#define BIT_EINT4_7		(0x1<<4)
+#define BIT_EINT8_23		(0x1<<5)
+#define BIT_BAT_FLT		(0x1<<7)
+#define BIT_TICK		(0x1<<8)
+#define BIT_WDT			(0x1<<9)
+#define BIT_TIMER0		(0x1<<10)
+#define BIT_TIMER1		(0x1<<11)
+#define BIT_TIMER2		(0x1<<12)
+#define BIT_TIMER3		(0x1<<13)
+#define BIT_TIMER4		(0x1<<14)
+#define BIT_UART2		(0x1<<15)
+#define BIT_LCD			(0x1<<16)
+#define BIT_DMA0		(0x1<<17)
+#define BIT_DMA1		(0x1<<18)
+#define BIT_DMA2		(0x1<<19)
+#define BIT_DMA3		(0x1<<20)
+#define BIT_SDI			(0x1<<21)
+#define BIT_SPI0		(0x1<<22)
+#define BIT_UART1		(0x1<<23)
+#define BIT_USBD		(0x1<<25)
+#define BIT_USBH		(0x1<<26)
+#define BIT_IIC			(0x1<<27)
+#define BIT_UART0		(0x1<<28)
+#define BIT_SPI1		(0x1<<29)
+#define BIT_RTC			(0x1<<30)
+#define BIT_ADC			(0x1<<31)
+#define BIT_ALLMSK		(0xFFFFFFFF)
+
+#define ClearPending(bit) {\
+		 rSRCPND = bit;\
+		 rINTPND = bit;\
+		 rINTPND;\
+		 }
+/* Wait until rINTPND is changed for the case that the ISR is very short. */
+#endif /*__S3C2440_H__*/
diff --git a/include/s3c24x0.h b/include/s3c24x0.h
index 71f35a5..c51d58e 100644
--- a/include/s3c24x0.h
+++ b/include/s3c24x0.h
@@ -126,6 +126,9 @@ typedef struct {
 	S3C24X0_REG32	CLKCON;
 	S3C24X0_REG32	CLKSLOW;
 	S3C24X0_REG32	CLKDIVN;
+#ifdef CONFIG_S3C2440
+	S3C24X0_REG32	CAMDIVN;
+#endif
 } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;
 
 
@@ -154,6 +157,7 @@ typedef struct {
 } /*__attribute__((__packed__))*/ S3C24X0_LCD;
 
 
+#ifdef CONFIG_S3C2410
 /* NAND FLASH (see S3C2410 manual chapter 6) */
 typedef struct {
 	S3C24X0_REG32	NFCONF;
@@ -163,6 +167,27 @@ typedef struct {
 	S3C24X0_REG32	NFSTAT;
 	S3C24X0_REG32	NFECC;
 } /*__attribute__((__packed__))*/ S3C2410_NAND;
+#elif defined CONFIG_S3C2440
+/* NAND FLASH (see S3C2440 manual chapter 6 ) */
+typedef struct {
+	S3C24X0_REG32	NFCONF;
+	S3C24X0_REG32	NFCONT;
+	S3C24X0_REG32	NFCMD;
+	S3C24X0_REG32	NFADDR;
+	S3C24X0_REG32	NFDATA;
+	S3C24X0_REG32	NFMECCD0;
+	S3C24X0_REG32	NFMECCD1;
+	S3C24X0_REG32	NFSECCD;
+	S3C24X0_REG32	NFSTAT;
+	S3C24X0_REG32	NFESTAT0;
+	S3C24X0_REG32	NFESTAT1;
+	S3C24X0_REG32	NFMECC0;
+	S3C24X0_REG32	NFMECC1;
+	S3C24X0_REG32	NFSECC;
+	S3C24X0_REG32	NFSBLOCK;
+	S3C24X0_REG32	NFEBLOCK;
+} /*__attribute__((__packed__))*/ S3C2440_NAND;
+#endif
 
 
 /* UART (see manual chapter 11) */
@@ -451,6 +476,64 @@ typedef struct {
 	S3C24X0_REG32	GSTATUS3;
 	S3C24X0_REG32	GSTATUS4;
 #endif
+#ifdef CONFIG_S3C2440
+	S3C24X0_REG32	GPACON;
+	S3C24X0_REG32	GPADAT;
+	S3C24X0_REG32	res1[2];
+	S3C24X0_REG32	GPBCON;
+	S3C24X0_REG32	GPBDAT;
+	S3C24X0_REG32	GPBUP;
+	S3C24X0_REG32	res2;
+	S3C24X0_REG32	GPCCON;
+	S3C24X0_REG32	GPCDAT;
+	S3C24X0_REG32	GPCUP;
+	S3C24X0_REG32	res3;
+	S3C24X0_REG32	GPDCON;
+	S3C24X0_REG32	GPDDAT;
+	S3C24X0_REG32	GPDUP;
+	S3C24X0_REG32	res4;
+	S3C24X0_REG32	GPECON;
+	S3C24X0_REG32	GPEDAT;
+	S3C24X0_REG32	GPEUP;
+	S3C24X0_REG32	res5;
+	S3C24X0_REG32	GPFCON;
+	S3C24X0_REG32	GPFDAT;
+	S3C24X0_REG32	GPFUP;
+	S3C24X0_REG32	res6;
+	S3C24X0_REG32	GPGCON;
+	S3C24X0_REG32	GPGDAT;
+	S3C24X0_REG32	GPGUP;
+	S3C24X0_REG32	res7;
+	S3C24X0_REG32	GPHCON;
+	S3C24X0_REG32	GPHDAT;
+	S3C24X0_REG32	GPHUP;
+	S3C24X0_REG32	res8;
+
+	S3C24X0_REG32	MISCCR;
+	S3C24X0_REG32	DCLKCON;
+	S3C24X0_REG32	EXTINT0;
+	S3C24X0_REG32	EXTINT1;
+	S3C24X0_REG32	EXTINT2;
+	S3C24X0_REG32	EINTFLT0;
+	S3C24X0_REG32	EINTFLT1;
+	S3C24X0_REG32	EINTFLT2;
+	S3C24X0_REG32	EINTFLT3;
+	S3C24X0_REG32	EINTMASK;
+	S3C24X0_REG32	EINTPEND;
+	S3C24X0_REG32	GSTATUS0;
+	S3C24X0_REG32	GSTATUS1;
+	S3C24X0_REG32	GSTATUS2;
+	S3C24X0_REG32	GSTATUS3;
+	S3C24X0_REG32	GSTATUS4;
+	S3C24X0_REG32	res9;
+
+	S3C24X0_REG32	DSC0;
+	S3C24X0_REG32	DSC1;
+	S3C24X0_REG32	MSLCON;
+	S3C24X0_REG32	GPJCON;
+	S3C24X0_REG32	GPJDAT;
+	S3C24X0_REG32	GPJUP;
+#endif
 } /*__attribute__((__packed__))*/ S3C24X0_GPIO;
 
 
-- 
1.6.0.6


More information about the U-Boot mailing list