summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/a9m2440
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boards/a9m2440')
-rw-r--r--arch/arm/boards/a9m2440/Makefile4
-rw-r--r--arch/arm/boards/a9m2440/a9m2410dev.c95
-rw-r--r--arch/arm/boards/a9m2440/a9m2440.c271
-rw-r--r--arch/arm/boards/a9m2440/baseboards.h23
-rw-r--r--arch/arm/boards/a9m2440/config.h73
-rw-r--r--arch/arm/boards/a9m2440/env/bin/_update34
-rw-r--r--arch/arm/boards/a9m2440/env/bin/boot40
-rw-r--r--arch/arm/boards/a9m2440/env/bin/hush_hack1
-rw-r--r--arch/arm/boards/a9m2440/env/bin/init34
-rw-r--r--arch/arm/boards/a9m2440/env/bin/update_kernel13
-rw-r--r--arch/arm/boards/a9m2440/env/bin/update_root13
-rw-r--r--arch/arm/boards/a9m2440/env/config26
-rw-r--r--arch/arm/boards/a9m2440/lowlevel_init.S240
13 files changed, 867 insertions, 0 deletions
diff --git a/arch/arm/boards/a9m2440/Makefile b/arch/arm/boards/a9m2440/Makefile
new file mode 100644
index 0000000000..779e83dc03
--- /dev/null
+++ b/arch/arm/boards/a9m2440/Makefile
@@ -0,0 +1,4 @@
+
+obj-y += lowlevel_init.o
+obj-y += a9m2440.o
+obj-$(CONFIG_MACH_A9M2410DEV) += a9m2410dev.o
diff --git a/arch/arm/boards/a9m2440/a9m2410dev.c b/arch/arm/boards/a9m2440/a9m2410dev.c
new file mode 100644
index 0000000000..1220bd9777
--- /dev/null
+++ b/arch/arm/boards/a9m2440/a9m2410dev.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2009 Juergen Beisert
+ *
+ * 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
+ *
+ */
+
+/**
+ * @file
+ * @brief a9m2410dev Baseboad specific initialization routines
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/s3c24x0-iomap.h>
+
+/**
+ * Initialize the CPU to be able to work with the a9m2410dev evaluation board
+ */
+int a9m2410dev_devices_init(void)
+{
+ unsigned int reg;
+
+ /* ---------- configure the GPIOs ------------- */
+ writel(0x007FFFFF, GPACON);
+ writel(0x00000000, GPCCON);
+ writel(0x00000000, GPCUP);
+ writel(0x00000000, GPDCON);
+ writel(0x00000000, GPDUP);
+ writel(0xAAAAAAAA, GPECON);
+ writel(0x0000E03F, GPEUP);
+ writel(0x00000000, GPBCON); /* all inputs */
+ writel(0x00000007, GPBUP); /* pullup disabled for GPB0..3 */
+ writel(0x00009000, GPFCON); /* GPF7 CLK_INT#, GPF6 Debug-LED */
+ writel(0x000000FF, GPFUP);
+ writel(readl(GPGDAT) | 0x1010, GPGDAT); /* switch off IDLE_SW#, switch off LCD backlight */
+ writel(0x0100A93A, GPGCON); /* switch on USB device */
+ writel(0x0000F000, GPGUP);
+ writel(0x0029FAAA, GPHCON);
+
+ writel((1 << 12) | (0 << 11), GPJDAT);
+ writel(0x0016aaaa, GPJCON);
+ writel(~((0<<12)| (1<<11)), GPJUP);
+
+ writel((0 << 12) | (0 << 11), GPJDAT);
+ writel(0x0016aaaa, GPJCON);
+ writel(0x00001fff, GPJUP);
+
+ writel(0x00000000, DSC0);
+ writel(0x00000000, DSC1);
+
+ /*
+ * USB port1 normal, USB port0 normal, USB1 pads for device
+ * PCLK output on CLKOUT0, UPLL CLK output on CLKOUT1,
+ */
+ writel((readl(MISCCR) & ~0xFFFF) | 0x0140, MISCCR);
+
+ /* ----------- configure the access to the outer space ---------- */
+ reg = readl(BWSCON);
+
+ /* CS#1 to access the network controller */
+ reg &= ~0xf0;
+ reg |= 0xe0;
+ writel(0x1350, BANKCON1);
+
+ /* CS#2 to the dual 16550 UART */
+ reg &= ~0xf00;
+ reg |= 0x400;
+ writel(0x0d50, BANKCON2);
+
+ writel(reg, BWSCON);
+
+ /* release the reset signal to the network and UART device */
+ reg = readl(MISCCR);
+ reg |= 0x10000;
+ writel(reg, MISCCR);
+
+ return 0;
+}
diff --git a/arch/arm/boards/a9m2440/a9m2440.c b/arch/arm/boards/a9m2440/a9m2440.c
new file mode 100644
index 0000000000..2567f5ed13
--- /dev/null
+++ b/arch/arm/boards/a9m2440/a9m2440.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2009 Juergen Beisert, Pengutronix
+ *
+ * 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
+ *
+ */
+
+/**
+ * @file
+ * @brief a9m2440 Specific Board Initialization routines
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <asm/mach-types.h>
+#include <partition.h>
+#include <nand.h>
+#include <asm/io.h>
+#include <mach/s3c24x0-iomap.h>
+#include <mach/s3c24x0-nand.h>
+#include <mach/s3c24xx-generic.h>
+
+#include "baseboards.h"
+
+static struct memory_platform_data ram_pdata = {
+ .name = "ram0",
+ .flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+ .name = "mem",
+ .map_base = CS6_BASE,
+ .platform_data = &ram_pdata,
+};
+
+static struct s3c24x0_nand_platform_data nand_info = {
+ .nand_timing = CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1)
+};
+
+static struct device_d nand_dev = {
+ .name = "s3c24x0_nand",
+ .map_base = S3C24X0_NAND_BASE,
+ .platform_data = &nand_info,
+};
+
+/*
+ * cs8900 network controller onboard
+ * Connected to CS line 5 + A24 and interrupt line EINT9,
+ * data width is 16 bit
+ */
+static struct device_d network_dev = {
+ .name = "cs8900",
+ .map_base = CS5_BASE + (1 << 24) + 0x300,
+ .size = 16,
+};
+
+static int a9m2440_check_for_ram(uint32_t addr)
+{
+ uint32_t tmp1, tmp2;
+ int rc = 0;
+
+ tmp1 = readl(addr);
+ tmp2 = readl(addr + sizeof(uint32_t));
+
+ writel(0xaaaaaaaa, addr);
+ writel(0x55555555, addr + sizeof(uint32_t));
+ if ((readl(addr) != 0xaaaaaaaa) || (readl(addr + sizeof(uint32_t)) != 0x55555555))
+ rc = 1; /* seems no RAM */
+
+ writel(0x55555555, addr);
+ writel(0xaaaaaaaa, addr + sizeof(uint32_t));
+ if ((readl(addr) != 0x55555555) || (readl(addr + sizeof(uint32_t)) != 0xaaaaaaaa))
+ rc = 1; /* seems no RAM */
+
+ writel(tmp1, addr);
+ writel(tmp2, addr + sizeof(uint32_t));
+
+ return rc;
+}
+
+static void a9m2440_disable_second_sdram_bank(void)
+{
+ writel(readl(BANKCON7) & ~(0x3 << 15),BANKCON7);
+ writel(readl(MISCCR) | (1 << 18), MISCCR); /* disable clock */
+}
+
+static int a9m2440_devices_init(void)
+{
+ uint32_t reg;
+
+ /*
+ * The special SDRAM setup code for this machine will always enable
+ * both SDRAM banks. But the second SDRAM device may not exists!
+ * So we must check here, if the second bank is populated to get the
+ * correct RAM size.
+ */
+ switch (readl(BANKSIZE) & 0x7) {
+ case 0:
+ if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 32 * 1024 * 1024))
+ a9m2440_disable_second_sdram_bank();
+ break;
+ case 1:
+ if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 64 * 1024 * 1024))
+ a9m2440_disable_second_sdram_bank();
+ break;
+ case 2:
+ if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 128 * 1024 * 1024))
+ a9m2440_disable_second_sdram_bank();
+ break;
+ case 4:
+ case 5:
+ case 6: /* not supported on this machine */
+ break;
+ default:
+ if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 16 * 1024 * 1024))
+ a9m2440_disable_second_sdram_bank();
+ break;
+ }
+
+ sdram_dev.size = s3c24x0_get_memory_size();
+
+ /* ----------- configure the access to the outer space ---------- */
+ reg = readl(BWSCON);
+
+ /* CS#5 to access the network controller */
+ reg &= ~0x00f00000;
+ reg |= 0x00d00000; /* 16 bit */
+ writel(0x1f4c, BANKCON5);
+
+ writel(reg, BWSCON);
+
+#ifdef CONFIG_MACH_A9M2410DEV
+ a9m2410dev_devices_init();
+#endif
+
+ /* release the reset signal to external devices */
+ reg = readl(MISCCR);
+ reg |= 0x10000;
+ writel(reg, MISCCR);
+
+ /* ----------- the devices the boot loader should work with -------- */
+ register_device(&nand_dev);
+ register_device(&sdram_dev);
+ register_device(&network_dev);
+
+#ifdef CONFIG_NAND
+ /* ----------- add some vital partitions -------- */
+ devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
+ dev_add_bb_dev("self_raw", "self0");
+
+ devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw");
+ dev_add_bb_dev("env_raw", "env0");
+#endif
+ armlinux_add_dram(&sdram_dev);
+ armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100);
+ armlinux_set_architecture(MACH_TYPE_A9M2440);
+
+ return 0;
+}
+
+device_initcall(a9m2440_devices_init);
+
+#ifdef CONFIG_S3C24XX_NAND_BOOT
+void __bare_init nand_boot(void)
+{
+ s3c24x0_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0, 512);
+}
+#endif
+
+static struct device_d a9m2440_serial_device = {
+ .name = "s3c24x0_serial",
+ .map_base = UART1_BASE,
+ .size = UART1_SIZE,
+};
+
+static int a9m2440_console_init(void)
+{
+ register_device(&a9m2440_serial_device);
+ return 0;
+}
+
+console_initcall(a9m2440_console_init);
+
+/** @page a9m2440 DIGI's a9m2440
+
+This CPU card is based on a Samsung S3C2440 CPU. The card is shipped with:
+
+- S3C2440\@400 MHz or 533 MHz (ARM920T/ARMv4T)
+- 16.9344 MHz crystal reference
+- SDRAM 32/64/128 MiB
+ - Samsung K4M563233E-EE1H (one or two devices for 32 MiB or 64 MiB)
+ - 2M x 32bit x 4 Banks Mobile SDRAM
+ - CL2\@100 MHz (CAS/RAS delay 19ns)
+ - 105 MHz max
+ - collumn address size is 9 bits
+ - Row cycle time: 69ns
+ - Samsung K4M513233C-DG75 (one or two devices for 64 MiB or 128 MiB)
+ - 4M x 32bit x 4 Banks Mobile SDRAM
+ - CL2\@100MHz (CAS/RAS delay 18ns)
+ - 111 MHz max
+ - collumn address size is 9 bits
+ - Row cycle time: 63ns
+ - 64ms refresh period (4k)
+ - 90 pin FBGA
+ - 32 bit data bits
+ - Extended temperature range (-25°C...85°C)
+- NAND Flash 32/64/128 MiB
+ - Samsung KM29U512T (NAND01GW3A0AN6)
+ - 64 MiB 3,3V 8-bit
+ - ID: 0xEC, 0x76, 0x??, 0xBD
+ - Samsung KM29U256T
+ - 32 MiB 3,3V 8-bit
+ - ID: 0xEC, 0x75, 0x??, 0xBD
+ - ST Micro
+ - 128 MiB 3,3V 8-bit
+ - ID: 0x20, 0x79
+ - 30ns/40ns/20ns
+- I2C interface, 100 KHz and 400 KHz
+ - Real Time Clock
+ - Dallas DS1337
+ - address 0x68
+ - EEPROM
+ - ST M24LC64
+ - address 0x50
+ - 16bit addressing
+- LCD interface
+- Touch Screen interface
+- Camera interface
+- I2S interface
+- AC97 Audio-CODEC interface
+- SD card interface
+- 3 serial RS232 interfaces
+- Host and device USB interface, USB1.1 compliant
+- Ethernet interface
+ - 10Mbps, Cirrus Logic, CS8900A (on the CPU card)
+- SPI interface
+- JTAG interface
+
+How to get the binary image:
+
+Using the default configuration:
+
+@code
+make ARCH=arm a9m2440_defconfig
+@endcode
+
+Build the binary image:
+
+@code
+make ARCH=arm CROSS_COMPILE=armv4compiler
+@endcode
+
+@note replace the armv4compiler with your ARM v4 cross compiler.
+
+*/
diff --git a/arch/arm/boards/a9m2440/baseboards.h b/arch/arm/boards/a9m2440/baseboards.h
new file mode 100644
index 0000000000..ec80312b69
--- /dev/null
+++ b/arch/arm/boards/a9m2440/baseboards.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2009 Juergen Beisert
+ *
+ * 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
+ *
+ */
+
+#ifdef CONFIG_MACH_A9M2410DEV
+extern int a9m2410dev_devices_init(void);
+#endif
diff --git a/arch/arm/boards/a9m2440/config.h b/arch/arm/boards/a9m2440/config.h
new file mode 100644
index 0000000000..43cb6ab934
--- /dev/null
+++ b/arch/arm/boards/a9m2440/config.h
@@ -0,0 +1,73 @@
+/**
+ * @file
+ * @brief Global defintions for the ARM S3C2440 based a9m2440 CPU card
+ */
+/* 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
+
+/**
+ * The external clock reference is a 16.9344 MHz crystal
+ */
+#define S3C24XX_CLOCK_REFERENCE 16934400
+
+/**
+ * Define the main clock configuration to be used in register CLKDIVN
+ *
+ * We must limit the frequency of the connected SDRAMs with the clock ratio
+ * setup to 1:4:8. This will result into FCLK:HCLK:PCLK = 400Mhz:100MHz:50MHz
+ */
+#define BOARD_SPECIFIC_CLKDIVN 0x05
+
+/**
+ * Define the MPLL configuration to be used in register MPLLCON
+ *
+ * We want the MPLL to run at 399.65 MHz
+ */
+#define BOARD_SPECIFIC_MPLL ((0x6e << 12) + (3 << 4) + 1)
+
+/**
+ * Define the UPLL configuration to be used in register UPLLCON
+ *
+ * We want the UPLL to run at 47.98 MHz
+ */
+#define BOARD_SPECIFIC_UPLL ((0x3c << 12) + (4 << 4) + 2)
+
+/*
+ * Flash access timings
+ * Tacls = 0ns (but 20ns data setup time)
+ * Twrph0 = 25ns (write) 35ns (read)
+ * Twrph1 = 10ns (10ns data hold time)
+ * Read cycle time = 50ns
+ *
+ * Assumed HCLK is 100MHz
+ * Tacls = 1 (-> 20ns)
+ * Twrph0 = 3 (-> 40ns)
+ * Twrph1 = 1 (-> 20ns)
+ * Cycle time = 80ns
+ */
+#define A9M2440_TACLS 1
+#define A9M2440_TWRPH0 3
+#define A9M2440_TWRPH1 1
+
+/* needed in the generic NAND boot code only */
+#ifdef CONFIG_S3C24XX_NAND_BOOT
+# define BOARD_DEFAULT_NAND_TIMING CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1)
+#endif
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/a9m2440/env/bin/_update b/arch/arm/boards/a9m2440/env/bin/_update
new file mode 100644
index 0000000000..b10682ece4
--- /dev/null
+++ b/arch/arm/boards/a9m2440/env/bin/_update
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+if [ -z "$part" -o -z "$image" ]; then
+ echo "define \$part and \$image"
+ exit 1
+fi
+
+if [ ! -e "$part" ]; then
+ echo "Partition $part does not exist"
+ exit 1
+fi
+
+if [ $# = 1 ]; then
+ image=$1
+fi
+
+if [ x$ip = xdhcp ]; then
+ dhcp
+fi
+
+ping $eth0.serverip
+if [ $? -ne 0 ] ; then
+ echo "update aborted"
+ exit 1
+fi
+
+echo
+echo "erasing partition $part"
+erase $part
+
+echo
+echo "flashing $image to $part"
+echo
+tftp $image $part
diff --git a/arch/arm/boards/a9m2440/env/bin/boot b/arch/arm/boards/a9m2440/env/bin/boot
new file mode 100644
index 0000000000..86e22cf9ff
--- /dev/null
+++ b/arch/arm/boards/a9m2440/env/bin/boot
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+. /env/config
+
+if [ x$1 = xnand ]; then
+ root=nand
+ kernel=nand
+fi
+
+if [ x$1 = xnet ]; then
+ root=net
+ kernel=net
+fi
+
+if [ x$root = xnand ]; then
+ bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2"
+fi
+if [ x$root = xnet ]; then
+ bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp"
+ if [ x$ip = xdhcp ]; then
+ bootargs="$bootargs ip=dhcp"
+ else
+ bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::"
+ fi
+fi
+
+bootargs="$bootargs mtdparts=\"NAND 32MiB 3,3V 8-bit:$nand_parts\""
+
+bootargs="$bootargs cs89x0_media=rj45 cs89x0_mac=$eth0.ethaddr"
+
+if [ x$kernel = xnet ]; then
+ if [ x$ip = xdhcp ]; then
+ dhcp
+ fi
+ tftp $uimage uImage || exit 1
+ bootm uImage
+else
+ bootm /dev/nand0.kernel.bb
+fi
+
diff --git a/arch/arm/boards/a9m2440/env/bin/hush_hack b/arch/arm/boards/a9m2440/env/bin/hush_hack
new file mode 100644
index 0000000000..5fffa92ecd
--- /dev/null
+++ b/arch/arm/boards/a9m2440/env/bin/hush_hack
@@ -0,0 +1 @@
+nand -a /dev/nand0.*
diff --git a/arch/arm/boards/a9m2440/env/bin/init b/arch/arm/boards/a9m2440/env/bin/init
new file mode 100644
index 0000000000..5ae44dd455
--- /dev/null
+++ b/arch/arm/boards/a9m2440/env/bin/init
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+PATH=/env/bin
+export PATH
+
+. /env/config
+
+if [ -e /dev/nand0 ]; then
+ addpart /dev/nand0 $nand_parts
+
+ # Uh, oh, hush first expands wildcards and then starts executing
+ # commands. What a bug!
+ source /env/bin/hush_hack
+fi
+
+if [ -z $eth0.ethaddr ]; then
+ while [ -z $eth0.ethaddr ]; do
+ readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr
+ done
+ echo -a /env/config "eth0.ethaddr=$eth0.ethaddr"
+fi
+
+echo
+echo -n "Hit any key to stop autoboot: "
+timeout -a $autoboot_timeout
+if [ $? != 0 ]; then
+ echo
+ echo "type update_kernel [<imagename>] to update kernel into flash"
+ echo "type update_root [<imagename>] to update rootfs into flash"
+ echo
+ exit
+fi
+
+boot
diff --git a/arch/arm/boards/a9m2440/env/bin/update_kernel b/arch/arm/boards/a9m2440/env/bin/update_kernel
new file mode 100644
index 0000000000..c43a55785b
--- /dev/null
+++ b/arch/arm/boards/a9m2440/env/bin/update_kernel
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+. /env/config
+
+part=/dev/nand0.kernel.bb
+
+if [ x$1 = x ]; then
+ image=$uimage
+else
+ image=$1
+fi
+
+. /env/bin/_update $image
diff --git a/arch/arm/boards/a9m2440/env/bin/update_root b/arch/arm/boards/a9m2440/env/bin/update_root
new file mode 100644
index 0000000000..46cbca5beb
--- /dev/null
+++ b/arch/arm/boards/a9m2440/env/bin/update_root
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+. /env/config
+
+part=/dev/nand0.root.bb
+
+if [ x$1 = x ]; then
+ image=$jffs2
+else
+ image=$1
+fi
+
+. /env/bin/_update $image
diff --git a/arch/arm/boards/a9m2440/env/config b/arch/arm/boards/a9m2440/env/config
new file mode 100644
index 0000000000..936c35f9a9
--- /dev/null
+++ b/arch/arm/boards/a9m2440/env/config
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# can be either 'net' or 'nand''
+kernel=net
+root=net
+
+uimage=uImage-a9m2440
+jffs2=root-a9m2440.jffs2
+
+autoboot_timeout=3
+
+nfsroot="/nfsexport/OSELAS.BSP-Hesch-TMU-1/platform-FS_A9M2440/root"
+bootargs="console=ttySAC0,38400"
+
+nand_parts="256k(barebox)ro,128k(bareboxenv),1536k(kernel),-(root)"
+rootpart_nand="/dev/mtdblock3"
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+#ip=dhcp
+
+# or set your networking parameters here
+eth0.ipaddr=192.168.42.32
+eth0.netmask=255.255.0.0
+eth0.gateway=192.168.23.1
+eth0.serverip=192.168.23.2
+eth0.ethaddr=00:04:f3:00:06:35
diff --git a/arch/arm/boards/a9m2440/lowlevel_init.S b/arch/arm/boards/a9m2440/lowlevel_init.S
new file mode 100644
index 0000000000..4b5c596076
--- /dev/null
+++ b/arch/arm/boards/a9m2440/lowlevel_init.S
@@ -0,0 +1,240 @@
+/*
+ *
+ */
+
+#include <config.h>
+#include <mach/s3c24x0-iomap.h>
+
+ .section ".text_bare_init.board_init_lowlevel","ax"
+
+/*
+ * To be able to setup the SDRAM interface correctly, we need some
+ * external information about the connected SDRAM devices.
+ *
+ * When we set GPH8, we can read at GPB:
+ * Bit 0..1: Memory device size -> 00=16M, 01=64M, 10=32M, 11=128M
+ * Bit 2: CL setting
+ *
+ * Some remarks: The CL setting seems useless. It always signals a CL3
+ * requirement, but the SDRAM types I found on the cards are supporting
+ * CL2 @ 100 MHz. But also these SDRAM types are only support 105 MHz max.
+ * So, we never need CL3 because we can't run the CPU at 533 MHz (which
+ * implies an 133 MHz SDRAM clock).
+ * All devices are connected via 32 bit databus
+ *
+ * Note: I was able to check the 32 MiB and 64 MiB configuration only. I didn't
+ * had access to a 16 MiB nor 128 MiB config.
+ *
+ */
+
+sdram_init:
+ /*
+ * Read the configuration. After reset until any GPIO port is
+ * configured yet, these pins show external settings, to detect
+ * the SDRAM size.
+ */
+ ldr r1, =GPBDAT
+ ldr r4, [r1]
+ and r4, r4, #0x3
+
+ ldr r1, =S3C24X0_MEMCTL_BASE
+ /* configure both SDRAM areas with 32 bit data bus width */
+ ldr r0, =((0x2 << 24) + (0x2 << 28))
+ str r0, [r1], #0x1c /* post add register offset for bank6 */
+
+ /*
+ * With the configuration we simply need to calculate an offset into
+ * our table with the predefined SDRAM settings
+ */
+ adr r0, SDRAMDATA
+ mov r2, #6*4 /* # of bytes per table entry */
+ mul r3, r4, r2
+ add r0, r0, r3 /* start address of the entry */
+
+ /*
+ * store the table entry data into the registers
+ */
+1:
+ ldr r3, [r0], #4
+ str r3, [r1], #4
+ subs r2, r2, #4
+ bne 1b
+
+/* TODO: Check if the second bank is populated, and switch it off if not */
+
+ mov pc, lr
+
+/*
+ * we need 4 sets of memory settings per main CPU clock speed
+ *
+ * 400MHz main speed:
+ * - 16 MiB in the first bank, maybe 16 MiB in the second bank (untested!)
+ * - 32 MiB in the first bank, maybe 32 MiB in the second bank (CL=2)
+ * - 64 MiB in the first bank, maybe 64 MiB in the second bank (CL=2)
+ * - 128 MiB in the first bank, maybe 128 MiB in the second bank (untested!)
+ *
+ * Note: SDRAM clock runs at 100MHz
+ */
+
+SDRAMDATA:
+/* --------------------------- 16 MiB @ 100MHz --------------------------- */
+ /*
+ * - MT = 11 (= sync dram type)
+ * - Trcd = 01 (= CL3)
+ * - SCAN = 00 (= 8 bit collumns)
+ */
+ .word ((0x3 << 15) + (0x1 << 2) + (0x0))
+ .word ((0x3 << 15) + (0x1 << 2) + (0x0))
+ /*
+ * SDRAM refresh settings
+ * - REFEN = 1 (= refresh enabled)
+ * - TREFMD = 0 (= auto refresh)
+ * - Trp = 00 (= 2 RAS precharge clocks)
+ * - Tsrc = 11 (= 7 clocks -> row cycle time @100MHz 2+5=7 -> 70ns)
+ * - Refrsh = 2^11 + 1 - 100 * 15.6 = 2049 - 1560 = FIXME
+ */
+ .word ((0x1 << 23) + (0x0 << 22) + (0x0 << 20) + (0x3 << 18) + 468)
+ /*
+ * SDRAM banksize
+ * - BURST_EN = 0 (= burst mode disabled)
+ * - SCKE_EN = 1 (= SDRAM SCKE enabled)
+ * - SCLK_EN = 1 (= clock active only during accesses)
+ * - BK67MAP = 010 (= 128MiB) FIXME?????
+ */
+ .word ((0 << 7) + (1 << 5) + (1 << 4) + 2)
+ /*
+ * SDRAM mode register
+ * CL = 010 (= 2 clocks)
+ */
+ .word (0x2 << 4)
+ .word (0x2 << 4)
+
+/* ------------- one or two banks with 64 MiB @ 100MHz -------------------- */
+
+ /*
+ * - MT = 11 (= sync dram type)
+ * - Trcd = 00 (= CL2)
+ * - SCAN = 01 (= 9 bit collumns)
+ */
+ .word ((0x3 << 15) + (0x0 << 2) + (0x1))
+ .word ((0x3 << 15) + (0x0 << 2) + (0x1))
+ /*
+ * SDRAM refresh settings
+ * - REFEN = 1 (= refresh enabled)
+ * - TREFMD = 0 (= auto refresh)
+ * - Trp = 00 (= 2 RAS precharge clocks)
+ * - Tsrc = 01 (= 5 clocks -> row cycle time @100MHz 2+5=7 -> 70ns)
+ * - Refrsh = 2^11 + 1 - 100 * 15.6 = 2049 - 1560 = 489
+ */
+ .word ((0x1 << 23) + (0x0 << 22) + (0x0 << 20) + (0x1 << 18) + 489)
+ /*
+ * SDRAM banksize
+ * - BURST_EN = 1 (= burst mode enabled)
+ * - SCKE_EN = 1 (= SDRAM SCKE enabled)
+ * - SCLK_EN = 1 (= clock active only during accesses)
+ * - BK67MAP = 001 (= 64 MiB)
+ */
+ .word ((1 << 7) + (1 << 5) + (1 << 4) + 1)
+ /*
+ * SDRAM mode register
+ * CL = 010 (= 2 clocks)
+ */
+ .word (0x2 << 4)
+ .word (0x2 << 4)
+
+/* ------------- one or two banks with 32 MiB @ 100MHz -------------------- */
+
+ /*
+ * - MT = 11 (= sync dram type)
+ * - Trcd = 00 (= CL2)
+ * - SCAN = 01 (= 9 bit collumns)
+ */
+ .word ((0x3 << 15) + (0x0 << 2) + (0x1))
+ .word ((0x3 << 15) + (0x0 << 2) + (0x1))
+ /*
+ * SDRAM refresh settings
+ * - REFEN = 1 (= refresh enabled)
+ * - TREFMD = 0 (= auto refresh)
+ * - Trp = 00 (= 2 RAS precharge clocks)
+ * - Tsrc = 01 (= 5 clocks -> row cycle time @100MHz 2+5=7 -> 70ns)
+ * - Refrsh = 2^11 + 1 - 100 * 15.6 = 2049 - 1560 = 489
+ */
+ .word ((0x1 << 23) + (0x0 << 22) + (0x0 << 20) + (0x1 << 18) + 489)
+ /*
+ * SDRAM banksize
+ * - BURST_EN = 1 (= burst mode enabled)
+ * - SCKE_EN = 1 (= SDRAM SCKE enabled)
+ * - SCLK_EN = 1 (= clock active only during accesses)
+ * - BK67MAP = 000 (= 32 MiB)
+ */
+ .word ((1 << 7) + (1 << 5) + (1 << 4) + 0)
+ /*
+ * SDRAM mode register
+ * CL = 010 (= 2 clocks)
+ */
+ .word (0x2 << 4)
+ .word (0x2 << 4)
+
+/* ------------ one or two banks with 128 MiB @ 100MHz -------------------- */
+
+ /*
+ * - MT = 11 (= sync dram type)
+ * - Trcd = 00 (= CL2)
+ * - SCAN = 01 (= 9 bit collumns)
+ */
+ .word ((0x3 << 15) + (0x0 << 2) + (0x1))
+ .word ((0x3 << 15) + (0x0 << 2) + (0x1))
+ /*
+ * SDRAM refresh settings
+ * - REFEN = 1 (= refresh enabled)
+ * - TREFMD = 0 (= auto refresh)
+ * - Trp = 00 (= 2 RAS precharge clocks)
+ * - Tsrc = 01 (= 5 clocks -> row cycle time @100MHz 2+5=7 -> 70ns)
+ * - Refrsh = 2^11 + 1 - 100 * 7.5 = 2049 - FIXME = 1259
+ */
+ .word ((0x1 << 23) + (0x0 << 22) + (0x1 << 20) + (0x3 << 18) + 1259)
+ /*
+ * SDRAM banksize
+ * - BURST_EN = 0 (= burst mode disabled)
+ * - SCKE_EN = 1 (= SDRAM SCKE enabled)
+ * - SCLK_EN = 1 (= clock active only during accesses)
+ * - BK67MAP = 010 (= 128MiB)
+ */
+ .word (0x32)
+ /*
+ * SDRAM mode register
+ * CL = 010 (= 2 clocks)
+ */
+ .word (0x2 << 4)
+ .word (0x2 << 4)
+
+/* ------------------------------------------------------------------------ */
+
+.globl board_init_lowlevel
+board_init_lowlevel:
+
+ mov r10, lr /* save the link register */
+
+ bl s3c24x0_disable_wd
+
+ /* skip everything here if we are already running from SDRAM */
+ cmp pc, #S3C24X0_SDRAM_BASE
+ blo 1f
+ cmp pc, #S3C24X0_SDRAM_END
+ bhs 1f
+
+ mov pc, r10
+
+/* we are running from NOR or NAND/SRAM memory. Do further initialisation */
+1:
+ bl s3c24x0_pll_init
+
+ bl sdram_init
+
+#ifdef CONFIG_S3C24XX_NAND_BOOT
+ mov lr, r10 /* restore the link register */
+/* up to here we are running from the internal SRAM area */
+ b s3c24x0_nand_boot /* does return directly to our caller into SDRAM */
+#else
+ mov pc, r10
+#endif