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

kevin.morfitt at fearnside-systems.co.uk kevin.morfitt at fearnside-systems.co.uk
Thu Mar 26 01:14:03 CET 2009


Adds support for the Embest SBC2440-II Board (see 
http://www.embedinfo.com/english/product/sbc2440-II.asp) with u-boot 
programmed in NOR flash.

Implementation is based on the existing u-boot support for s3C2410-based 
boards. Where I've copied and modified existing files I've left the 
style of the original code as it was, including any non-conformance with 
the u-boot coding style. Where I've added new code I've aimed to use the 
u-boot coding style. I've run MAKEALL with the LIST_ARM9 targets only as 
the changes don't affect any other architectures.

Signed-off-by: Kevin Morfitt <kevin.morfitt at fearnside-systems.co.uk>

diff -uprN u-boot-2009.03/MAKEALL u-boot-2009.03-PATCHED/MAKEALL
--- u-boot-2009.03/MAKEALL    2009-03-21 21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/MAKEALL    2009-03-25 21:48:14.171875000 +0000
@@ -512,6 +512,7 @@ LIST_ARM9="            \
     omap5912osk        \
     omap730p2        \
     sbc2410x        \
+    sbc2440ii    \
     scb9328            \
     smdk2400        \
     smdk2410        \
diff -uprN u-boot-2009.03/Makefile u-boot-2009.03-PATCHED/Makefile
--- u-boot-2009.03/Makefile    2009-03-21 21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/Makefile    2009-03-22 09:42:11.078125000 +0000
@@ -2821,6 +2821,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 -uprN u-boot-2009.03/board/embest/sbc2440ii/Makefile 
u-boot-2009.03-PATCHED/board/embest/sbc2440ii/Makefile
--- u-boot-2009.03/board/embest/sbc2440ii/Makefile    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/board/embest/sbc2440ii/Makefile    2009-03-22 
09:44:24.640625000 +0000
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000-2006
+# 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$(BOARD).a
+
+COBJS    := sbc2440ii.o flash.o sbc2440ii_cmd.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 -uprN u-boot-2009.03/board/embest/sbc2440ii/config.mk 
u-boot-2009.03-PATCHED/board/embest/sbc2440ii/config.mk
--- u-boot-2009.03/board/embest/sbc2440ii/config.mk    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/board/embest/sbc2440ii/config.mk   
 2009-03-25 21:05:21.281250000 +0000
@@ -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 -uprN u-boot-2009.03/board/embest/sbc2440ii/flash.c 
u-boot-2009.03-PATCHED/board/embest/sbc2440ii/flash.c
--- u-boot-2009.03/board/embest/sbc2440ii/flash.c    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/board/embest/sbc2440ii/flash.c    2009-03-22 
21:43:19.765625000 +0000
@@ -0,0 +1,437 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu at sysgo.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 <common.h>
+
+ulong myflush (void);
+
+#define FLASH_BANK_SIZE    PHYS_FLASH_SIZE
+#define MAIN_SECT_SIZE  0x10000    /* 64 KB */
+
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+
+#define CMD_READ_ARRAY        0x000000F0
+#define CMD_UNLOCK1        0x000000AA
+#define CMD_UNLOCK2        0x00000055
+#define CMD_ERASE_SETUP        0x00000080
+#define CMD_ERASE_CONFIRM    0x00000030
+#define CMD_PROGRAM        0x000000A0
+#define CMD_UNLOCK_BYPASS    0x00000020
+
+#define MEM_FLASH_ADDR1        (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE 
+ (0x00000555 << 1)))
+#define MEM_FLASH_ADDR2        (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE 
+ (0x000002AA << 1)))
+
+#define BIT_ERASE_DONE        0x00000080
+#define BIT_RDY_MASK        0x00000080
+#define BIT_PROGRAM_ERROR    0x00000020
+#define BIT_TIMEOUT        0x80000000    /* our flag */
+
+#define READY 1
+#define ERR   2
+#define TMO   4
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init (void)
+{
+    int i, j;
+    ulong size = 0;
+
+    for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
+        ulong flashbase = 0;
+
+        flash_info[i].flash_id =
+#if defined(CONFIG_AMD_LV400)
+            (AMD_MANUFACT & FLASH_VENDMASK) |
+            (AMD_ID_LV400B & FLASH_TYPEMASK);
+#elif defined(CONFIG_AMD_LV800)
+            (AMD_MANUFACT & FLASH_VENDMASK) |
+            (AMD_ID_LV800B & FLASH_TYPEMASK);
+#elif defined(CONFIG_AMD_LV160B)
+            (AMD_MANUFACT & FLASH_VENDMASK) |
+            (AMD_ID_LV160B & FLASH_TYPEMASK);
+#else
+#error "Unknown flash configured"
+#endif
+            flash_info[i].size = FLASH_BANK_SIZE;
+        flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
+        memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
+        if (i == 0)
+            flashbase = PHYS_FLASH_1;
+        else
+            panic ("configured too many flash banks!\n");
+        for (j = 0; j < flash_info[i].sector_count; j++) {
+            if (j <= 3) {
+                /* 1st one is 16 KB */
+                if (j == 0) {
+                    flash_info[i].start[j] =
+                        flashbase + 0;
+                }
+
+                /* 2nd and 3rd are both 8 KB */
+                if ((j == 1) || (j == 2)) {
+                    flash_info[i].start[j] =
+                        flashbase + 0x4000 + (j -
+                                      1) *
+                        0x2000;
+                }
+
+                /* 4th 32 KB */
+                if (j == 3) {
+                    flash_info[i].start[j] =
+                        flashbase + 0x8000;
+                }
+            } else {
+                flash_info[i].start[j] =
+                    flashbase + (j - 3) * MAIN_SECT_SIZE;
+            }
+        }
+        size += flash_info[i].size;
+    }
+
+    flash_protect (FLAG_PROTECT_SET,
+               CONFIG_SYS_FLASH_BASE,
+               CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
+               &flash_info[0]);
+
+    flash_protect (FLAG_PROTECT_SET,
+               CONFIG_ENV_ADDR,
+               CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
+
+    return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+    int i;
+
+    switch (info->flash_id & FLASH_VENDMASK) {
+    case (AMD_MANUFACT & FLASH_VENDMASK):
+        printf ("AMD: ");
+        break;
+    default:
+        printf ("Unknown Vendor ");
+        break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+    case (AMD_ID_LV400B & FLASH_TYPEMASK):
+        printf ("1x Amd29LV400BB (4Mbit)\n");
+        break;
+    case (AMD_ID_LV800B & FLASH_TYPEMASK):
+        printf ("1x Amd29LV800BB (8Mbit)\n");
+        break;
+    case (AMD_ID_LV160B & FLASH_TYPEMASK):
+        printf ("1x Amd29LV160DB (16Mbit)\n");
+        break;
+    default:
+        printf ("Unknown Chip Type\n");
+        goto Done;
+        break;
+    }
+
+    printf ("  Size: %ld MB in %d Sectors\n",
+        info->size >> 20, info->sector_count);
+
+    printf ("  Sector Start Addresses:");
+    for (i = 0; i < info->sector_count; i++) {
+        if ((i % 5) == 0) {
+            printf ("\n   ");
+        }
+        printf (" %08lX%s", info->start[i],
+            info->protect[i] ? " (RO)" : "     ");
+    }
+    printf ("\n");
+
+      Done:;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+    ushort result;
+    int iflag, cflag, prot, sect;
+    int rc = ERR_OK;
+    int chip;
+
+    /* first look for protection bits */
+
+    if (info->flash_id == FLASH_UNKNOWN)
+        return ERR_UNKNOWN_FLASH_TYPE;
+
+    if ((s_first < 0) || (s_first > s_last)) {
+        return ERR_INVAL;
+    }
+
+    if ((info->flash_id & FLASH_VENDMASK) !=
+        (AMD_MANUFACT & FLASH_VENDMASK)) {
+        return ERR_UNKNOWN_FLASH_VENDOR;
+    }
+
+    prot = 0;
+    for (sect = s_first; sect <= s_last; ++sect) {
+        if (info->protect[sect]) {
+            prot++;
+        }
+    }
+    if (prot)
+        return ERR_PROTECTED;
+
+    /*
+     * Disable interrupts which might cause a timeout
+     * here. Remember that our exception vectors are
+     * at address 0 in the flash, and we don't want a
+     * (ticker) exception to happen while the flash
+     * chip is in programming mode.
+     */
+    cflag = icache_status ();
+    icache_disable ();
+    iflag = disable_interrupts ();
+
+    /* Start erase on unprotected sectors */
+    for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+        printf ("Erasing sector %2d ... ", sect);
+
+        /* arm simple, non interrupt dependent timer */
+        reset_timer_masked ();
+
+        if (info->protect[sect] == 0) {    /* not protected */
+            vu_short *addr = (vu_short *) (info->start[sect]);
+
+            MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+            MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+            MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
+
+            MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+            MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+            *addr = CMD_ERASE_CONFIRM;
+
+            /* wait until flash is ready */
+            chip = 0;
+
+            do {
+                result = *addr;
+
+                /* check timeout */
+                if (get_timer_masked () >
+                    CONFIG_SYS_FLASH_ERASE_TOUT) {
+                    MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+                    chip = TMO;
+                    break;
+                }
+
+                if (!chip
+                    && (result & 0xFFFF) & BIT_ERASE_DONE)
+                    chip = READY;
+
+                if (!chip
+                    && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
+                    chip = ERR;
+
+            } while (!chip);
+
+            MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+
+            if (chip == ERR) {
+                rc = ERR_PROG_ERROR;
+                goto outahere;
+            }
+            if (chip == TMO) {
+                rc = ERR_TIMOUT;
+                goto outahere;
+            }
+
+            printf ("ok.\n");
+        } else {    /* it was protected */
+
+            printf ("protected!\n");
+        }
+    }
+
+    if (ctrlc ())
+        printf ("User Interrupt!\n");
+
+      outahere:
+    /* allow flash to settle - wait 10 ms */
+    udelay_masked (10000);
+
+    if (iflag)
+        enable_interrupts ();
+
+    if (cflag)
+        icache_enable ();
+
+    return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_hword (flash_info_t * info, ulong dest, ushort data)
+{
+    vu_short *addr = (vu_short *) dest;
+    ushort result;
+    int rc = ERR_OK;
+    int cflag, iflag;
+    int chip;
+
+    /*
+     * Check if Flash is (sufficiently) erased
+     */
+    result = *addr;
+    if ((result & data) != data)
+        return ERR_NOT_ERASED;
+
+
+    /*
+     * Disable interrupts which might cause a timeout
+     * here. Remember that our exception vectors are
+     * at address 0 in the flash, and we don't want a
+     * (ticker) exception to happen while the flash
+     * chip is in programming mode.
+     */
+    cflag = icache_status ();
+    icache_disable ();
+    iflag = disable_interrupts ();
+
+    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+    MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
+    *addr = CMD_PROGRAM;
+    *addr = data;
+
+    /* arm simple, non interrupt dependent timer */
+    reset_timer_masked ();
+
+    /* wait until flash is ready */
+    chip = 0;
+    do {
+        result = *addr;
+
+        /* check timeout */
+        if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) {
+            chip = ERR | TMO;
+            break;
+        }
+        if (!chip && ((result & 0x80) == (data & 0x80)))
+            chip = READY;
+
+        if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
+            result = *addr;
+
+            if ((result & 0x80) == (data & 0x80))
+                chip = READY;
+            else
+                chip = ERR;
+        }
+
+    } while (!chip);
+
+    *addr = CMD_READ_ARRAY;
+
+    if (chip == ERR || *addr != data)
+        rc = ERR_PROG_ERROR;
+
+    if (iflag)
+        enable_interrupts ();
+
+    if (cflag)
+        icache_enable ();
+
+    return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+    ulong cp, wp;
+    int l;
+    int i, rc;
+    ushort data;
+
+    wp = (addr & ~1);    /* get lower word aligned address */
+
+    /*
+     * handle unaligned start bytes
+     */
+    if ((l = addr - wp) != 0) {
+        data = 0;
+        for (i = 0, cp = wp; i < l; ++i, ++cp) {
+            data = (data >> 8) | (*(uchar *) cp << 8);
+        }
+        for (; i < 2 && cnt > 0; ++i) {
+            data = (data >> 8) | (*src++ << 8);
+            --cnt;
+            ++cp;
+        }
+        for (; cnt == 0 && i < 2; ++i, ++cp) {
+            data = (data >> 8) | (*(uchar *) cp << 8);
+        }
+
+        if ((rc = write_hword (info, wp, data)) != 0) {
+            return (rc);
+        }
+        wp += 2;
+    }
+
+    /*
+     * handle word aligned part
+     */
+    while (cnt >= 2) {
+        data = *((vu_short *) src);
+        if ((rc = write_hword (info, wp, data)) != 0) {
+            return (rc);
+        }
+        src += 2;
+        wp += 2;
+        cnt -= 2;
+    }
+
+    if (cnt == 0) {
+        return ERR_OK;
+    }
+
+    /*
+     * handle unaligned tail bytes
+     */
+    data = 0;
+    for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
+        data = (data >> 8) | (*src++ << 8);
+        --cnt;
+    }
+    for (; i < 2; ++i, ++cp) {
+        data = (data >> 8) | (*(uchar *) cp << 8);
+    }
+
+    return write_hword (info, wp, data);
+}
diff -uprN u-boot-2009.03/board/embest/sbc2440ii/lowlevel_init.S 
u-boot-2009.03-PATCHED/board/embest/sbc2440ii/lowlevel_init.S
--- u-boot-2009.03/board/embest/sbc2440ii/lowlevel_init.S    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/board/embest/sbc2440ii/lowlevel_init.S   
 2009-03-25 21:04:56.656250000 +0000
@@ -0,0 +1,188 @@
+/*
+ * 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
+
+/* BWSCON */
+#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 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 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 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 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 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 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 B6_MT            0x3    /* SDRAM */
+#define B6_Trcd        0x2
+#define B6_SCAN        0x1    /* 9bit */
+
+#define B7_MT            0x3    /* SDRAM */
+#define B7_Trcd        0x2    /* 4clk */
+#define B7_SCAN        0x1    /* 9bit */
+
+/* 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
+
+/* 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 */
+
+/* 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
+
+/* 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
+
+/**************************************/
+
+_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 
(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
+    .word 
((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
+    .word 
((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
+    .word 
((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
+    .word 
((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
+    .word 
((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
+    .word 
((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
+    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+    .word ((BURST_EN<<7)+(SCKE_EN<<5)+(SCLK_EN<<4)+(BK67MAP))
+    .word ((WBL6<<9)+(TM6<<7)+(CL6<<4)+(BT6<<3)+(BL6))
+    .word ((WBL7<<9)+(TM7<<7)+(CL7<<4)+(BT7<<3)+(BL7))
diff -uprN u-boot-2009.03/board/embest/sbc2440ii/sbc2440ii.c 
u-boot-2009.03-PATCHED/board/embest/sbc2440ii/sbc2440ii.c
--- u-boot-2009.03/board/embest/sbc2440ii/sbc2440ii.c    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/board/embest/sbc2440ii/sbc2440ii.c   
 2009-03-25 21:05:14.171875000 +0000
@@ -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;
+
+static inline void delay (unsigned long loops)
+{
+    __asm__ volatile ("1:\n"
+              "subs %0, %1, #1\n"
+              "bne 1b":"=r" (loops):"0" (loops));
+}
+
+/* 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
+ */
+
+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 */
+    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 -uprN u-boot-2009.03/board/embest/sbc2440ii/sbc2440ii_cmd.c 
u-boot-2009.03-PATCHED/board/embest/sbc2440ii/sbc2440ii_cmd.c
--- u-boot-2009.03/board/embest/sbc2440ii/sbc2440ii_cmd.c    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/board/embest/sbc2440ii/sbc2440ii_cmd.c   
 2009-03-25 21:05:37.984375000 +0000
@@ -0,0 +1,61 @@
+/*
+ * (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 <net.h>
+
+#if 0
+    #define DEBUGN    printf
+#else
+    #define DEBUGN(x, args ...) {}
+#endif
+
+static int get_file_tftp(struct cmd_tbl_s *cmftp, int flag, int argc, 
char *argv[]);
+
+U_BOOT_CMD(
+    tftp, 3, 0, get_file_tftp,
+    "tftp\t- Upload a file via TFTP",
+    "<address> <file name> - Upload <file name> to <address> via TFTP"
+);
+
+static int get_file_tftp(struct cmd_tbl_s *cmftp, int flag, int argc, 
char *argv[])
+{
+    load_addr = simple_strtoul(argv[1], NULL, 16);
+    copy_filename(BootFile, argv[2], sizeof (BootFile));
+    NetBootFileXferSize = 0;
+
+    DEBUGN("TFTP: Filename: %s Address: 0x%08X\n", BootFile, (unsigned 
int)load_addr);
+
+    if (NetLoop (TFTP) <= 0) {
+        printf("ERROR: tftp transfer failed\n");
+        return -1;
+    }
+
+    if (NetBootFileXferSize == 0) {
+        printf("ERROR: Can't determine file size\n");
+        return -1;
+    }
+
+    printf("File transfer succeeded - file size %lu bytes\n", 
NetBootFileXferSize);
+    return 0;
+}
diff -uprN u-boot-2009.03/board/embest/sbc2440ii/u-boot.lds 
u-boot-2009.03-PATCHED/board/embest/sbc2440ii/u-boot.lds
--- u-boot-2009.03/board/embest/sbc2440ii/u-boot.lds    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/board/embest/sbc2440ii/u-boot.lds   
 2009-03-22 09:49:23.765625000 +0000
@@ -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 -uprN u-boot-2009.03/cpu/arm920t/s3c24x0/i2c.c 
u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/i2c.c
--- u-boot-2009.03/cpu/arm920t/s3c24x0/i2c.c    2009-03-21 
21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/i2c.c    2009-03-22 
09:50:20.312500000 +0000
@@ -34,6 +34,8 @@
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 #include <i2c.h>
 
diff -uprN u-boot-2009.03/cpu/arm920t/s3c24x0/interrupts.c 
u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/interrupts.c
--- u-boot-2009.03/cpu/arm920t/s3c24x0/interrupts.c    2009-03-21 
21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/interrupts.c   
 2009-03-22 09:51:19.890625000 +0000
@@ -30,13 +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)
 
 #include <arm920t.h>
 #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;
@@ -178,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 -uprN u-boot-2009.03/cpu/arm920t/s3c24x0/nand.c 
u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/nand.c
--- u-boot-2009.03/cpu/arm920t/s3c24x0/nand.c    2009-03-21 
21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/nand.c    2009-03-25 
21:57:32.046875000 +0000
@@ -21,48 +21,114 @@
 #include <common.h>
 
 #if 0
-#define DEBUGN    printf
+    #define DEBUGCMD    printf
 #else
-#define DEBUGN(x, args ...) {}
+    #define DEBUGCMD(x, args ...) {}
+#endif
+
+#if 0
+    #define DEBUGECC    printf
+#else
+    #define DEBUGECC(x, args ...) {}
+#endif
+
+#if 0
+    #define DEEPDEBUGECC    printf
+#else
+    #define DEEPDEBUGECC(x, args ...) {}
 #endif
 
 #if defined(CONFIG_CMD_NAND)
 #if !defined(CONFIG_NAND_LEGACY)
 
 #include <nand.h>
-#include <s3c2410.h>
+#ifndef CONFIG_S3C2440
+    #include <s3c2410.h>
+#else
+    #include <s3c2440.h>
+#endif
 #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)
+#define NF_BASE        0x4e000000
+#define NFCONF            __REGi(NF_BASE + 0x0)
+#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)
+    {
+        DEBUGCMD("Negating nFCE\n");
+        NFCONT |= S3C2440_NFCONT_nFCE;
+    }
+    else
+    {
+        DEBUGCMD("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);
+    DEBUGCMD("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
 
     if (ctrl & NAND_CTRL_CHANGE) {
         ulong IO_ADDR_W = NF_BASE;
@@ -83,28 +149,63 @@ static void s3c2410_hwcontrol(struct mtd
     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)
+{
+    DEBUGCMD("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
+
+    if (cmd == NAND_CMD_NONE)
+    {
+        return;
+    }
+
+    if (ctrl & NAND_CLE)
+    {
+        DEBUGCMD("NFCMD = 0x%08X\n", cmd);
+        NFCMD = cmd;
+    }
+
+    if (ctrl & NAND_ALE)
+    {
+        DEBUGCMD("NFADDR = 0x%08X\n", cmd);
+        NFADDR = cmd;
+    }
+}
+#endif
 
 static int s3c2410_dev_ready(struct mtd_info *mtd)
 {
-    DEBUGN("dev_ready\n");
+    DEBUGCMD("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);
-    NFCONF |= S3C2410_NFCONF_INITECC;
+    DEBUGECC("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",
-        mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
+#else
+    unsigned long ecc = NFMECC0;
+
+    ecc_code[0] = ecc;
+    ecc_code[1] = ecc >> 8;
+    ecc_code[2] = ecc >> 16;
+#endif
+    DEBUGECC("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
+         mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
 
     return 0;
 }
@@ -112,13 +213,55 @@ static int s3c2410_nand_calculate_ecc(st
 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;
+
+    DEBUGECC("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];
+
+    DEEPDEBUGECC("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);
 
-    printf("s3c2410_nand_correct_data: not implemented\n");
-    return -1;
+        DEBUGECC("correcting error bit %d, byte %d\n", bit, byte);
+
+        dat[byte] ^= (1 << bit);
+        return 1;
+    }
+
+    DEBUGECC("Failed to correct ECC error\n");
+     return -1;
 }
 #endif
 
@@ -128,11 +271,12 @@ int board_nand_init(struct nand_chip *na
     u_int8_t tacls, twrph0, twrph1;
     S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
 
-    DEBUGN("board_nand_init()\n");
+    DEBUGCMD("board_nand_init()\n");
 
     clk_power->CLKCON |= (1 << 4);
 
     /* initialize hardware */
+#ifndef CONFIG_S3C2440
     twrph0 = 3; twrph1 = 0; tacls = 0;
 
     cfg = S3C2410_NFCONF_EN;
@@ -144,20 +288,49 @@ int board_nand_init(struct nand_chip *na
 
     /* 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;
+    }
+    DEBUGECC("ecc: size: %d bytes: %d\n", nand->ecc.size, nand->ecc.bytes);
 #else
     nand->ecc.mode = NAND_ECC_SOFT;
 #endif
@@ -168,12 +341,12 @@ int board_nand_init(struct nand_chip *na
     nand->options = 0;
 #endif
 
-    DEBUGN("end of nand_init\n");
+    DEBUGCMD("end of nand_init\n");
 
     return 0;
 }
 
 #else
- #error "U-Boot legacy NAND support not available for S3C2410"
+    #error "U-Boot legacy NAND support not available for S3C2410"
 #endif
 #endif
diff -uprN u-boot-2009.03/cpu/arm920t/s3c24x0/serial.c 
u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/serial.c
--- u-boot-2009.03/cpu/arm920t/s3c24x0/serial.c    2009-03-21 
21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/serial.c    2009-03-22 
18:55:46.531250000 +0000
@@ -19,12 +19,14 @@
  */
 
 #include <common.h>
-#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined 
(CONFIG_TRAB)
+#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined 
(CONFIG_TRAB) || defined(CONFIG_S3C2440)
 
 #if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
 #include <s3c2400.h>
 #elif defined(CONFIG_S3C2410)
 #include <s3c2410.h>
+#elif defined(CONFIG_S3C2440)
+#include <s3c2440.h>
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
diff -uprN u-boot-2009.03/cpu/arm920t/s3c24x0/speed.c 
u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/speed.c
--- u-boot-2009.03/cpu/arm920t/s3c24x0/speed.c    2009-03-21 
21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/speed.c    2009-03-25 
21:55:08.562500000 +0000
@@ -30,12 +30,14 @@
  */
 
 #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
@@ -67,7 +69,18 @@ static ulong get_PLLCLK(int pllreg)
     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 */
@@ -81,7 +94,21 @@ ulong get_HCLK(void)
 {
     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 */
@@ -95,7 +122,13 @@ ulong get_PCLK(void)
 /* return UCLK frequency */
 ulong get_UCLK(void)
 {
+#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 -uprN u-boot-2009.03/cpu/arm920t/s3c24x0/usb.c 
u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/usb.c
--- u-boot-2009.03/cpu/arm920t/s3c24x0/usb.c    2009-03-21 
21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/cpu/arm920t/s3c24x0/usb.c    2009-03-22 
18:59:36.984375000 +0000
@@ -24,12 +24,14 @@
 #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 -uprN u-boot-2009.03/cpu/arm920t/start.S 
u-boot-2009.03-PATCHED/cpu/arm920t/start.S
--- u-boot-2009.03/cpu/arm920t/start.S    2009-03-21 21:04:41.000000000 
+0000
+++ u-boot-2009.03-PATCHED/cpu/arm920t/start.S    2009-03-22 
19:04:16.140625000 +0000
@@ -132,7 +132,7 @@ 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)
@@ -146,6 +146,14 @@ copyex:
 #  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 +164,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 +173,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 -uprN u-boot-2009.03/drivers/rtc/s3c24x0_rtc.c 
u-boot-2009.03-PATCHED/drivers/rtc/s3c24x0_rtc.c
--- u-boot-2009.03/drivers/rtc/s3c24x0_rtc.c    2009-03-21 
21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/drivers/rtc/s3c24x0_rtc.c    2009-03-22 
19:05:14.328125000 +0000
@@ -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 -uprN u-boot-2009.03/include/common.h 
u-boot-2009.03-PATCHED/include/common.h
--- u-boot-2009.03/include/common.h    2009-03-21 21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/include/common.h    2009-03-22 
21:25:48.375000000 +0000
@@ -498,7 +498,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 -uprN u-boot-2009.03/include/configs/sbc2440ii.h 
u-boot-2009.03-PATCHED/include/configs/sbc2440ii.h
--- u-boot-2009.03/include/configs/sbc2440ii.h    1970-01-01 
00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/include/configs/sbc2440ii.h    2009-03-25 
22:09:51.906250000 +0000
@@ -0,0 +1,247 @@
+/*
+ * (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 */
+#define CONFIG_SYS_CLK_FREQ    12000000/* the SBC2440-II has 12MHz 
input clock */
+
+
+#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)
+#define CONFIG_SYS_GBL_DATA_SIZE    128    /* size in bytes reserved 
for initial data */
+
+/*
+ * 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_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_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_ETHADDR            08:00:3e:26:0a:5b
+#define CONFIG_NETMASK            255.255.255.0
+#define CONFIG_IPADDR            192.168.0.69
+#define CONFIG_GATEWAYIP        192.168.0.1
+#define CONFIG_SERVERIP            192.168.0.70
+#define CONFIG_ROOTPATH            FRNSIDE-1/netshared
+#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)
+#define CONFIG_KGDB_BAUDRATE    115200        /* speed to run kgdb 
serial port */
+/* what's this ? it's not used anywhere */
+#define CONFIG_KGDB_SER_INDEX    1        /* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP    /* undef to save memory        */
+#define CONFIG_SYS_PROMPT        "[ SBC2440-II ]# "    /* Monitor 
Command Prompt    */
+#define CONFIG_SYS_CBSIZE        256        /* Console I/O Buffer 
Size    */
+#define CONFIG_SYS_PBSIZE        
 (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS        16        /* max number of command 
args    */
+#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE    /* Boot Argument 
Buffer Size    */
+
+#define CONFIG_SYS_MEMTEST_START    0x30000000    /* memtest works on    */
+#define CONFIG_SYS_MEMTEST_END    0x33F00000    /* 63 MB in DRAM    */
+
+#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
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+/* #define CONFIG_AMD_LV400    1    /\* uncomment this if you have a 
LV400 flash *\/ */
+/* #define CONFIG_AMD_LV800    1    /\* uncomment this if you have a 
LV800 flash *\/ */
+
+#define CONFIG_AMD_LV160B    1    /* uncomment this if you have a 
LV160DB flash */
+
+#define CONFIG_SYS_MAX_FLASH_BANKS    1    /* max number of memory banks */
+
+#ifdef CONFIG_AMD_LV160B
+    #define PHYS_FLASH_SIZE                    0x00200000 /* 2MB */
+    #define CONFIG_SYS_MAX_FLASH_SECT    (35)    /* max number of 
sectors on one chip */
+    #define CONFIG_ENV_ADDR                    (CONFIG_SYS_FLASH_BASE + 
0x1F0000) /* addr of environment */
+#endif
+
+#ifdef CONFIG_AMD_LV800
+    #define PHYS_FLASH_SIZE                    0x00100000 /* 1MB */
+    #define CONFIG_SYS_MAX_FLASH_SECT    (19)    /* max number of 
sectors on one chip */
+    #define CONFIG_ENV_ADDR                    (CONFIG_SYS_FLASH_BASE + 
0x0F0000) /* addr of environment */
+#endif
+
+#ifdef CONFIG_AMD_LV400
+    #define PHYS_FLASH_SIZE                    0x00080000 /* 512KB */
+    #define CONFIG_SYS_MAX_FLASH_SECT    (11)    /* max number of 
sectors on one chip */
+    #define CONFIG_ENV_ADDR                    (CONFIG_SYS_FLASH_BASE + 
0x070000) /* addr of environment */
+#endif
+
+/* timeout values are in ticks */
+#define CONFIG_SYS_FLASH_ERASE_TOUT    (5*CONFIG_SYS_HZ) /* Timeout for 
Flash Erase */
+#define CONFIG_SYS_FLASH_WRITE_TOUT    (5*CONFIG_SYS_HZ) /* Timeout for 
Flash Write */
+
+#define CONFIG_ENV_IS_IN_FLASH    1
+#define CONFIG_ENV_SIZE                0x10000    /* Total Size of 
Environment Sector */
+
+/*-----------------------------------------------------------------------
+ * NAND flash settings
+ */
+#if defined(CONFIG_CMD_NAND)
+    #define CONFIG_SYS_NAND_BASE            0x4e00000c
+    #define CONFIG_SYS_MAX_NAND_DEVICE    1    /* Max number of NAND 
devices        */
+    #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 -uprN u-boot-2009.03/include/s3c2440.h 
u-boot-2009.03-PATCHED/include/s3c2440.h
--- u-boot-2009.03/include/s3c2440.h    1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2009.03-PATCHED/include/s3c2440.h    2009-03-25 
21:05:44.750000000 +0000
@@ -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 -uprN u-boot-2009.03/include/s3c24x0.h 
u-boot-2009.03-PATCHED/include/s3c24x0.h
--- u-boot-2009.03/include/s3c24x0.h    2009-03-21 21:04:41.000000000 +0000
+++ u-boot-2009.03-PATCHED/include/s3c24x0.h    2009-03-22 
19:11:51.437500000 +0000
@@ -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;
 
 
@@ -153,8 +156,8 @@ typedef struct {
 #endif
 } /*__attribute__((__packed__))*/ S3C24X0_LCD;
 
-
-/* NAND FLASH (see S3C2410 manual chapter 6) */
+#ifdef CONFIG_S3C2410
+/* NAND FLASH (see S3C2410 manual chapter 6 ) */
 typedef struct {
     S3C24X0_REG32    NFCONF;
     S3C24X0_REG32    NFCMD;
@@ -163,6 +166,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 +475,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;
 
 

-- 

==================
Kevin Morfitt
Fearnside Systems Ltd
25 Holbeck Road
Nottingham
NG8 3PB

t: 0115 9136703
m: 07939 126277
e: kevin.morfitt at fearnsidesystems.co.uk




More information about the U-Boot mailing list